Create an ingress controller in Azure Kubernetes Service (AKS)

An ingress controller is a piece of software that provides reverse proxy, configurable traffic routing, and TLS termination for Kubernetes services. Kubernetes ingress resources are used to configure the ingress rules and routes for individual Kubernetes services. Using an ingress controller and ingress rules, a single IP address can be used to route traffic to multiple services in a Kubernetes cluster.

This article shows you how to deploy the NGINX ingress controller in an Azure Kubernetes Service (AKS) cluster. Two applications are then run in the AKS cluster, each of which is accessible over the single IP address.

You can also:

Before you begin

This article uses Helm to install the NGINX ingress controller, cert-manager, and a sample web app. You need to have Helm initialized within your AKS cluster and using a service account for Tiller. For more information on configuring and using Helm, see Install applications with Helm in Azure Kubernetes Service (AKS).

This article also requires that you are running the Azure CLI version 2.0.64 or later. Run az --version to find the version. If you need to install or upgrade, see Install Azure CLI.

Create an ingress controller

To create the ingress controller, use Helm to install nginx-ingress. For added redundancy, two replicas of the NGINX ingress controllers are deployed with the --set controller.replicaCount parameter. To fully benefit from running replicas of the ingress controller, make sure there's more than one node in your AKS cluster.

The ingress controller also needs to be scheduled on a Linux node. Windows Server nodes (currently in preview in AKS) shouldn't run the ingress controller. A node selector is specified using the --set nodeSelector parameter to tell the Kubernetes scheduler to run the NGINX ingress controller on a Linux-based node.

Tip

The following example creates a Kubernetes namespace for the ingress resources named ingress-basic. Specify a namespace for your own environment as needed. If your AKS cluster is not RBAC enabled, add --set rbac.create=false to the Helm commands.

# Create a namespace for your ingress resources
kubectl create namespace ingress-basic

# Use Helm to deploy an NGINX ingress controller
helm install stable/nginx-ingress \
    --namespace ingress-basic \
    --set controller.replicaCount=2 \
    --set nodeSelector."beta.kubernetes.io/os"=linux

When the Kubernetes load balancer service is created for the NGINX ingress controller, a dynamic public IP address is assigned, as shown in the following example output:

$ kubectl get service -l app=nginx-ingress --namespace ingress-basic

NAME                                                 TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
aspiring-labradoodle-nginx-ingress-controller        LoadBalancer   10.0.61.144    40.117.74.8   80:30386/TCP,443:32276/TCP   6m2s
aspiring-labradoodle-nginx-ingress-default-backend   ClusterIP      10.0.192.145   <none>        80/TCP                       6m2s

No ingress rules have been created yet, so the NGINX ingress controller's default 404 page is displayed if you browse to the internal IP address. Ingress rules are configured in the following steps.

Run demo applications

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 ingress-basic

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 ingress-basic \
    --set title="AKS Ingress Demo" \
    --set serviceName="ingress-demo"

Create an ingress route

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://40.117.74.8/ is routed to the service named aks-helloworld. Traffic to the address http://40.117.74.8/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
  namespace: ingress-basic
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: aks-helloworld
          servicePort: 80
        path: /(.*)
      - backend:
          serviceName: ingress-demo
          servicePort: 80
        path: /hello-world-two(/|$)(.*)

Create the ingress resource using the kubectl apply -f hello-world-ingress.yaml command.

$ kubectl apply -f hello-world-ingress.yaml

ingress.extensions/hello-world-ingress created

Test the ingress controller

To test the routes for the ingress controller, browse to the two applications. Open a web browser to the IP address of your NGINX ingress controller, such as http://40.117.74.8. The first demo application is displayed in the web browser, as shown in the follow example:

First app running behind the ingress controller

Now add the /hello-world-two path to the IP address, such as http://40.117.74.8/hello-world-two. The second demo application with the custom title is displayed:

Second app running behind the ingress controller

Clean up resources

This article used Helm to install the ingress components and sample apps. When you deploy a Helm chart, a number of Kubernetes resources are created. These resources includes pods, deployments, and services. To clean up these resources, you can either delete the entire sample namespace, or the individual resources.

Delete the sample namespace and all resources

To delete the entire sample namespace, use the kubectl delete command and specify your namespace name. All the resources in the namespace are deleted.

kubectl delete namespace ingress-basic

Then, remove the Helm repo for the AKS hello world app:

helm repo remove azure-samples

Delete resources individually

Alternatively, a more granular approach is to delete the individual resources created. List the Helm releases with the helm list command. Look for charts named nginx-ingress and aks-helloworld, as shown in the following example output:

$ helm list

NAME                	REVISION	UPDATED                 	STATUS  	CHART               	APP VERSION	NAMESPACE
aspiring-labradoodle	1       	Wed Mar 27 19:55:37 2019	DEPLOYED	nginx-ingress-1.3.1 	0.22.0     	ingress-basic
esteemed-koala      	1       	Wed Mar 27 19:59:18 2019	DEPLOYED	aks-helloworld-0.1.0	           	ingress-basic
wonderful-puma      	1       	Wed Mar 27 19:59:07 2019	DEPLOYED	aks-helloworld-0.1.0	           	ingress-basic

Delete the releases with the helm delete command. The following example deletes the NGINX ingress deployment, and the two sample AKS hello world apps.

$ helm delete aspiring-labradoodle esteemed-koala wonderful-puma

release "aspiring-labradoodle" deleted
release "esteemed-koala" deleted
release "wonderful-puma" deleted

Next, remove the Helm repo for the AKS hello world app:

helm repo remove azure-samples

Remove the ingress route that directed traffic to the sample apps:

kubectl delete -f hello-world-ingress.yaml

Finally, you can delete the itself namespace. Use the kubectl delete command and specify your namespace name:

kubectl delete namespace ingress-basic

Next steps

This article included some external components to AKS. To learn more about these components, see the following project pages:

You can also: