39.4 Azure CNI and Kubenet Networking
Right, let’s talk networking. This is where the rubber meets the road in Kubernetes, and where Azure’s “managed” service starts to feel a lot more… hands-on. You have two primary choices here: the Azure-native kubenet and the more advanced, integrated Azure CNI. Your choice isn’t just about IP addresses; it’s a fundamental decision about how tightly you want your cluster woven into the fabric of your Azure Virtual Network (VNet). Choose poorly, and you’ll be dealing with a special kind of IP address hell. Let’s get into it.
Kubenet: The Simple(ish) Life
Kubenet is the default, and for good reason: it’s simple to set up and gets you going fast. Here’s the deal: Azure’s networking plugin creates a route table and allocates a single, lonely IP address from your VNet’s subnet to each node (the VM hosting your pods). Your pods, however, live in a completely separate, software-defined network. They get their IPs from a private CIDR block that’s only meaningful within the Kubernetes cluster.
This means Azure’s infrastructure (your VNet, other Azure services, on-prem networks) has no innate idea where your pods are. It’s like your pods live in a charming little village (the cluster) that only has one road (the node’s IP) connecting it to the big city (the VNet). To get traffic to a specific pod, you use Kubernetes services (LoadBalancer, ClusterIP) or you rely on the route table Azure creates, which tells the VNet “to get to the pod network 10.244.0.0/16, go through node 10.0.0.4”.
The main constraint, and it’s a big one, is scale. Since each node shares its single VNet IP for all outbound pod traffic and for SNAT, you can only run as many pods per node as Azure CNI allows. You’re also limited by the size of the subnet you provide—it only needs to have enough IPs for your nodes, not your pods. This is often the choice for getting started or for clusters that won’t grow massive.
# Creating a cluster with kubenet is straightforward.
# You just need a pre-existing VNet and subnet, or let Azure create one for you.
az aks create \
--resource-group myResourceGroup \
--name myAKSCluster \
--node-count 3 \
--network-plugin kubenet \
--service-cidr 10.0.0.0/16 \
--dns-service-ip 10.0.0.10 \
--pod-cidr 10.244.0.0/16 \
--vnet-subnet-id /subscriptions/<sub-id>/resourceGroups/<vnet-rg>/providers/Microsoft.Network/virtualNetworks/<vnet-name>/subnets/<subnet-name>
Azure CNI: The VNet Native Power Play
Azure Container Networking Interface (CNI) is the “no compromises” option for when you need your cluster to be a first-class citizen in your network. With Azure CNI, every pod gets a real, honest-to-goodness IP address from your Azure VNet subnet. No software-defined overlay networks, no NAT (for pod-to-pod traffic within the VNet). Your pod can talk directly to an Azure VM, a PaaS service with VNet integration, or an on-prem resource, and that resource sees the traffic as coming from the pod’s IP.
This is incredibly powerful. It means you can use Network Security Groups (NSGs) directly on pod IPs for micro-segmentation. It means your service discovery isn’t locked inside Kubernetes; a pod can talk to a database hosted on a VM using its native VNet DNS name. The integration is sublime.
The cost? Sheer, unadulterated IP address management. You must plan your subnet very carefully. Each node reserves IP addresses based on its VM size (e.g., a Standard_D8s_v3 reserves 30 IPs). So the formula is: (number of nodes) * (max pods per node) + (number of nodes) + (service address range size). You need a subnet large enough to handle all that, plus any future scaling. If you screw this up, you’ll be unable to scale your nodes or deploy new pods, full stop.
# Creating a cluster with Azure CNI. Note the much larger subnet size required.
az aks create \
--resource-group myResourceGroup \
--name myAKSCluster \
--node-count 3 \
--network-plugin azure \
--max-pods 50 \ # You MUST set this based on your node size and needs
--vnet-subnet-id /subscriptions/<sub-id>/resourceGroups/<vnet-rg>/providers/Microsoft.Network/virtualNetworks/<vnet-name>/subnets/<large-subnet-name>
The Gotchas and The Glory
Whichever you choose, there are landmines. With kubenet, the big one is egress traffic. Since all outbound traffic is SNAT’d through the node’s IP, if you have a dozen pods making calls to an external API, that API sees a dozen calls all from the same IP. This can quickly run you into rate limits. You also can’t easily use VNet-internal features that rely on a client’s source IP.
With Azure CNI, the gotcha is the aforementioned IP exhaustion. It’s the number one operational headache. You think “/23 is plenty!” until you need to scale during a holiday sale. Just use a /22 or larger from the start. I’m not kidding. Also, while pod-to-pod traffic is direct, pod-to-node traffic still gets weirdly routed through the host, a design choice I will politely call “interesting.”
The best practice? Use Azure CNI for any serious production workload where network integration and performance are key. The operational overhead of managing a large subnet is a fair trade for the raw power and simplicity of having every pod on the real network. Reserve kubenet for dev clusters, proof-of-concepts, or situations where you are severely constrained on VNet IP space and have no other choice.