Use a static public IP address with Sitecore in AKS

Running Sitecore in the Azure Kubernetes Services (AKS), Nginx Ingress controller provides a public IP address that we can use to bind a hostname and root traffic to the environment. But in case of any update/redeploy of the ingress controller, the public IP address will be changed which means the website will be unavailable until DNS records are not updated. To avoid this website downtime we need to set up a static public IP address for the ingress controller.

There are two ways to create a public IP address within Azure Subscription:

  • create a Public IP in a cluster’s resource group that is created within Kubernetes cluster;
  • create a Public IP within any other Resource Group.
In first case we need to get a cluster’s resource group name. The following command can be used for that:
 az aks show --resource-group <Resource-Group-Name> --name <Kubernetes-Cluster-Name> --query nodeResourceGroup -o tsv

where Resource-Group-Name is a name of the resource group where our cluster is created. Usually the cluster’s resource group name looks like:

MC_<Resource-Group-Name>_<Kubernetes-Cluster-Name>_<Cluster-Region>

Then we need to create a Public IP using the following command:

 az network public-ip create --resource-group MC_<Resource-Group-Name>_<Kubernetes-Cluster-Name>_<Cluster-Region> --name <IP-Address-Label-Name> --sku Standard --allocation-method static

In the second case the following command is used to create a static Public IP:

az network public-ip create --resource-group <Resource-Group-Name> --name <IP-Address-Label-Name> --sku Standard --allocation-method static

Then we need to ensure the cluster identity used by the AKS cluster has delegated permissions to the other resource group. For example:

 az role assignment create \
    --assignee <Client ID> \
    --role "Network Contributor" \
    --scope /subscriptions/<subscription id>/resourceGroups/<resource group name>

To get a newly created IP we need to run the following command:

az network public-ip show --resource-group <Resource-Group-Name> OR MC_<Resource-Group-Name>_<Kubernetes-Cluster-Name>_<Cluster-Region>  --name <IP-Address-Label-Name> --query "{address: ipAddress}"

 

Once we have a Public IP address added, we need to add two additional lines to the install ingress controller command:

helm install nginx-ingress ingress-nginx/ingress-nginx `

--set controller.replicaCount=2 `

--set controller.nodeSelector."beta\.kubernetes\.io/os"=linux `

--set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux `

--set controller.service.loadBalancerIP=<PUBLIC-IP-ADDRESS> `

--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"=<some-label> `

--set controller.admissionWebhooks.patch.nodeSelector."beta\.kubernetes\.io/os"=linux `

--set-string controller.config.proxy-body-size=10m

 

To make sure that everything is as expected, we can run a command below:

kubectl get services

The result of execution should look like following:

where EXTERNAL-IP should be the same as newly created. If you see <pending> instead, the following command can be useful for troubleshot:

kubectl describe service nginx-ingress-ingress-nginx-controller