Demonstrates Cilium tunnel versus native routing modes, inspects packet flows, and shows required physical network changes to enable native pod subnet routing with static routes or BGP.
This lesson demonstrates Cilium’s two routing modes — tunnel (encapsulation) and native routing — by inspecting packet flows for each mode and showing what changes are required on your physical network to enable native routing.We use a small 3-node cluster (1 control-plane, 2 workers) where each node sits on a different physical network and all networks connect via a central router. The pod CIDRs are allocated by Cilium/Cluster IPAM from 10.0.0.0/8 and are split per node (for example, 10.0.1.0/24 for worker1 and 10.0.2.0/24 for worker2).We will observe traffic from a pod on worker1 to a pod on worker2 using four terminals: control-plane, worker1, worker2, and router.
By default Cilium uses tunnel mode (VXLAN) to encapsulate pod traffic between nodes, so no changes are required on the physical network for basic pod-to-pod connectivity.
kubectl get node# NAME STATUS ROLES AGE VERSION# control-plane Ready control-plane 26d v1.32.3# worker1 Ready <none> 26d v1.32.3# worker2 Ready <none> 26d v1.32.3
Sample app pods (spread across worker1 and worker2):
Copy
kubectl get pod -o wide# NAME READY STATUS RESTARTS AGE IP NODE# app1-75c78488c4-5kfpf 1/1 Running 0 58s 10.0.2.80 worker2# app1-75c78488c4-62mkr 1/1 Running 0 58s 10.0.1.71 worker1# ...
From a pod on worker1, verify connectivity to a pod on worker2:
3) Switch to native routing (disable encapsulation)
To enable native routing, update your Cilium values.yaml to set routingMode to “native”, disable the tunnel (tunnelPort: 0), and configure ipv4NativeRoutingCIDR so Cilium knows which pod CIDRs should be advertised/routed natively.Example values to change:
Copy
# Enable native routingroutingMode: "native"# Disable VXLAN/Geneve tunnel (0 disables)tunnelPort: 0tunnelSourcePortRange: 0-0# CIDR(s) to route natively on the wireipv4NativeRoutingCIDR: "10.0.0.0/8"
Apply the change and restart the operator and agents:
4) Native routing: expected connectivity failure until physical routes exist
Once native routing is enabled, pod traffic is sent on the physical network using pod source/destination IPs. If the router does not have routes for the pod CIDRs, packets will be dropped.Example: Pods after native mode is enabled:
Copy
kubectl get pod -o wide# NAME READY STATUS RESTARTS AGE IP NODE# app1-75c78488c4-lq842 1/1 Running 0 59s 10.0.1.39 worker1# app1-75c78488c4-tdpqj 1/1 Running 0 59s 10.0.2.137 worker2
Attempting to ping from worker1 to worker2 likely fails initially:
Copy
kubectl exec -it app1-75c78488c4-s79d2 -- bash# inside pod:ping -c 3 10.0.2.137# No responses — expected until the router knows how to reach the pod CIDRs
When using native routing, your physical network must route the pod CIDR(s). Provide routes via static entries, a dynamic routing protocol (for example, BGP), or another mechanism so other network segments can reach pod subnets.
Each node receives a dedicated IPAM range from Cilium. Use the agent debug info to find per-node IPAM allocations.Find the cilium agent pods and node IPs:
Add static routes on the router that map the pod CIDRs to each node’s physical IP:Check current routes:
Copy
ip route# e.g. shows existing connected networks and default route
Add routes pointing pod CIDRs to node IPs:
Copy
sudo ip route add 10.0.2.0/24 via 192.168.44.128sudo ip route add 10.0.1.0/24 via 192.168.211.128
Verify routes:
Copy
ip route# now shows:# 10.0.2.0/24 via 192.168.44.128 dev ens38# 10.0.1.0/24 via 192.168.211.128 dev ens39
The router will now forward packets destined for 10.0.2.0/24 to worker2 and 10.0.1.0/24 to worker1.Note: In production, dynamic routing (BGP) is preferable to manual static routes for maintainability and scaling.
Tunnel mode is convenient for quick deployments or when you cannot change the underlay network. It hides pod IPs from the physical network but adds encapsulation overhead.
Native routing removes encapsulation overhead and can reduce latency but requires that your physical network be aware of the pod CIDRs. This can be done via static routes for small deployments or dynamic routing (BGP) for production-scale environments.
For production clusters with many nodes and dynamic topology, prefer a routing protocol (BGP) over manual static routes.