Azure CNI, when powered by Cilium, fundamentally changes how network policies are enforced on Azure Kubernetes Service (AKS) clusters, shifting from iptables to eBPF for blazing-fast, scalable policy enforcement.
Let’s see this in action. Imagine you have a simple AKS cluster with two deployments: frontend and backend.
# frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 2
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
# backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: httpd
image: httpd:latest
ports:
- containerPort: 80
By default, pods can talk to each other freely. Now, let’s enforce a policy where only the frontend pods can communicate with the backend pods.
# frontend-to-backend-allow.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: default # Assuming both deployments are in the default namespace
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80
When you apply this NetworkPolicy to a standard AKS cluster using azure-cni, Kubernetes’ kube-proxy (which often uses iptables under the hood) will program rules to allow this traffic. However, with Cilium powering Azure CNI, the story is different. Cilium uses eBPF programs directly on the network stack of your nodes. When a packet leaves a frontend pod destined for the backend pod’s port 80, the eBPF program attached to the network interface intercepts it. It checks the packet’s source and destination labels against the NetworkPolicy. If they match the allowed rule, the packet proceeds. If not, it’s dropped. This happens at a much lower level and with far greater efficiency than iptables traversing the kernel’s netfilter hooks.
The problem this solves is network security within your Kubernetes cluster. In large, dynamic environments, manually managing firewall rules for every service interaction becomes a nightmare. Network Policies, especially when implemented efficiently, allow you to define granular access control between pods based on their labels, treating network security as code. Cilium’s eBPF-based implementation brings performance and scalability to this model, overcoming the limitations of traditional iptables in high-throughput scenarios.
Internally, Cilium works by:
- Policy Translation: It translates Kubernetes
NetworkPolicyobjects into its own internal policy model. - eBPF Program Generation: It generates eBPF programs that are loaded into the Linux kernel on each node.
- Packet Interception & Enforcement: These eBPF programs hook into network events (like packet ingress and egress) and enforce the translated policies by inspecting packet metadata and making allow/deny decisions.
- Identity-Based Security: Cilium assigns a unique identity to each pod and service, which is used by the eBPF programs for policy enforcement, rather than relying solely on IP addresses.
The exact levers you control are primarily the NetworkPolicy objects themselves, defining podSelector, namespaceSelector, ingress, and egress rules. When using Cilium with Azure CNI, you also have access to Cilium-specific Custom Resource Definitions (CRDs) for more advanced features like multi-cluster networking, service mesh capabilities (via Hubble), and more sophisticated load balancing. The azure.microsoft.com/use-cilium annotation on your AKS node pools is the key flag to enable this integration.
A subtle but powerful aspect of Cilium’s eBPF implementation is how it handles service load balancing. Unlike kube-proxy which often relies on iptables SNATing, Cilium can perform its own load balancing decisions directly within eBPF. This means that when a packet from a frontend pod hits a backend service IP, Cilium’s eBPF program can select a backend pod and rewrite the destination IP and port before it even hits the regular network stack, all within the kernel, leading to significantly reduced latency and overhead.
The next concept you’ll likely explore is enabling Hubble, Cilium’s observability layer, to visualize network flows and policy enforcement in real-time.