Skip to content

iptables SNAT optimization

iptables SNAT optimization is a network configuration adjustment performed in Kubernetes clusters (specifically those using Flannel) to ensure transparent communication between container Pods across different hosts.

By default, source network address translation (SNAT) rules may cause traffic from one Pod to another to appear as if it originated from the host machine's IP address. This optimization modifies the POSTROUTING chain rules to exclude internal cluster traffic from NAT, preserving the original source Pod IP addresses.^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

Problem Statement

Without optimization, when a container sends traffic to another container on a different host, the kernel's IP tables may perform MASQUERADE (SNAT) on the packets.^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

Consequently, the destination container sees the source IP as the host node's IP rather than the originating Pod's IP.^[400-devops-06-kubernetes-k8s-paas-03k8s.md] This behavior is problematic for logging and transparency, as it obscures the actual client identity within the cluster.^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

Optimization Solution

To achieve transparent access, administrators must modify the iptables rules in the nat table's POSTROUTING chain.^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

The optimization involves two steps: removing the default broad rule and inserting a specific rule with destination exclusions.

1. Delete the Default Rule

The default Flannel installation typically creates a rule that matches the source subnet and performs MASQUERADE for traffic leaving non-docker interfaces.^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

This rule must be deleted (using -D).

# Example for deleting the default rule
# Adjust subnet (172.7.21.0/24) to match your specific host configuration
iptables -t nat -D POSTROUTING -s 172.7.21.0/24 ! -o docker0 -j MASQUERADE
^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

2. Insert the Optimized Rule

A new rule is inserted at the top of the chain (using -I) that adds a destination exclusion.^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

The logic dictates: "If the source is from the local Pod subnet AND the destination is NOT within the overall cluster network AND the output interface is not docker0, then perform MASQUERADE."^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

# Example command structure
# -s: Source subnet (local host)
# -d: Destination subnet (cluster network to exclude)
# -o: Output interface
iptables -t nat -I POSTROUTING -s 172.7.21.0/24 ! -d 172.7.0.0/16 ! -o docker0 -j MASQUERADE
^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

Persistence

After verifying the rules with iptables-save, the configuration should be saved to the system configuration file (e.g., /etc/sysconfig/iptables) to persist across reboots.^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

Verification

After applying the optimization, cross-host communication can be verified. For example, executing a curl request from a Pod on one host to a Pod on another host should result in the target Pod's logs displaying the source Pod's IP (e.g., 172.7.21.2) instead of the host's IP.^[400-devops-06-kubernetes-k8s-paas-03k8s.md]

Sources

^[400-devops-06-kubernetes-k8s-paas-03k8s.md]