Configure NGINX ingress controller to support Azure private DNS zone with application routing add-on
This article shows you how to configure an NGINX ingress controller to work with an Azure internal load balancer. It also explains how to configure a private Azure DNS zone to enable DNS resolution for the private endpoints to resolve specific domains.
Before you begin
An AKS cluster with the application routing add-on.
To attach an Azure private DNS Zone, you need the Owner, Azure account administrator, or Azure coadministrator role on your Azure subscription.
Connect to your AKS cluster
To connect to the Kubernetes cluster from your local computer, you use kubectl
, the Kubernetes command-line client. You can install it locally using the az aks install-cli command. If you use the Azure Cloud Shell, kubectl
is already installed.
The following example configures connecting to your cluster named aks-cluster in the test-rg using the az aks get-credentials
command.
az aks get-credentials \
--resource-group test-rg \
--name aks-cluster
Create a virtual network
To publish a private DNS zone to your virtual network, specify a list of virtual networks that are allowed to resolve records within the zone with virtual network links.
The following example creates a virtual network named vnet-1 in the test-rg resource group, and one subnet named subnet-1 to create within the virtual network with a specific address prefix.
az network vnet create \
--name vnet-1 \
--resource-group test-rg \
--location eastus \
--address-prefix 10.2.0.0/16 \
--subnet-name subnet-1 \
--subnet-prefixes 10.2.0.0/24
Create an Azure private DNS zone
Note
You can configure the application routing add-on to automatically create records on one or more Azure global and private DNS zones for hosts defined on ingress resources. All global Azure DNS zones and all private Azure DNS zones must be in the same resource group.
Create a DNS zone using the az network private-dns zone create command, specifying the name of the zone and the resource group to create it in. The following example creates a DNS zone named private.contoso.com in the test-rg resource group.
az network private-dns zone create \
--resource-group test-rg \
--name private.contoso.com
You create a virtual network link to the DNS zone created earlier using the az network private-dns link vnet create command. The following example creates a link named dns-link to the zone private.contoso.com for the virtual network vnet-1. Include the --registration-enabled
parameter to specify the link isn't registration enabled.
az network private-dns link vnet create \
--resource-group test-rg \
--name dns-link \
--zone-name private.contoso.com \
--virtual-network vnet-1 \
--registration-enabled false
The Azure DNS private zone auto registration feature manages DNS records for virtual machines deployed in a virtual network. When you link a virtual network with a private DNS zone with this setting enabled, a DNS record gets created for each Azure virtual machine for your AKS node deployed in the virtual network.
Attach an Azure private DNS zone to the application routing add-on
Note
The az aks approuting zone add
command uses the permissions of the user running the command to create the Azure DNS Zone role assignment. The Private DNS Zone Contributor role is a built-in role for managing private DNS resources and is assigned to the add-on's managed identity. For more information on AKS managed identities, see Summary of managed identities.
Retrieve the resource ID for the DNS zone using the
az network dns zone show
command and set the output to a variable namedZONEID
. The following example queries the zone private.contoso.com in the resource group test-rg.ZONEID=$(az network private-dns zone show \ --resource-group test-rg \ --name private.contoso.com \ --query "id" \ --output tsv)
Update the add-on to enable integration with Azure DNS using the
az aks approuting zone
command. You can pass a comma-separated list of DNS zone resource IDs. The following example updates the AKS cluster aks-cluster in the resource group test-rg.az aks approuting zone add \ --resource-group test-rg \ --name aks-cluster \ --ids=${ZONEID} \ --attach-zones
Create an NGINX ingress controller with a private IP address and an internal load balancer
The application routing add-on uses a Kubernetes custom resource definition (CRD) called NginxIngressController
to configure NGINX ingress controllers. You can create more ingress controllers or modify an existing configuration.
NginxIngressController
CRD has a loadBalancerAnnotations
field to control the behavior of the NGINX ingress controller's service by setting load balancer annotations. For more information about load balancer annotations, see Customizations via Kubernetes annotations.
Perform the following steps to create an NGINX ingress controller with an internal facing Azure Load Balancer with a private IP address.
Copy the following YAML manifest into a new file named nginx-internal-controller.yaml and save the file to your local computer.
apiVersion: approuting.kubernetes.azure.com/v1alpha1 kind: NginxIngressController metadata: name: nginx-internal spec: ingressClassName: nginx-internal controllerNamePrefix: nginx-internal loadBalancerAnnotations: service.beta.kubernetes.io/azure-load-balancer-internal: "true"
Create the NGINX ingress controller resources using the
kubectl apply
command.kubectl apply -f nginx-internal-controller.yaml
The following example output shows the created resource:
nginxingresscontroller.approuting.kubernetes.azure.com/nginx-internal created
Verify the ingress controller was created
You can verify the status of the NGINX ingress controller using the
kubectl get nginxingresscontroller
command.kubectl get nginxingresscontroller
The following example output shows the created resource. It might take a few minutes for the controller to be available:
NAME INGRESSCLASS CONTROLLERNAMEPREFIX AVAILABLE default webapprouting.kubernetes.azure.com nginx True nginx-internal nginx-internal nginx-internal True
Deploy an application
The application routing add-on uses annotations on Kubernetes Ingress objects to create the appropriate resources.
Create the application namespace called
aks-store
to run the example pods using thekubectl create namespace
command.kubectl create namespace aks-store
Deploy the AKS store application using the following YAML manifest file:
kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/aks-store-demo/main/sample-manifests/docs/app-routing/aks-store-deployments-and-services.yaml -n aks-store
This manifest creates the necessary deployments and services for the AKS store application.
Create the Ingress resource that uses a host name on the Azure private DNS zone and a private IP address
Update host
with the name of your DNS host, for example, store-front.private.contoso.com. Verify you're specifying nginx-internal for the ingressClassName.
Copy the following YAML manifest into a new file named ingress.yaml and save the file to your local computer.
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: store-front namespace: aks-store spec: ingressClassName: nginx-internal rules: - host: store-front.private.contoso.com - http: paths: - backend: service: name: store-front port: number: 80 path: / pathType: Prefix
Create the ingress resource using the
kubectl apply
command.kubectl apply -f ingress.yaml -n aks-store
The following example output shows the created resource:
ingress.networking.k8s.io/store-front created
Verify the managed Ingress was created
You can verify the managed Ingress was created using the kubectl get ingress
command.
kubectl get ingress -n aks-store
The following example output shows the created managed Ingress:
NAME CLASS HOSTS ADDRESS PORTS AGE
store-front nginx-internal store-front.private.contoso.com 80 10s
Verify the Azure private DNS zone was updated
In a few minutes, run the az network private-dns record-set a list command to view the A records for your Azure private DNS zone. Specify the name of the resource group and the name of the DNS zone. In this example, the resource group is test-rg and DNS zone is private.contoso.com.
az network private-dns record-set a list \
--resource-group test-rg \
--zone-name private.contoso.com
The following example output shows the created record:
[
{
"aRecords": [
{
"ipv4Address": "10.224.0.7"
}
],
"etag": "ecc303c5-4577-4ca2-b545-d34e160d1c2d",
"fqdn": "store-front.private.contoso.com.",
"id": "/subscriptions/68ed2a89-5b8a-45e0-b2f9-65b8fa556333/resourceGroups/test-rg/providers/Microsoft.Network/privateDnsZones/private.contoso.com/A/store-front",
"isAutoRegistered": false,
"name": "store-front",
"resourceGroup": "test-rg",
"ttl": 300,
"type": "Microsoft.Network/privateDnsZones/A"
}
]
Next steps
For other configuration information related to SSL encryption other advanced NGINX ingress controller and ingress resource configuration, review DNS and SSL configuration and application routing add-on configuration.
Azure Kubernetes Service