Join us on Thursday, May 23rd with Buoyant & Ambassador as we dive into the battle of the Service Mesh vs the API Gateway. Register Now.

Back to blog
KUBERNETES

externalTrafficPolicy=local on Kubernetes

August 3, 2020 | 2 min read

externalTrafficPolicy=local
is an annotation on the Kubernetes
service
resource that can be set to preserve the client source IP. When this value is set, the actual IP address of a client (e.g., a browser or mobile application) is propagated to the Kubernetes
service
instead of the IP address of the node.

So how exactly does this work, and why do we need it?

Pods and Nodes: Recap

In Kubernetes, containers are deployed in individual pods, which are then deployed on one or more nodes. A node is a physical or virtual machine, and represents the actual, concrete compute entity of a Kubernetes cluster. Kubernetes schedules pods to run on nodes based on a variety of criteria such as resource availability. Multiple pods are typically run on a single node.

Routing traffic to a Kubernetes cluster

Traffic entering a Kubernetes cluster arrives at a node. The node then routes traffic to the target pod via

kube-proxy
. If the pod is not on the same node as the incoming traffic, the node routes the traffic to the node where the pod resides.

ExternalTrafficPolicy=local

This leads us to

ExternalTrafficPolicy
. When a node routes traffic to a pod on another node, the source IP address of that traffic becomes that of the node, and not the client.

By setting

ExternalTrafficPolicy=local
, nodes only route traffic to pods that are on the same node, which then preserves client IP. It’s important to recognize that
ExternalTrafficPolicy
is not a way to preserve source IP; it’s a change in networking policy that happens to preserve source IP.

Preserving Source IP with Kubernetes ingress

How else can you preserve source IP with Kubernetes? If your external load balancer is a Layer 7 load balancer, the

X-Forwarded-For
header will also propagate client IP. If you are using a Layer 4 load balancer, you can use the PROXY protocol.

Edge Stack API Gateway

To experiment with this in your own Kubernetes environment, you can quickly bootstrap a Kubernetes ingress controller