AKS Networking Model Explained

Networking in Kubernetes involves several layers: node networks, pod networks, service networks, and external load balancers. In AKS, these layers integrate with Azure Virtual Networks. Understanding how they fit together helps you design your cluster correctly from the start — because many networking decisions cannot be changed without recreating the cluster.

The three IP address spaces

An AKS cluster uses three distinct IP address ranges:

  • Node network (VNet subnet) — the Azure VNet subnet where cluster nodes live. Node IPs come from here.
  • Pod CIDR — the IP range for pods. With Kubenet this is a separate overlay network. With Azure CNI, pods get IPs from the node subnet.
  • Service CIDR — a virtual IP range used only for Service cluster IPs. Traffic to these IPs is handled by kube-proxy rules — the IPs are never routed at the network level, only by the kernel on each node.

These three ranges must not overlap with each other, with your VNet, or with any peered networks. Plan them before creating your cluster. You cannot change them afterward without recreating the cluster.

Default address ranges

NetworkDefault CIDRMax sizeNotes
Service CIDR10.0.0.0/16ConfigurableVirtual IPs for Services. Must not exist in any VNet.
DNS Service IP10.0.0.10Single IPMust be within Service CIDR. Used for CoreDNS.
Pod CIDR (Kubenet)10.244.0.0/16ConfigurableOnly used with Kubenet CNI.
# Specify custom ranges when creating a cluster
az aks create \
  --resource-group my-aks-rg \
  --name my-cluster \
  --network-plugin kubenet \
  --pod-cidr 192.168.0.0/16 \
  --service-cidr 172.16.0.0/16 \
  --dns-service-ip 172.16.0.10 \
  --generate-ssh-keys

CNI plugins: Kubenet vs Azure CNI

The Container Network Interface (CNI) plugin determines how pod networking is implemented. AKS supports several options, with Kubenet and Azure CNI being the most common. See the Azure CNI vs Kubenet page for a full comparison. The key points:

  • Kubenet — simpler, less IP address consumption, but pods are behind NAT. Traffic from pods shows as the node IP. Cannot directly connect to pods from outside the cluster using pod IPs.
  • Azure CNI — every pod gets a real Azure VNet IP. Full VNet integration. Each pod IP must be pre-allocated in the subnet, consuming more address space but enabling direct pod connectivity from the VNet.
  • Azure CNI Overlay — a newer hybrid: pods get overlay IPs (not from VNet subnet) but still have full Azure network integration. Reduces IP address exhaustion concerns.

How Service networking works — kube-proxy

Service IPs are virtual — they do not exist in any routing table outside the nodes. When you create a Service with ClusterIP 10.0.142.200, no device in your VNet actually has that IP. Instead, kube-proxy programs iptables rules on every node.

When a pod sends traffic to 10.0.142.200:80, the kernel intercepts it before it leaves the node and redirects it to one of the backend pod IPs via DNAT (destination NAT). This happens at kernel speed with no additional process hop.

# See the iptables rules kube-proxy creates (on a node)
# You would need to SSH into a node or use a privileged debug pod

# Instead, inspect from kubectl:
kubectl get endpoints web-app
# These are the real pod IPs that iptables rules point to

# Check if kube-proxy is running
kubectl get pods -n kube-system -l k8s-app=kube-proxy

DNS in AKS — CoreDNS

Every AKS cluster runs CoreDNS as the cluster DNS server. Pods are configured to use the DNS service IP (typically 10.0.0.10) for DNS resolution. CoreDNS resolves:

  • Kubernetes service names to Service cluster IPs
  • Pod hostnames to pod IPs
  • External domains via upstream DNS (forwarded to Azure DNS)
# Check CoreDNS health
kubectl get pods -n kube-system -l k8s-app=kube-dns

# Test DNS resolution from inside a pod
kubectl run dns-test --image=busybox --rm -it -- \
  nslookup kubernetes.default.svc.cluster.local

# Expected output includes the Service cluster IP for the kubernetes API server

# Check CoreDNS config
kubectl describe configmap coredns -n kube-system

DNS is often the silent culprit when services cannot find each other. Always test DNS resolution first when debugging connectivity issues.

Network policies

By default, all pods can communicate with all other pods in the cluster — including pods in different namespaces. Network policies let you restrict this to only the connections your application requires.

# Network policies require a supporting CNI plugin
# Enable Azure Network Policy when creating a cluster
az aks create \
  --resource-group my-aks-rg \
  --name my-cluster \
  --network-plugin azure \
  --network-policy azure \
  --generate-ssh-keys

A network policy that allows the frontend to talk to the API, but nothing else to talk to the API:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-allow-frontend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-service
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: web-frontend
    ports:
    - protocol: TCP
      port: 8080

Once this policy is applied, only pods with label app=web-frontend can reach the API service on port 8080. All other ingress is denied.

Tip

Start with a default-deny-all policy for each namespace and then add allow rules for specific connections. This is safer than trying to add deny rules for specific combinations — it is easy to miss a route.

Controlling outbound traffic

AKS cluster nodes need outbound internet access to pull images, communicate with Azure APIs, and install updates. By default, AKS uses a public load balancer for outbound traffic. For tighter control:

# Use Azure NAT Gateway for outbound traffic
# Creates a static outbound IP for the cluster
az aks create \
  --resource-group my-aks-rg \
  --name my-cluster \
  --outbound-type managedNATGateway \
  --nat-gateway-managed-outbound-ip-count 1 \
  --nat-gateway-idle-timeout 4 \
  --generate-ssh-keys

# Or use User-Defined Routing to send egress through a firewall
az aks create \
  --resource-group my-aks-rg \
  --name my-cluster \
  --outbound-type userDefinedRouting \
  --generate-ssh-keys

User-Defined Routing lets you route all outbound cluster traffic through Azure Firewall, where you can log and filter it. This is required for compliance environments that need to audit what external services the cluster communicates with.

Common mistakes

  1. Overlapping CIDR ranges. If your service CIDR overlaps with an on-premises network or peered VNet, traffic to those networks breaks. Map out all IP ranges before creating the cluster.
  2. Insufficient subnet size with Azure CNI. Azure CNI allocates IPs per pod. A /24 subnet (256 IPs) sounds large, but with 10 nodes × 30 pods each = 300 pod IPs needed plus node IPs. Use at least a /22 for production Azure CNI clusters.
  3. Not enabling network policy. Without network policy, a compromised pod can reach any other pod in the cluster. Even a basic default-deny policy reduces lateral movement risk significantly.
  4. Relying on IP addresses for service discovery. Pod IPs and even cluster IPs can change if the cluster is recreated or if objects are deleted and recreated. Always use DNS names for service-to-service communication.
  5. Debugging network issues by restarting pods. Pod restarts do not fix network configuration problems. Check endpoints, network policies, and DNS first before restarting anything.

Frequently asked questions

Do pods in AKS have real Azure VNet IP addresses?

It depends on the CNI plugin. With Azure CNI, each pod gets a real IP from your VNet subnet. With Kubenet, pods get IPs from an overlay network and only nodes get VNet IPs. Azure CNI gives better Azure integration but consumes more subnet IPs.

How do pods on different nodes communicate with each other?

With Azure CNI, pods use direct VNet routing — pod-to-pod traffic across nodes stays within the VNet. With Kubenet, traffic goes through NAT on each node, which adds overhead and complexity.

What is a network policy and do I need one?

A network policy is a Kubernetes resource that controls which pods can communicate with which other pods. Without network policies, all pods can reach all other pods. In production, you should restrict this with policies to limit blast radius if a pod is compromised.

Last verified: 19 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.