-
Secure your Cluster with ApplicationGateway WAF
- create an ApplicationGateway with WAF enabled
- route traffic from public ApplicationGateway to your Cluster's internal LoadBalancer
-
Cluster
- create a Cluster with Azure Advanced Container Network Integration (Azure CNI)
- create an internal ingress controller
- deploy your cluster with Azure ARM Templates
- create a service principal for Kubernetes to manage Azure resources
Open a shell and create a resource group
> az group create --name <your-rg-name> --location <your-azure-location>
> az ad sp create-for-rbac --name <your-spn-name> --skip-assignment true
Remember the 'appId' and 'password' from the output.
Get the ObjectId of your created ServicePrincipal and remember it.
> az ad sp show --id <your-appId>
To deploy the Cluster on Azure use the following ARM Template. Open a shell and go to the directory where the ARM Template is located.
> az group deployment create -g <your-resourcegroup-name> --template-file akscluster.json --parameters akscluster.parameters.json --parameters aksClusterName=<your-cluster-name> aksServicePrincipalAppId=<your-spn-appId> aksServicePrincipalClientSecret=<your-spn-password> aksServicePrincipalObjectId=<your-spn-objectId> aksDnsPrefix=<dns-prefix-name-of-your-choice>
Remember the ip address of the ApplicationGateway from the output.
After your cluster is deployed get the cluster credentials to access the cluster with kubectl.
> az aks get-credentials --name <your-cluster-name> --resource-group <your-resourcegroup-name>
Check the current context of kubectl.
> kubectl config current-context
Switch context to your deployed cluster.
> kubectl config set-context <your-clustername>
At this point we have an AKS Cluster deployed to Azure without a load balancer. Now we have to deploy an internal ingress controller with a private IP address. The currently used VNET has an IP address range of 16.0.0.0/8 if you used the default value in akscluster.parameters.json. The VNET is splitted into two subnets
- kubesubnet with an IP address range of 16.0.0.0/16
- appgwsubnet with an IP address range of 16.1.0.0/16
To deploy an internal ingress controller we need to use a free IP address in the range of the kubesubnet address range. For this example we use 16.0.255.1.
For this example we use Helm to install an internal NGINX ingress controller. Create a file named values.yaml and add following content.
controller:
service:
loadBalancerIP: 16.0.255.1
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
If Helm is not installed on your system execute the following steps.
Install NGINX Ingress Controller using Helm.
> helm install ingress stable/nginx-ingress --namespace <your namespace> -f values.yaml --set controller.replicaCount=2
Check if the service for the controller is deployed using the ip address 16.0.255.1
> kubectl get service -n <your namespace>
To see the ingress controller in action, let's run two demo applications in your AKS cluster. In this example, Helm is used to deploy two instances of a simple 'Hello world' application. Before you can install the sample Helm charts, add the Azure samples repository to your Helm environment as follows:
> helm repo add azure-samples https://azure-samples.github.io/helm-charts/
Create the first demo application from a Helm chart with the following command:
helm install azure-samples/aks-helloworld --namespace <your namespace> --generate-name
Now install a second instance of the demo application. For the second instance, you specify a new title so that the two applications are visually distinct. You also specify a unique service name:
helm install azure-samples/aks-helloworld --namespace <your namespace> --set title="AKS Ingress Demo" --set serviceName="ingress-demo" --generate-name
Both applications are now running on your Kubernetes cluster. To route traffic to each application, create a Kubernetes ingress resource. The ingress resource configures the rules that route traffic to one of the two applications. In the following example, traffic to the address http://16.0.255.1/ is routed to the service named aks-helloworld. Traffic to the address http://16.0.255.1/hello-world-two is routed to the ingress-demo service. Create a file named hello-world-ingress.yaml and copy in the following example YAML.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: aks-helloworld
servicePort: 80
- path: /hello-world-two
backend:
serviceName: ingress-demo
servicePort: 80
Create the ingress resource using kubectl apply -f hello-world-ingress.yaml
.
> kubectl apply -f hello-world-ingress.yaml
Now access the demo applications using your public Application Gateway ip.
> curl -L <appgtw-ip>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="/static/default.css">
<title>Welcome to Azure Kubernetes Service (AKS)</title>
[...]
Now add /hello-world-two path to the address, such as http:///hello-world-two. The second demo application with the custom title is returned, as shown in the following condensed example output:
> curl -L -k http://<appgtw-ip>/hello-world-two
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="/static/default.css">
<title>AKS Ingress Demo</title>
[...]