Back to blog

Isovalent, Azure Linux, and Azure Kubernetes Service come together.

Amit Gupta
Amit Gupta
Published: Updated: Isovalent
Isovalent, Azure Linux, and Azure Kubernetes Service come together.

Isovalent Enterprise for Cilium can now be installed on Azure Kubernetes Service clusters using Azure Linux as the host Operating system. In this tutorial you will learn how to:

  • Install AKS clusters running Azure CNI powered by Cilium with Azure Linux.
  • Migrate your existing clusters on Azure CNI powered by Cilium from Ubuntu to Azure Linux
  • Upgrade your clusters from Azure CNI powered by Cilium running Azure Linux to Isovalent Enterprise for Cilium.

What is Isovalent Enterprise for Cilium?

Azure Kubernetes Service (AKS) uses Cilium natively wherein AKS combines the robust control plane of Azure CNI with the data plane of Cilium to provide high-performance networking and security. Isovalent Cilium Enterprise is an enterprise-grade, hardened distribution of open-source projects Cilium, Hubble, and Tetragon, built and supported by the Cilium creators. Cilium enhances networking and security at the network layer, while Hubble ensures thorough network observability and tracing. Tetragon ties it all together with runtime enforcement and security observability, offering a well-rounded solution for connectivity, compliance, multi-cloud, and security concerns. 

How can you deploy Isovalent Enterprise for Cilium?

Isovalent Enterprise for Cilium is available in the Azure Marketplace. It can also be deployed using Azure Resource Manager (ARM) Templates and Azure CLI.

What is Azure Linux?

Microsoft announced the General Availability for Azure Linux Container Host in May 2023. Azure Linux is a lightweight operating system, containing only the packages needed for a cloud environment. Azure Linux can be customized through custom packages and tools, to fit the requirements of your application. Azure Kubernetes Services is one such application that does Production-grade container orchestration as an option for container hosting. The Azure Linux container host for AKS is an open-source Linux distribution created by Microsoft, and it’s available as a container host on Azure Kubernetes Service (AKS).

Why Azure Linux as the host OS?

A popular question you would ask is why choose Azure Linux as the host OS:

  • Optimized to run in Azure. Built verified and digitally signed by Microsoft .
  • Supply chain security.
  • Smaller and leaner Linux to reduce footprint, surface attack area, & optimize performance.
  • Operational consistency across Edge to Cloud.
  • Rigorous validation and testing of packages and images on AKS infrastructure.

Pre-Requisites

The following prerequisites need to be taken into account before you proceed with this tutorial.

  • Azure CLI version 2.48.1 or later. Run az –version to see the currently installed version. If you need to install or upgrade, see Install Azure CLI.
  • If using ARM templates or the REST API, the AKS API version must be 2022–09–02-preview or later.
  • You should have an Azure Subscription.
  • Install kubectl.
  • Install Cilium CLI.
  • Install Helm.
  • To install Isovalent Enterprise for Cilium, contact sales@isovalent.com or support@isovalent.com 
  • Ensure you have enough quota resources to create an AKS cluster. Go to the Subscription blade, navigate to “Usage + Quotas”, and make sure you have enough quota for the following resources:
    -Regional vCPUs
    -Standard Dv4 Family vCPUs
  • You can choose regions where the respective quotas are available and not strictly follow the regions picked up during this tutorial.

Limitations with Azure Linux Container Host

  • Azure Linux cannot yet be deployed through the Azure Portal.
  • Azure Linux doesn’t support AppArmor. Support for SELinux can be manually configured.
  • Creating an AKS cluster on Isovalent Enterprise for Cilium with Azure Linux as the host OS will be available in a future release.

Installing Azure Linux on Azure Kubernetes Service Clusters

We will be covering the following combinations of how to install and migrate AKS clusters with Azure Linux.

Network Plugin
Default Nodepool OS
(during AKS cluster creation)

Additional Nodepool OS
(after AKS cluster creation)
Migration from Ubuntu to Azure Linux
Azure CNI (Powered by Cilium)-Overlay ModeAzure LinuxAzure LinuxN.A
Azure CNI (Powered by Cilium)-Overlay ModeUbuntuAzure LinuxYes
Azure CNI (Powered by Cilium)-Dynamic IP Allocation ModeAzure LinuxAzure LinuxN.A
Azure CNI (Powered by Cilium)-Dynamic IP Allocation ModeUbuntuAzure LinuxYes
Azure CNI (Powered by Cilium)-Overlay Mode  to Isovalent Enterprise for CiliumAzure LinuxN.AN.A
Bring your own CNI (BYOCNI)Azure LinuxAzure LinuxN.A
Bring your own CNI (BYOCNI)UbuntuAzure LinuxYes
  • N.A= Not Applicable
  • BYOCNI (Azure Linux) and BYOCNI (Ubuntu) have also been tested and validated. If you would like to get more information about them; you can get in touch with sales@isovalent.com and support@isovalent.com

Choosing the IMU for a Product?- Installation, Migration or Upgrade

You can take a look at this flowchart and then decide whether you would like to do:

  • A greenfield installation of your AKS cluster with Azure Linux
  • Upgrade/Migrate your existing AKS clusters from Ubuntu to Azure Linux

Scenario 1: AKS cluster on Azure CNI powered by Cilium in (Overlay mode) with Azure Linux

AKS Resource Group Creation

Create a Resource Group

az group create --name azpcoverlayal --location westus2

AKS Cluster creation

Create a cluster with Azure CNI Powered by Cilium with network-plugin as Azure, network-plugin-mode as Overlay, and network-dataplane as Cilium

az aks create -n azpcoverlayal -g azpcoverlayal -l westus2 \
  --network-plugin azure \
  --network-plugin-mode overlay \
  --pod-cidr 192.168.0.0/16 \
  --network-dataplane cilium \
  --os-sku AzureLinux

Set the Subscription

If you have multiple Azure subscriptions, choose the subscription you want to use.

  • Replace SubscriptionName with your subscription name.
  • You can also use your subscription ID instead of your subscription name.
az account set --subscription SubscriptionName

Set the Kubernetes Context

Log in to the Azure portal and browse to Kubernetes Services> select the respective Kubernetes service that was created ( AKS Cluster) and click on connect. This will help you connect to your AKS cluster and set the respective Kubernetes context.

az aks get-credentials --resource-group azpcoverlayal --name azpcoverlayal

Cluster Status Check

Check the status of the nodes and make sure they are in a ‘Ready’ state and are running ‘CBL-Mariner/Linux’ as the host OS.

kubectl get nodes -o wide
NAME                                STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE            KERNEL-VERSION     CONTAINER-RUNTIME
aks-nodepool1-34896908-vmss000000   Ready    agent   47m   v1.26.6   10.224.0.4    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-34896908-vmss000001   Ready    agent   47m   v1.26.6   10.224.0.6    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-34896908-vmss000002   Ready    agent   47m   v1.26.6   10.224.0.5    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22

Add nodepool with OS-type as AzureLinux

Add an Azure Linux node pool to your existing cluster.

Note- When adding a new Azure Linux node pool, you need to add at least one as --mode System . Otherwise, AKS will not allow you to delete your existing node pool.

az aks nodepool add --resource-group azpcoverlayal --cluster-name azpcoverlayal --name alnodepool --node-count 2 --os-sku AzureLinux --mode System

Cluster Status Check

Check the status of the newly added node and make sure they are in a ‘Ready’ state and are running ‘CBL-Mariner/Linux’ as the host OS.

kubectl get nodes -o wide
NAME                                 STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE            KERNEL-VERSION     CONTAINER-RUNTIME
aks-alnodepool-17576648-vmss000000   Ready    agent   51s   v1.26.6   10.224.0.8    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-alnodepool-17576648-vmss000001   Ready    agent   62s   v1.26.6   10.224.0.7    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-34896908-vmss000000    Ready    agent   51m   v1.26.6   10.224.0.4    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-34896908-vmss000001    Ready    agent   51m   v1.26.6   10.224.0.6    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-34896908-vmss000002    Ready    agent   51m   v1.26.6   10.224.0.5    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22

Scenario 2: AKS cluster on Azure CNI powered by Cilium (Overlay Mode) with Ubuntu (Migration to Azure Linux)

AKS Resource Group Creation

Create a Resource Group

az group create --name azpcoverlay --location francecentral

AKS Cluster creation

Create a cluster with Azure CNI Powered by Cilium with network-plugin as Azure, network-plugin-mode as Overlay, and network-dataplane as Cilium.

az aks create -n azpcoverlay -g azpcoverlay -l francecentral \
  --network-plugin azure \
  --network-plugin-mode overlay \
  --pod-cidr 192.168.0.0/16 \
  --network-dataplane cilium

Set the Subscription

If you have multiple Azure subscriptions, choose the subscription you want to use.

  • Replace SubscriptionName with your subscription name.
  • You can also use your subscription ID instead of your subscription name.
az account set --subscription SubscriptionName

Set the Kubernetes Context

Log in to the Azure portal and browse to Kubernetes Services> select the respective Kubernetes service that was created ( AKS Cluster) and click on connect. This will help you connect to your AKS cluster and set the respective Kubernetes context.

az aks get-credentials --resource-group azpcoverlayal --name azpcoverlay

Cluster Status Check

Check the status of the nodes and make sure they are in a ‘Ready’ state and are running ‘Ubuntu’ as the host OS.

kubectl get nodes -o wide
NAME                                STATUS   ROLES   AGE    VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
aks-nodepool1-20464456-vmss000000   Ready    agent   153m   v1.26.6   10.224.0.5    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1
aks-nodepool1-20464456-vmss000001   Ready    agent   153m   v1.26.6   10.224.0.4    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1
aks-nodepool1-20464456-vmss000002   Ready    agent   153m   v1.26.6   10.224.0.6    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1

Add nodepool with OS-type as AzureLinux

Add an Azure Linux node pool to your existing cluster.

Note- When adding a new Azure Linux node pool, you need to add at least one as --mode System . Otherwise, AKS will not allow you to delete your existing node pool.

az aks nodepool add --resource-group azpcoverlay --cluster-name azpcoverlay --name alnodepool --node-count 2 --os-sku AzureLinux --mode System

Cluster Status Check

Check the status of the newly added nodes and make sure they are in a ‘Ready’ state and are running ‘CBL-Mariner/Linux’ as the host OS.

kubectl get nodes -o wide
NAME                                 STATUS   ROLES   AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
aks-alnodepool-38981809-vmss000000   Ready    agent   2m10s   v1.26.6   10.224.0.8    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2    containerd://1.6.22
aks-alnodepool-38981809-vmss000001   Ready    agent   2m16s   v1.26.6   10.224.0.7    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2    containerd://1.6.22
aks-nodepool1-20464456-vmss000000    Ready    agent   158m    v1.26.6   10.224.0.5    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1
aks-nodepool1-20464456-vmss000001    Ready    agent   158m    v1.26.6   10.224.0.4    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1
aks-nodepool1-20464456-vmss000002    Ready    agent   158m    v1.26.6   10.224.0.6    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1

Migrate the default nodes to Azure Linux

You can migrate the default nodes that are created while creating the AKS cluster and are running Ubuntu as the host OS. This is optional and if not required you can skip this step. Migration is a 3-part process:

Cordon the existing Nodes (Default)

Cordoning marks specified nodes as unschedulable and prevents any more pods from being added to the nodes.

First, obtain the names of the nodes you’d like to cordon with kubectl get nodes:

kubectl get nodes -o wide
NAME                                 STATUS   ROLES   AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
aks-alnodepool-38981809-vmss000000   Ready    agent   2m10s   v1.26.6   10.224.0.8    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2    containerd://1.6.22
aks-alnodepool-38981809-vmss000001   Ready    agent   2m16s   v1.26.6   10.224.0.7    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2    containerd://1.6.22
aks-nodepool1-20464456-vmss000000    Ready    agent   158m    v1.26.6   10.224.0.5    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1
aks-nodepool1-20464456-vmss000001    Ready    agent   158m    v1.26.6   10.224.0.4    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1
aks-nodepool1-20464456-vmss000002    Ready    agent   158m    v1.26.6   10.224.0.6    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1

Next, using kubectl cordon <node-names>, specify the desired nodes in a space-separated list:

kubectl cordon aks-nodepool1-20464456-vmss000000 aks-nodepool1-20464456-vmss000001 aks-nodepool1-20464456-vmss000002

Check the status of the nodes that are being cordoned:

kubectl get nodes -o wide
NAME                                 STATUS                     ROLES   AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
aks-alnodepool-38981809-vmss000000   Ready                      agent   55m     v1.26.6   10.224.0.8    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2    containerd://1.6.22
aks-alnodepool-38981809-vmss000001   Ready                      agent   56m     v1.26.6   10.224.0.7    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2    containerd://1.6.22
aks-nodepool1-20464456-vmss000000    Ready,SchedulingDisabled   agent   3h32m   v1.26.6   10.224.0.5    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1
aks-nodepool1-20464456-vmss000001    Ready,SchedulingDisabled   agent   3h32m   v1.26.6   10.224.0.4    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1
aks-nodepool1-20464456-vmss000002    Ready,SchedulingDisabled   agent   3h32m   v1.26.6   10.224.0.6    <none>        Ubuntu 22.04.3 LTS   5.15.0-1049-azure   containerd://1.7.5-1

Drain the existing nodes (Default)

To successfully drain nodes and evict running pods, ensure that any PodDisruptionBudgets (PDBs) allow for at least 1 pod replica to be moved at a time, otherwise, the drain/evict operation will fail. To check this, you can run kubectl get pdb -A, and make sure ALLOWED DISRUPTIONS is at least 1 or higher.

kubectl get pdb -A
NAMESPACE     NAME                 MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
kube-system   coredns-pdb          1               N/A               1                     68m
kube-system   konnectivity-agent   1               N/A               1                     68m
kube-system   metrics-server-pdb   1               N/A               1                     68m

Draining nodes will cause pods running on them to be evicted and recreated on the other, schedulable nodes.

To drain nodes, use kubectl drain <node-names> --ignore-daemonsets --delete-emptydir-data, again using a space-separated list of node names:

Note- Using --delete-emptydir-data is required to evict the AKS-created coredns and metrics-server pods. If this flag isn’t used, an error is expected.

kubectl drain aks-nodepool1-20464456-vmss000000 aks-nodepool1-20464456-vmss000001 aks-nodepool1-20464456-vmss000002 --ignore-daemonsets --delete-emptydir-data

Remove the existing nodes (Default)

To remove the existing nodes use the az aks delete command. The final result is the AKS cluster having a single Azure Linux node pool with the desired SKU size and all the applications and pods properly running.

az aks nodepool delete \
    --resource-group azpcoverlay \
    --cluster-name azpcoverlay \
    --name nodepool1

Check the status of the nodes to ensure that the default node has been deleted and the additional node running AzureLinux is in a ‘Ready’ state:

kubectl get nodes -o wide
NAME                                 STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE            KERNEL-VERSION     CONTAINER-RUNTIME
aks-alnodepool-38981809-vmss000000   Ready    agent   60m   v1.26.6   10.224.0.8    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-alnodepool-38981809-vmss000001   Ready    agent   60m   v1.26.6   10.224.0.7    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22

Scenario 3: AKS cluster on Azure CNI powered by Cilium (Dynamic IP mode) with Azure Linux

AKS Resource Group Creation

Create a Resource Group

az group create --name azpcvnet --location canadacentral

AKS Network creation

Create a virtual network with a subnet for nodes and a subnet for pods and retrieve the subnetID

az network vnet create -g azpcvnet --location canadacentral --name azpcvnet --address-prefixes 10.0.0.0/8 -o none

az network vnet subnet create -g azpcvnet --vnet-name azpcvnet --name nodesubnet --address-prefixes 10.240.0.0/16 -o none

az network vnet subnet create -g azpcvnet --vnet-name azpcvnet --name podsubnet --address-prefixes 10.241.0.0/16 -o none

AKS Cluster creation

Create an AKS cluster referencing the node subnet using –vnet-subnet-id and the pod subnet using –pod-subnet-id. Make sure to use the argument –network-plugin as azure and network-dataplane as cilium.

az aks create -n azpcvnet -g azpcvnet -l canadacentral \
  --max-pods 250 \
  --network-plugin azure \
  --vnet-subnet-id /subscriptions/<subscription-id>/resourceGroups/azpcvnet/providers/Microsoft.Network/virtualNetworks/azpcvnet/subnets/nodesubnet \
  --pod-subnet-id /subscriptions/<subscription-id>/resourceGroups/azpcvnet/providers/Microsoft.Network/virtualNetworks/azpcvnet/subnets/podsubnet \
  --network-dataplane cilium \
  --os-sku AzureLinux

Set the Subscription

If you have multiple Azure subscriptions, choose the subscription you want to use.

  • Replace SubscriptionName with your subscription name.
  • You can also use your subscription ID instead of your subscription name.
az account set --subscription SubscriptionName

Set the Kubernetes Context

Log in to the Azure portal and browse to Kubernetes Services> select the respective Kubernetes service that was created ( AKS Cluster) and click on connect. This will help you connect to your AKS cluster and set the respective Kubernetes context.

az aks get-credentials --resource-group azpcvnet --name azpcvnet

Cluster Status Check

Check the status of the nodes and make sure they are in a ‘Ready’ state and are running ‘CBL-Mariner/Linux’ as the host OS.

kubectl get nodes -o wide
NAME                                STATUS   ROLES   AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE            KERNEL-VERSION     CONTAINER-RUNTIME
aks-nodepool1-35610968-vmss000000   Ready    agent   56m     v1.26.6   10.240.0.5    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-35610968-vmss000001   Ready    agent   55m     v1.26.6   10.240.0.4    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-35610968-vmss000002   Ready    agent   56m     v1.26.6   10.240.0.6    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22

Add nodepool with OS-type as AzureLinux

Add an Azure Linux node pool to your existing cluster. In the case of Azure CNI (Dynamic IP allocation), you need to add a new subnet for pods and nodes in addition to what was created originally at the time of the AKS cluster creation.

Note- When adding a new Azure Linux node pool, you need to add at least one as --mode System . Otherwise, AKS will not allow you to delete your existing node pool.

az network vnet subnet create --resource-group azpcvnet  --vnet-name azpcvnet  --name node2subnet --address-prefixes 10.242.0.0/16 -o none

az network vnet subnet create --resource-group azpcvnet  --vnet-name azpcvnet --name pod2subnet --address-prefixes 10.243.0.0/16 -o none

az aks nodepool add --cluster-name azpcvnet --resource-group azpcvnet --name azpclinux --max-pods 250 --node-count 2 --vnet-subnet-id /subscriptions/<subscription-id>/resourceGroups/azpcvnet/providers/Microsoft.Network/virtualNetworks/azpcvnet/subnets/node2subnet  --pod-subnet-id /subscriptions/<subscription-id>/resourceGroups/azpcvnet/providers/Microsoft.Network/virtualNetworks/azpcvnet/subnets/pod2subnet  --os-sku AzureLinux --mode System 

Cluster Status Check

Check the status of the newly added node and make sure they are in a ‘Ready’ state and are running ‘CBL-Mariner/Linux’ as the host OS.

kubectl get nodes -o wide
NAME                                STATUS   ROLES   AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE            KERNEL-VERSION     CONTAINER-RUNTIME
aks-azpclinux-27886613-vmss000000   Ready    agent   3m57s   v1.26.6   10.242.0.5    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-azpclinux-27886613-vmss000001   Ready    agent   4m5s    v1.26.6   10.242.0.4    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-35610968-vmss000000   Ready    agent   56m     v1.26.6   10.240.0.5    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-35610968-vmss000001   Ready    agent   55m     v1.26.6   10.240.0.4    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-35610968-vmss000002   Ready    agent   56m     v1.26.6   10.240.0.6    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22

Scenario 4: AKS cluster on Azure CNI powered by Cilium (Dynamic IP mode) with Ubuntu (Migration to Azure Linux)

AKS Resource Group Creation

Create a Resource Group

az group create --name azpcvnet1 --location australiacentral

AKS Network creation

Create a virtual network with a subnet for nodes and a subnet for pods and retrieve the subnetID

az network vnet create -g azpcvnet1 --location australiacentral --name azpcvnet1 --address-prefixes 10.0.0.0/8 -o none

az network vnet subnet create -g azpcvnet1 --vnet-name azpcvnet1 --name nodesubnet --address-prefixes 10.240.0.0/16 -o none

az network vnet subnet create -g azpcvnet1 --vnet-name azpcvnet1 --name podsubnet --address-prefixes 10.241.0.0/16 -o none

AKS Cluster creation

Create an AKS cluster referencing the node subnet using –vnet-subnet-id and the pod subnet using –pod-subnet-id. Make sure to use the argument –network-plugin as azure and network-dataplane as cilium.

az aks create -n azpcvnet1 -g azpcvnet1 -l australiacentral \
  --max-pods 250 \
  --network-plugin azure \
  --vnet-subnet-id /subscriptions/<subscription-id>/resourceGroups/azpcvnet1/providers/Microsoft.Network/virtualNetworks/azpcvnet1/subnets/nodesubnet \
  --pod-subnet-id /subscriptions/<subscription-id>/resourceGroups/azpcvnet1/providers/Microsoft.Network/virtualNetworks/azpcvnet1/subnets/podsubnet \
  --network-dataplane cilium

Set the Subscription

If you have multiple Azure subscriptions, choose the subscription you want to use.

  • Replace SubscriptionName with your subscription name.
  • You can also use your subscription ID instead of your subscription name.
az account set --subscription SubscriptionName

Set the Kubernetes Context

Log in to the Azure portal and browse to Kubernetes Services> select the respective Kubernetes service that was created ( AKS Cluster) and click on connect. This will help you connect to your AKS cluster and set the respective Kubernetes context.

az aks get-credentials --resource-group azpcvnet1 --name azpcvnet1

Cluster Status Check

Check the status of the nodes and make sure they are in a ‘Ready’ state and are running ‘Ubuntu’ as the host OS.

kubectl get nodes -o wide
NAME                                STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
aks-nodepool1-23335260-vmss000000   Ready    agent   21m   v1.26.6   10.240.0.5    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1
aks-nodepool1-23335260-vmss000001   Ready    agent   21m   v1.26.6   10.240.0.4    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1
aks-nodepool1-23335260-vmss000002   Ready    agent   21m   v1.26.6   10.240.0.6    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1

Add nodepool with OS-type as AzureLinux

Add an Azure Linux node pool to your existing cluster. In the case of Azure CNI (Dynamic IP allocation), you need to add a new subnet for pods and nodes in addition to what was created originally at the time of the AKS cluster creation.

Note- When adding a new Azure Linux node pool, you need to add at least one as --mode System . Otherwise, AKS will not allow you to delete your existing node pool.

az network vnet subnet create --resource-group azpcvnet1  --vnet-name azpcvnet1  --name node2subnet --address-prefixes 10.242.0.0/16 -o none

az network vnet subnet create --resource-group azpcvnet1  --vnet-name azpcvnet1 --name pod2subnet --address-prefixes 10.243.0.0/16 -o none

az aks nodepool add --cluster-name azpcvnet1 --resource-group azpcvnet1 --name azpclinux1 --max-pods 250 --node-count 2 --vnet-subnet-id /subscriptions/<subscription-id>/resourceGroups/azpcvnet1/providers/Microsoft.Network/virtualNetworks/azpcvnet1/subnets/node2subnet  --pod-subnet-id /subscriptions/<subscription-id>/resourceGroups/azpcvnet1/providers/Microsoft.Network/virtualNetworks/azpcvnet1/subnets/pod2subnet  --os-sku AzureLinux --mode System

Cluster Status Check

Check the status of the newly added node and make sure they are in a ‘Ready’ state and are running ‘CBL-Mariner/Linux’ as the host OS.

kubectl get nodes -o wide
NAME                                 STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
aks-azpclinux1-23905787-vmss000000   Ready    agent   10m   v1.26.6   10.242.0.5    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2   containerd://1.6.22
aks-azpclinux1-23905787-vmss000001   Ready    agent   10m   v1.26.6   10.242.0.4    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-23335260-vmss000000    Ready    agent   39m   v1.26.6   10.240.0.5    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1
aks-nodepool1-23335260-vmss000001    Ready    agent   39m   v1.26.6   10.240.0.4    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1
aks-nodepool1-23335260-vmss000002    Ready    agent   39m   v1.26.6   10.240.0.6    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1

Migrate the default nodes to Azure Linux

You can migrate the default nodes that are created while creating the AKS cluster and are running Ubuntu as the host OS. This is optional and if not required you can skip this step. Migration is a 3-part process:

Cordon the existing Nodes (Default)

Cordoning marks specified nodes as unschedulable and prevents any more pods from being added to the nodes.

First, obtain the names of the nodes you’d like to cordon with kubectl get nodes:

kubectl get nodes -o wide
NAME                                 STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
aks-azpclinux1-23905787-vmss000000   Ready    agent   32m   v1.26.6   10.242.0.5    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2   containerd://1.6.22
aks-azpclinux1-23905787-vmss000001   Ready    agent   32m   v1.26.6   10.242.0.4    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-23335260-vmss000000    Ready    agent   61m   v1.26.6   10.240.0.5    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1
aks-nodepool1-23335260-vmss000001    Ready    agent   61m   v1.26.6   10.240.0.4    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1
aks-nodepool1-23335260-vmss000002    Ready    agent   61m   v1.26.6   10.240.0.6    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1

Next, using kubectl cordon <node-names>, specify the desired nodes in a space-separated list:

kubectl cordon aks-nodepool1-23335260-vmss000000 aks-nodepool1-23335260-vmss000001 aks-nodepool1-23335260-vmss000002

Check the status of the nodes that are being cordoned:

kubectl get nodes -o wide
NAME                                 STATUS                     ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
aks-azpclinux1-23905787-vmss000000   Ready                      agent   45m   v1.26.6   10.242.0.5    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2   containerd://1.6.22
aks-azpclinux1-23905787-vmss000001   Ready                      agent   45m   v1.26.6   10.242.0.4    <none>        CBL-Mariner/Linux    5.15.131.1-2.cm2   containerd://1.6.22
aks-nodepool1-23335260-vmss000000    Ready,SchedulingDisabled   agent   74m   v1.26.6   10.240.0.5    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1
aks-nodepool1-23335260-vmss000001    Ready,SchedulingDisabled   agent   74m   v1.26.6   10.240.0.4    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1
aks-nodepool1-23335260-vmss000002    Ready,SchedulingDisabled   agent   74m   v1.26.6   10.240.0.6    <none>        Ubuntu 22.04.3 LTS   6.2.0-1014-azure   containerd://1.7.5-1

Drain the existing nodes (Default)

To successfully drain nodes and evict running pods, ensure that any PodDisruptionBudgets (PDBs) allow for at least 1 pod replica to be moved at a time, otherwise, the drain/evict operation will fail. To check this, you can run kubectl get pdb -A, and make sure ALLOWED DISRUPTIONS is at least 1 or higher.

kubectl get pdb -A
NAMESPACE     NAME                 MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
kube-system   coredns-pdb          1               N/A               1                     68m
kube-system   konnectivity-agent   1               N/A               1                     68m
kube-system   metrics-server-pdb   1               N/A               1                     68m

Draining nodes will cause pods running on them to be evicted and recreated on the other, schedulable nodes.

To drain nodes, use kubectl drain <node-names> --ignore-daemonsets --delete-emptydir-data, again using a space-separated list of node names:

Note- Using --delete-emptydir-data is required to evict the AKS-created coredns and metrics-server pods. If this flag isn’t used, an error is expected.

kubectl drain aks-nodepool1-23335260-vmss000000 aks-nodepool1-23335260-vmss000001 aks-nodepool1-23335260-vmss000002 --ignore-daemonsets --delete-emptydir-data

Remove the existing nodes (Default)

To remove the existing nodes use the az aks delete command. The final result is the AKS cluster having a single Azure Linux node pool with the desired SKU size and all the applications and pods properly running.

az aks nodepool delete \
    --resource-group azpcvnet1 \
    --cluster-name azpcvnet1 \
    --name nodepool1

Check the status of the nodes to ensure that the default node has been deleted and the additional node running AzureLinux is in a ‘Ready’ state:

kubectl get nodes -o wide
NAME                                 STATUS   ROLES   AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE            KERNEL-VERSION     CONTAINER-RUNTIME
aks-azpclinux1-23905787-vmss000000   Ready    agent   48m   v1.26.6   10.242.0.5    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22
aks-azpclinux1-23905787-vmss000001   Ready    agent   48m   v1.26.6   10.242.0.4    <none>        CBL-Mariner/Linux   5.15.131.1-2.cm2   containerd://1.6.22

Scenario 5: AKS cluster on Isovalent Enterprise for Cilium with Azure Linux

Note- You can upgrade your existing clusters as described in Scenarios 1 to 4 to Isovalent Enterprise for Cilium through Azure Marketplace and we have chosen one of those options to highlight the upgrade process. The steps for upgrading all the 4 scenarios are the same.

You can follow this blog and the steps outlined to upgrade an existing AKS cluster to Isovalent Enterprise for Cilium. Make sure you take care of the prerequisites.

  • In the Azure portal, search for Marketplace on the top search bar. In the results, under Services, select Marketplace.

  • Type ‘Isovalent’ In the search window and select the offer.

  • On the Plans + Pricing tab, select an option. Ensure that the terms are acceptable, and then select Create.
  • Select the resource group in which the cluster exists that we will be upgraded.
  • Click Create New Dev Cluster, select ‘No’ and click Next: Cluster Details.

  • As ‘No’ was selected, this will result in an upgrade of an already existing cluster in that region
  • The name for the AKS cluster will be auto-populated by clicking on the drop-down selection.
  • Click ‘Next: Review + Create’ Details.

  • Once Final validation is complete, click ‘Create’

  • When the application is deployed, the portal will show ‘Your deployment is complete’, along with details of the deployment.

  • Verify that the nodes are running Azure Linux. Click > Resource Groups> Kubernetes Services> Select the AKS cluster> Nodepools

How to upgrade Azure Linux Container Host Nodes?

The Azure Linux Container Host ships updates through Updated Azure Linux node images

Note- Make sure you have an AKS cluster either running Azure Linux or migrated to Azure Linux by following the steps outlined in the previous sections.

Manually upgrade your cluster

To manually upgrade the node-image on a cluster:

az aks nodepool upgrade \
    --resource-group azcnial \
    --cluster-name azcnial \
    --name alnodepool \
    --node-image-only

Validation- Isovalent Enterprise for Cilium

Validate the version of Isovalent Enterprise for Cilium

Check the version of Isovalent Enterprise for Cilium with cilium version:

kubectl -n kube-system exec ds/cilium -- cilium version
Defaulted container "cilium-agent" out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
Client: 1.13.4-cee.1 22f99e91 2023-06-15T03:11:44+00:00 go version go1.19.10 linux/amd64
Daemon: 1.13.4-cee.1 22f99e91 2023-06-15T03:11:44+00:00 go version go1.19.10 linux/amd64

Cilium Health Check

cilium-health is a tool available in Cilium that provides visibility into the overall health of the cluster’s networking connectivity. You can check node-to-node health with cilium-health status:

kubectl -n kube-system exec ds/cilium -- cilium-health status
Defaulted container "cilium-agent" out of: cilium-agent, config (init), mount-cgroup (init), apply-sysctl-overwrites (init), mount-bpf-fs (init), clean-cilium-state (init), install-cni-binaries (init)
Probe time:   2023-11-02T13:13:21Z
Nodes:
  aks-al nodepool-38475519-vm 000001 (localhost):
    Host connectivity to 10.240.0.120:
      ICMP to stack:   OK, RTT=342.3µs
      HTTP to agent:   OK, RTT=321.801µs
    Endpoint connectivity to 10.0.3.230:
      ICMP to stack:   OK, RTT=346.601µs
      HTTP to agent:   OK, RTT=995.002µs
  aks-alnodepool-38475519-vmss000000:
    Host connectivity to 10.240.0.91:
      ICMP to stack:   OK, RTT=2.584705ms
      HTTP to agent:   OK, RTT=1.347503ms
    Endpoint connectivity to 10.0.4.49:
      ICMP to stack:   OK, RTT=633.301µs
      HTTP to agent:   OK, RTT=4.180909ms

Cilium Connectivity Test

The Cilium connectivity test deploys a series of services, deployments, and CiliumNetworkPolicy which will use various connectivity paths to connect. Connectivity paths include with and without service load-balancing and various network policy combinations.

Cilium connectivity test was run for all of the above scenarios and the tests passed successfully. Adding a truncated output for one such test result.

cilium connectivity test
ℹ️  Monitor aggregation detected, will skip some flow validation steps
[azpcvnet] Creating namespace cilium-test for connectivity check...
[azpcvnet] Deploying echo-same-node service...
[azpcvnet] Deploying DNS test server configmap...
[azpcvnet] Deploying same-node deployment...
[azpcvnet] Deploying client deployment...
[azpcvnet] Deploying client2 deployment...
[azpcvnet] Deploying echo-other-node service...
[azpcvnet] Deploying other-node deployment...
[host-netns] Deploying byocni daemonset...
[host-netns-non-cilium] Deploying byocni daemonset...
[azpcvnet] Deploying echo-external-node deployment...
[azpcvnet] Waiting for deployments [client client2 echo-same-node] to become ready...
[azpcvnet] Waiting for deployments [echo-other-node] to become ready...
[azpcvnet] Waiting for CiliumEndpoint for pod cilium-test/client-6f6788d7cc-qzvl2 to appear...
[azpcvnet] Waiting for CiliumEndpoint for pod cilium-test/client2-bc59f56d5-7d9nx to appear...
[azpcvnet] Waiting for pod cilium-test/client-6f6788d7cc-qzvl2 to reach DNS server on cilium-test/echo-same-node-6d449fcc4-9r7wb pod...
[azpcvnet] Waiting for pod cilium-test/client2-bc59f56d5-7d9nx to reach DNS server on cilium-test/echo-same-node-6d449fcc4-9r7wb pod...
[azpcvnet] Waiting for pod cilium-test/client-6f6788d7cc-qzvl2 to reach DNS server on cilium-test/echo-other-node-5dbf9455cb-p2662 pod...
[azpcvnet] Waiting for pod cilium-test/client2-bc59f56d5-7d9nx to reach DNS server on cilium-test/echo-other-node-5dbf9455cb-p2662 pod...
[azpcvnet] Waiting for pod cilium-test/client-6f6788d7cc-qzvl2 to reach default/kubernetes service...
[azpcvnet] Waiting for pod cilium-test/client2-bc59f56d5-7d9nx to reach default/kubernetes service...
🏃 Running tests...
✅ All 42 tests (313 actions) successful, 12 tests skipped, 1 scenarios skipped.

Caveats/ Troubleshooting

  • If you are adding a nodepool with network plugins Azure CNI Dynamic IP or Azure CNI powered by Cilium and a different/new subnet for both pods and nodes has not been added you will observe this error.
az aks nodepool add --resource-group azpcvnet --cluster-name azpcvnet --name azpcvnet --node-count 2 --os-sku AzureLinux --mode System
The behavior of this command has been altered by the following extension: aks-preview
(InvalidParameter) All or none of the agentpools should set podsubnet
Code: InvalidParameter
Message: All or none of the agentpools should set podsubnet
  • If you are deleting a nodepool in any of the above scenarios that have been explained, ensure that there is one nodepool that was created with --mode System else you will observe this error.
az aks nodepool delete \
    --resource-group azpcvnet \
    --cluster-name azpcvnet \
    --name nodepool1
The behavior of this command has been altered by the following extension: aks-preview
(OperationNotAllowed) There has to be at least one system agent pool.
Code: OperationNotAllowed
Message: There has to be at least one system agent pool.

Conclusion

Hopefully, this post gave you a good overview of how to install or migrate your existing or new AKS clusters running Azure CNI powered by Cilium with Azure Linux; and also upgrade to Isovalent Enterprise for Cilium. If you have any feedback on the solution, please share it with us. You’ll find us on the Cilium Slack channel.

Try it out

Further Reading

Amit Gupta
AuthorAmit GuptaSenior Technical Marketing Engineer

Related

Blogs

Isovalent in Azure Kubernetes Service (AKS)

In this tutorial, users will learn how to deploy Isovalent Enterprise for Cilium on your AKS cluster from Azure Marketplace on a new cluster and also upgrade an existing cluster from an AKS cluster running Azure CNI powered by Cilium to Isovalent Enterprise for Cilium.

Amit Gupta
Amit Gupta
Blogs

Enabling Enterprise features for Isovalent in Azure Kubernetes Service (AKS)

In this tutorial, you will learn how to enable Enterprise features (Layer-3, 4 & 7 policies, DNS-based policies, and observe the Network Flows using Hubble-CLI) in an Azure Kubernetes Service (AKS) cluster running Isovalent Enterprise for Cilium.

Amit Gupta
Amit Gupta

Industry insights you won’t delete. Delivered to your inbox weekly.