Using public IPs from a public IP prefix in Azure Kubernetes Service

When creating a service of type LoadBalancer in AKS, AKS will by default use a random public IP address and configure that on the AKS load balancer. You can however use a static self-managed public IP address as well. Don’t confuse this with using a public ip prefix for the outbound rule for AKS though.

Today I had a customer meeting, where the customer expressed interest in using IPs from a public IP prefix. You can do this as well, learn more about how to do this here:

The process

Using a public IP from a public ip prefix is similar to the process of using a regular self-managed public IP in AKS. You’ll have to do the following steps to make this work:

  1. Create an AKS cluster.
  2. Create a public IP prefix
  3. Create a public IP from that prefix
  4. Give the AKS service principal permissions over the resource group of the public IP (*)
  5. Reference the resource group of that public IP and the IP address itself in the service definition in Kubernetes.

(*) AKS needs to list the public IP addresses in that resource group, so you’ll need to provide permissions to the full resource group of the public IP; not just the public IP itself.

Let’s walk through this. I did all of this using the Azure CLI, code can be found on GitHub.

Creating an AKS cluster

For this test, I created a very simple AKS cluster. You can see the command below:

az group create -n aks-prefix -l westus2
az aks create -g aks-prefix -n aks-prefix -l westus2 --enable-managed-identity --node-count 1 --generate-ssh-keys
az aks get-credentials -g aks-prefix -n aks-prefix

Creating public ip prefix and public ip

Next up, we’ll create a public IP prefix and public ip from that prefix. For the purposes of this example, I’m creating them in the same resource group as my AKS cluster; but you could create them in a separate resource group as well if you prefer.

# creating public ip prefix
az network public-ip prefix create \
    --length 30 \
    --name pip-prefix \
    --resource-group aks-prefix \
    --location westus2 \
    --version IPv4

# creating IP from prefix
az network public-ip create \
    --name pip-for-aks \
    --resource-group aks-prefix \
    --allocation-method Static \
    --public-ip-prefix pip-prefix \
    --sku Standard \
    --version IPv4

Giving AKS permissions on the resource group

Next, we’ll need to give AKS permissions on the resource group hosting the public IP. For this, we’ll need the ID of the managed identity assigned to AKS and the ID of the resource group.

RGID=$(az group show -n aks-prefix -o tsv --query id )
APPID=$(az aks show -n aks-prefix -g aks-prefix --query "identity.principalId" -o tsv)
az role assignment create \
    --assignee $APPID \
    --role "Network Contributor" \
    --scope $RGID

Creating a Kubernetes service using that public IP

And now, we can create the service in Kubernetes using that public IP. Let’s first get the actual IP address (we’ll need to input this later in the YAML for the service):

az network public-ip show \
    -n pip-for-aks \
    -g aks-prefix \
    --query "ipAddress" \
    -o tsv

This will show you the public IP address. You’ll then need to input that into the YAML to create the service. You also need to provide the resource group that the public IP is a part of:

apiVersion: v1
kind: Service
metadata:
  name: myapp
  annotations:
        service.beta.kubernetes.io/azure-load-balancer-resource-group: aks-prefix
spec:
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 80
  type: LoadBalancer
  loadBalancerIP: <your-public-ip>

And then you can create the service and check it’s creation in Kubernetes using the following command:

kubectl create -f service.yaml
kubectl get svc -w

And this should show you an output similar to this:

And that is an IP from the prefix we created earlier.

Summary

In this post, you learned how to use an IP address from a public IP prefix in AKS. We created a new cluster, created a public ip prefix and an IP in that prefix and finally linked that to the AKS cluster.

Leave a Reply