- Default behavior: pod egress is SNAT’d to the node IP.
- Enabling Cilium egress gateway and applying a CiliumEgressGatewayPolicy.
- Capturing traffic to confirm egress from a single gateway node and inspecting VXLAN encapsulation.
Prerequisites: Cilium must be installed with kube-proxy replacement enabled (kubeProxyReplacement), eBPF masquerade (bpf.masquerade) turned on, and a Cilium release that supports the egress gateway feature. Confirm your cluster networking and node labeling permissions before proceeding.
- Flow: pod IP → node → router → internet. The node performs SNAT, so the router and external services see the node IP as the source address, not the pod IP.
- If pods run on multiple worker nodes, external services observe different source IPs depending on the node used.

- Cilium egress gateway centralizes outbound traffic from selected pods through one or more chosen node(s). Those egress node(s) perform SNAT so the external source IP is the chosen egress IP.
- Internally, Cilium forwards traffic from source nodes to the egress gateway node. In overlay networks (common with Cilium), this forwarding is encapsulated (VXLAN or similar). The egress node decapsulates, performs SNAT, and sends traffic to the internet.
- kube-proxy replacement (ensure kubeProxyReplacement is enabled in values):
- eBPF masquerade (native BPF SNAT):
- Enable egress gateway support (depends on Cilium version and values layout). After editing Helm values, upgrade and restart Cilium:
- Label the node(s) you want to act as egress gateway(s) and reference that label in the policy nodeSelector.
- Note: label values in YAML matchLabels must be strings. Quote boolean-like values (e.g., “true”).
- This example selects pods with label app=app1, matches all destinations (0.0.0.0/0), and configures the node labeled egress: “true” to use egress IP 192.168.44.128.
When authoring CiliumEgressGatewayPolicy YAML, always quote label values (for example: egress: “true”) so they are treated as strings. Also ensure your Cilium version supports the egress gateway feature and that kubeProxyReplacement and bpf.masquerade are enabled.
- Check the BPF egress table from a Cilium agent pod to confirm source pods are mapped to the configured egress IP:
- Start a capture on your router. To write a pcap file and capture ICMP on all interfaces:
- From a pod on worker1 (not the egress gateway), ping 8.8.8.8 and stop the capture after a few packets:
- Router should now see the configured egress IP (192.168.44.128) as the source for traffic from pods matched by the policy instead of the pod’s local node IP.
- When the source pod is on a different node than the configured egress node, Cilium forwards the packet across nodes using overlay encapsulation (often VXLAN). The outer header shows node→egress-node (physical IPs) and the inner payload contains the original pod→internet packet. The egress node decapsulates, SNATs to the egress IP, and sends the packet to the internet. Replies are received by the egress node and forwarded/decapsulated back to the source node as needed.

- Default: each node SNATs pod outbound traffic to its node IP; external servers will see multiple source IPs if pods are distributed across nodes.
- With Cilium egress gateway: you can centralize egress IPs by selecting one or more egress nodes. Matched pod traffic is forwarded (often via VXLAN), SNAT’d at the egress node, and sent to the internet — useful for predictable outbound IPs, firewalling, and auditing.
- Ensure:
- kubeProxyReplacement is enabled,
- eBPF masquerade (bpf.masquerade) is enabled,
- quoting label values (e.g., egress: “true”) in YAML to avoid boolean parsing issues.
- For production: consider multiple egress nodes and failover strategies to avoid single points of egress.
- A granular policy example selecting a single destination IP (e.g., “8.8.8.8/32”),
- Steps to configure multiple egress nodes with failover,
- Commands to inspect Cilium policy state and logs for troubleshooting.