Azure AKS Networking: VNET Integration and CNI
Azure AKS Networking: VNET Integration and CNI
Complete guide to Azure CNI vs Kubenet for AKS networking, VNET integration, private clusters, and best practices for production.
Table of Contents
- AKS Networking Models
- Azure CNI vs Kubenet
- VNET Integration
- Private AKS Clusters
- Network Policy
- DNS and Ingress
- Common Issues
AKS Networking Models
Two models determine how pods get IP addresses:
| Kubenet | Azure CNI | |
|---|---|---|
| Pod IPs | From an overlay network | Directly from the VNET subnet |
| Routable | Only within cluster | Routable on the VNET |
| Scale | IP-efficient | Requires larger subnet |
| Use case | Small clusters, IP-constrained | Production, hybrid networking |
Azure CNI vs Kubenet
Kubenet (Default)
az aks create \
--resource-group my-rg \
--name my-cluster \
--network-plugin kubenet \
--pod-cidr 10.244.0.0/16
Pods get IPs from 10.244.0.0/16 — not your VNET. Traffic flows through NAT on the node.
Azure CNI
az aks create \
--resource-group my-rg \
--name my-cluster \
--network-plugin azure \
--vnet-subnet-id /subscriptions/.../subnets/aks-subnet \
--pod-subnet-id /subscriptions/.../subnets/pod-subnet # optional
Pods get IPs directly from the VNET subnet — routable, firewall-friendly, but consumes real IPs.
Azure CNI Overlay (Best of Both)
az aks create \
--resource-group my-rg \
--name my-cluster \
--network-plugin azure \
--network-plugin-mode overlay
Pods get IPs from a private overlay (like Kubenet) but appear on the VNET for north-south traffic.
VNET Integration
Custom VNET
# Create VNET first
az network vnet create \
--resource-group my-rg \
--name aks-vnet \
--address-prefix 10.0.0.0/8 \
--subnet-name aks-subnet \
--subnet-prefix 10.240.0.0/16
az aks create \
--resource-group my-rg \
--name my-cluster \
--vnet-subnet-id $(az network vnet subnet show -g my-rg --vnet-name aks-vnet -n aks-subnet --query id -o tsv) \
--network-plugin azure \
--service-cidr 10.0.0.0/16 \
--dns-service-ip 10.0.0.10
Subnet Sizing
Azure CNI assigns a real IP per pod. Plan for:
Subnet size = (max pods per node × max nodes) + system pods + headroom
Example: 50 nodes × 30 pods = 1500 IPs → /20 (4094 usable) is safe.
Private AKS Clusters
az aks create \
--resource-group my-rg \
--name private-cluster \
--enable-private-cluster \
--private-dns-zone system
API server gets a private IP. Access via:
az aks command invokefor one-off commands- VPN/ExpressRoute for kubectl
- Azure Bastion + jumpbox VM
Network Policy
# Enable at cluster creation
az aks create \
--resource-group my-rg \
--name my-cluster \
--network-plugin azure \
--network-policy azure # or calico
Apply Kubernetes NetworkPolicies as normal:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
DNS and Ingress
Azure DNS for Private Clusters
az aks create \
--enable-private-cluster \
--private-dns-zone /subscriptions/.../privatednszones/privatelink.uksouth.azmk8s.io
Application Gateway Ingress Controller
az aks create \
--resource-group my-rg \
--name my-cluster \
--enable-addon ingress-appgw \
--appgw-name my-appgw \
--appgw-subnet-id /subscriptions/.../subnets/appgw-subnet
Internal Load Balancer
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
spec:
type: LoadBalancer
# ...
Common Issues
Pods Can't Resolve DNS
kubectl exec -it <pod> -- nslookup kubernetes.default
# Check CoreDNS logs:
kubectl logs -n kube-system -l k8s-app=kube-dns
Pods Can't Reach External IPs
Check Network Security Groups on the AKS subnet — outbound rules may be too restrictive.
CNI IP Exhaustion
# Check available IPs
az network vnet subnet show -g my-rg --vnet-name aks-vnet -n aks-subnet \
--query "availableIpAddressCount"
Private Cluster DNS Not Resolving
Ensure the private DNS zone is linked to the VNET where your VM/bastion lives.
Related Articles
Last Updated: October 2026
Author: CloudOpsGuide Team
Difficulty: Intermediate
Estimated Reading Time: 14 minutes