IPAM and Network Policies
Supported Versions: Cilium 1.18 Last Updated: February 23, 2026
Lab Environment Setup
To follow along with the examples in this document, you need the following tools and environment:
Required Tools
- kubectl v1.31 or higher
- A working Kubernetes cluster (EKS, minikube, kind, etc.)
- Cilium CLI
IPAM and Network Policy Lab Setup
# Check Cilium status
cilium status --wait
# Check current IPAM configuration
kubectl -n kube-system get configmap cilium-config -o yaml | grep -E 'ipam|allocator'
# Create namespace for network policy testing
kubectl create namespace policy-test
# Deploy test application
kubectl -n policy-test apply -f https://raw.githubusercontent.com/cilium/cilium/v1.14/examples/minikube/http-sw-app.yamlIP Address Management (IPAM) Strategies
Key Concept: IPAM (IP Address Management) is a system responsible for allocating, tracking, and managing IP addresses.
IPAM is a system responsible for allocating, tracking, and managing IP addresses. Cilium supports various IPAM modes that can be flexibly configured to match different environments and requirements.
Cilium IPAM Architecture
Cilium IPAM Modes:
Cluster Pool:
- Default IPAM mode
- Centralized IP address allocation across the entire cluster
- Can configure single or multiple IP pools
- Simple and easy to use
Kubernetes Host Scope:
- Allocates IP address range to each node
- Node allocates IP addresses from its own range
- No central coordination needed
- Prevents IP conflicts between nodes
CRD-based IPAM:
- IP pool definition through CiliumIPPool custom resource
- Allocate IP pools to specific namespaces or pods
- Fine-grained IP address management
- Dynamic IP pool management
AWS ENI (Elastic Network Interface):
- AWS VPC ENI integration
- Assigns native VPC IP addresses to pods
- VPC native networking without overlay network
- Optimized for AWS environment
Azure IPAM:
- Azure VNET integration
- Assigns native VNET IP addresses to pods
- Optimized for Azure environment
IPAM Components:
- IP Pool: Range of IP addresses available for allocation
- IP Allocation: Assigning IP addresses to endpoints
- IP Release: Reclaiming unused IP addresses
- IP Conflict Detection: Preventing IP address conflicts
- IP Reservation: Reserving IP addresses for specific purposes
IPAM Considerations:
- Address Space Size: Number of IP addresses needed
- Network Segmentation: Subnet and CIDR block design
- Scalability: Considering future growth
IPAM Configuration Example
Cluster Pool IPAM Configuration:
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
ipam: "cluster-pool"
cluster-pool-ipv4-cidr: "10.0.0.0/16"
cluster-pool-ipv4-mask-size: "24"
enable-ipv4: "true"
enable-ipv6: "false"AWS ENI IPAM Configuration:
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
ipam: "eni"
enable-ipv4: "true"
enable-ipv6: "false"
eni-tags: "{\"cluster\": \"eks-cluster\"}"
ec2-api-endpoint: "ec2.us-west-2.amazonaws.com"- Cloud Integration: Integration with cloud provider networking
- IPv4 vs IPv6: Single or dual stack configuration
Kubernetes and Cilium IPAM Integration
Cilium integrates closely with Kubernetes to allocate and manage IP addresses for pods and services.
Kubernetes IPAM Integration Flow:
- Pod Creation: Kubernetes requests pod creation
- CNI Call: kubelet calls Cilium CNI plugin
- IP Allocation Request: Cilium requests IP address from IPAM module
- IP Allocation: IPAM allocates available IP address
- Network Setup: Cilium configures pod's network namespace
- State Storage: IP allocation information stored
- Pod Start: Pod starts with configured network
Cilium Cluster Pool Configuration:
# cilium-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
# Cluster pool IPAM mode
ipam: "cluster-pool"
# IPv4 CIDR range
cluster-pool-ipv4-cidr: "10.0.0.0/8"
cluster-pool-ipv4-mask-size: "24"
# IPv6 CIDR range (optional)
cluster-pool-ipv6-cidr: "fd00::/104"
cluster-pool-ipv6-mask-size: "120"
# Enable dual stack
enable-ipv4: "true"
enable-ipv6: "true"CRD-based IPAM Example:
# cilium-ippool.yaml
apiVersion: "cilium.io/v2alpha1"
kind: CiliumIPPool
metadata:
name: "production-pool"
spec:
ipv4:
cidr: "10.10.0.0/16"
blockSize: 27 # 32 IP address blocks
selector:
matchLabels:
environment: productionAWS ENI IPAM Configuration:
# cilium-aws-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cilium-config
namespace: kube-system
data:
# AWS ENI IPAM mode
ipam: "eni"
# AWS ENI configuration
enable-endpoint-routes: "true"
auto-create-cilium-node-resource: "true"
# ENI tags (optional)
eni-tags: "{\"team\": \"platform\"}"
# Prefix delegation (optional)
enable-prefix-delegation: "true"
eni-prefix-delegation-enabled: "true"IPAM Mode Deep Dive
1. Cluster Scope - Default Mode
Cluster Scope IPAM is Cilium's default IPAM mode, allocating IP addresses centrally across the entire cluster.
Key Features:
- Centralized IP address allocation
- Guarantees IP address uniqueness across the cluster
- Can configure single or multiple IP pools
- Simple and easy to use
How it works:
- Cilium agent allocates IP addresses from the cluster-wide IP pool.
- Allocated IP addresses are stored in Kubernetes CRDs.
- IP address allocation information is shared across all nodes in the cluster.
2. Kubernetes Host Scope
Kubernetes Host Scope IPAM allocates IP address ranges to each node, and nodes allocate IP addresses from their own range.
Key Features:
- Per-node IP address range allocation
- No central coordination needed
- Prevents IP conflicts between nodes
- Improved scalability
How it works:
- Kubernetes allocates a PodCIDR to each node.
- Cilium allocates IP addresses from the node's PodCIDR.
- Each node independently manages its own IP address range.
3. Multi-Pool - Beta
Multi-Pool IPAM provides the ability to define multiple IP pools and allocate specific pools to specific workloads.
Key Features:
- Define and manage multiple IP pools
- Allocate IP pools per namespace, pod, or node
- Fine-grained IP address management
- Support for various network requirements
How it works:
- Define multiple IP pools using CiliumIPPool CRD.
- Use selectors to allocate specific pools to specific workloads.
- Cilium allocates IP addresses from the appropriate pool according to defined rules.
4. Azure IPAM
Azure IPAM integrates with Azure VNET to assign native VNET IP addresses to pods.
Key Features:
- Azure VNET native IP address allocation
- Azure network security group integration
- Azure networking optimization
5. Azure Delegated IPAM
Azure Delegated IPAM is a mode that delegates IP address management to Azure CNI.
Key Features:
- Integration with Azure CNI
- Azure-managed IP address allocation
- Leverages Azure networking features
6. CRD-based IPAM
CRD-based IPAM uses Kubernetes CRDs to manage IP address allocation.
Key Features:
- IP address management through Kubernetes CRDs
- Declarative IP address allocation
- Integration with Kubernetes native workflows
How it works:
- IP address pool information is stored in CiliumNode CRD.
- Cilium agent reads IP address allocation information from CRD.
- IP address allocation state is updated in CRD.
Querying Per-Node PodCIDRs via CiliumNode CR
In Cilium's cluster-pool IPAM mode, pod CIDR allocation information for each node is recorded in the CiliumNode CR. This CR serves as the authoritative source for static route configuration, IPAM debugging, and network troubleshooting.
Note: The Kubernetes Node object's
spec.podCIDRmay differ from the CiliumNode CR'sspec.ipam.podCIDRs. In Cilium environments, always use the CiliumNode CR as the source of truth.
CiliumNode CR Structure (Key Fields)
apiVersion: cilium.io/v2
kind: CiliumNode
metadata:
name: hybrid-node-001
spec:
addresses:
- ip: 10.80.1.10 # Node IP (used as next hop for static routes)
type: InternalIP
ipam:
podCIDRs:
- 10.85.0.0/25 # Pod CIDR allocated to this nodespec.addresses[].ip: The node's actual IP address. Used as the next hop when configuring static routes.spec.ipam.podCIDRs: List of pod CIDRs allocated to this node by the Cilium Operator.
Query Commands
# List all CiliumNodes
kubectl get ciliumnodes
# Query node IP and PodCIDR in table format
kubectl get ciliumnodes -o custom-columns='\
NAME:.metadata.name,\
NODE_IP:.spec.addresses[0].ip,\
POD_CIDR:.spec.ipam.podCIDRs[0]'Example output:
NAME NODE_IP POD_CIDR
hybrid-node-001 10.80.1.10 10.85.0.0/25
hybrid-node-002 10.80.1.11 10.85.0.128/25
hybrid-node-003 10.80.1.12 10.85.1.0/25Scripting Usage
# Extract routing table information using jq
kubectl get ciliumnodes -o json | jq -r \
'.items[] | "\(.metadata.name)\t\(.spec.addresses[0].ip)\t\(.spec.ipam.podCIDRs[0])"'
# Auto-generate static route commands (useful for EKS Hybrid Nodes, etc.)
kubectl get ciliumnodes -o json | jq -r \
'.items[] | "ip route add \(.spec.ipam.podCIDRs[0]) via \(.spec.addresses[0].ip)"'Use Case: This information is used to configure static routes without BGP in EKS Hybrid Nodes environments. For details, see EKS Hybrid Nodes - Network Configuration.
Network Policy Design and Implementation
Cilium network policies provide a powerful mechanism to control communication between microservices at L3-L7 layers. These policies extend the Kubernetes NetworkPolicy API to provide more granular control.
Network Policy Basic Concepts:
- Endpoint Selector: Defines endpoints to which policy applies
- Ingress Rules: Controls incoming traffic
- Egress Rules: Controls outgoing traffic
- L3/L4 Policy: IP address and port-based filtering
- L7 Policy: Application layer protocol-aware filtering
L3/L4 Network Policy Example:
# l3-l4-policy.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "l3-l4-policy"
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
egress:
- toEndpoints:
- matchLabels:
app: database
toPorts:
- ports:
- port: "3306"
protocol: TCPL7 HTTP Policy Example:
# l7-http-policy.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "l7-http-policy"
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: "GET"
path: "/api/v1/users"
- method: "POST"
path: "/api/v1/users"
headers:
- "Content-Type: application/json"L7 Kafka Policy Example:
# l7-kafka-policy.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "l7-kafka-policy"
spec:
endpointSelector:
matchLabels:
app: kafka-broker
ingress:
- fromEndpoints:
- matchLabels:
app: kafka-client
toPorts:
- ports:
- port: "9092"
protocol: TCP
rules:
kafka:
- apiKey: "Produce"
topic: "allowed-topic-1"
- apiKey: "Fetch"
topic: "allowed-topic-1"
- apiKey: "CreateTopics"
topic: "allowed-topic-.*"
apiVersions: ["0", "1"]DNS-based Policy Example:
# dns-policy.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "dns-policy"
spec:
endpointSelector:
matchLabels:
app: client
egress:
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": kube-system
"k8s:k8s-app": kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
- toFQDNs:
- matchName: "api.example.com"
- matchPattern: "*.googleapis.com"
toPorts:
- ports:
- port: "443"
protocol: TCPNetwork Policy Best Practices:
Apply Default Deny Policy:
- Block all traffic not explicitly allowed
- Apply least privilege principle
Gradual Approach:
- Start with observation mode to assess impact
- Gradually apply and strengthen policies
Use Label-based Selectors:
- Use label-based selectors instead of IP addresses
- Provides flexibility in dynamic environments
Policy Layering:
- Combine base policies and specific policies
- Separation of concerns and maintainability
Policy Testing and Validation:
- Test before policy application
- Continuous policy validation and monitoring
Multi-cluster Scenarios
Cilium provides powerful features for networking and security across multiple Kubernetes clusters. This enables cross-cluster service communication, network policy enforcement, and load balancing.
Multi-cluster Connectivity Models:
Global Services:
- Expose services across multiple clusters
- Cross-cluster load balancing
- Automatic failover and high availability
Cluster Mesh:
- Direct connectivity between clusters
- Cross-cluster network policies
- Unified observability
Remote Nodes:
- Display nodes from remote clusters as local
- Transparent communication between clusters
- Single network namespace simulation
Cilium Cluster Mesh Architecture:
+-------------------+ +-------------------+
| Cluster A | | Cluster B |
| | | |
| +---------------+ | | +---------------+ |
| | Service A | | | | Service B | |
| | (Global) | | | | (Global) | |
| +-------+-------+ | | +-------+-------+ |
| | | | | |
| +---v---+ | | +---v---+ |
| | eBPF | | | | eBPF | |
| +---+---+ | | +---+---+ |
| | | | | |
| +-------v-------+ | | +-------v-------+ |
| | Cilium | |<------>| | Cilium | |
| | Clustermesh | | | | Clustermesh | |
| +---------------+ | | +---------------+ |
| | | |
+-------------------+ +-------------------+Cilium Cluster Mesh Setup:
# Enable Cluster Mesh on Cluster A
cilium clustermesh enable --context cluster-a
# Enable Cluster Mesh on Cluster B
cilium clustermesh enable --context cluster-b
# Connect clusters
cilium clustermesh connect --context cluster-a --destination-context cluster-b
# Check status
cilium clustermesh status --context cluster-aGlobal Service Definition:
# global-service.yaml
apiVersion: v1
kind: Service
metadata:
name: global-service
annotations:
io.cilium/global-service: "true"
spec:
selector:
app: global-app
ports:
- port: 80
targetPort: 8080
type: ClusterIPCross-cluster Network Policy:
# cross-cluster-policy.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "cross-cluster-policy"
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
io.kubernetes.pod.namespace: frontend-ns
io.cilium.k8s.policy.cluster: cluster-a
toPorts:
- ports:
- port: "8080"
protocol: TCPQuiz
To test what you learned in this chapter, try the Topic Quiz.