Packets sent to LoadBalancer Services are source NAT'd (source IP is replaced by the IP of the node) by default because all schedulable nodes in the "Ready" state are eligible for load-balanced traffic. When your ingress controller routes a client's request to a container in your AKS cluster, the original source IP of that request is unavailable to the target container. You can preserve source IP on requests to your containers in AKS by enabling client source IP preservation. The client source IP is stored in the request header under X-Forwarded-For. One caveat is when using an ingress controller with client source IP preservation enabled, TLS pass-through to the destination container will not work. The following details explain how to setup client source IP preservation.
sudo az aks install-cli
az aks get-credentials --resource-group ftademo --name asurity-demo
We will create a small nginx webserver that echoes back the source IP of requests it receives through an HTTP header.
kubectl create deployment source-ip-app --image=k8s.gcr.io/echoserver:1.4
kubectl expose deployment source-ip-app --name=loadbalancer --port=80 --target-port=8080 --type=LoadBalancer
kubectl get svc loadbalancer
The Client IP is of one of the nodes.
kubectl patch svc loadbalancer -p '{"spec":{"externalTrafficPolicy":"Local"}}'
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2021-12-08T09:10:05Z"
finalizers:
- service.kubernetes.io/load-balancer-cleanup
labels:
app: source-ip-app
name: loadbalancer
namespace: sourceip
resourceVersion: "11870944"
uid: f8e39f83-f205-4b0c-b74d-a3ab3dbc9659
spec:
clusterIP: 10.0.3.106
clusterIPs:
- 10.0.3.106
externalTrafficPolicy: Local
healthCheckNodePort: 30107
ports:
- nodePort: 30486
port: 80
protocol: TCP
targetPort: 8080
selector:
app: source-ip-app
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 20.72.104.239
Setting the service.spec.externalTrafficPolicy field to "Local" forces nodes without Service endpoints to remove themselves from the list of nodes eligible for loadbalanced traffic by deliberately failing health checks.
kubectl get pod -o wide -l run=source-ip-app
kubectl get pod -n sourceip -o wide -l app=source-ip-app
kubectl debug node/aks-nodepool1-33498924-vmss00000c -it --image=mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11source-ip-ap
Curl to fetch the /healthz endpoint.
curl localhost:30107/healthzThere are Endpoints on this node.
kubectl debug node/aks-nodepool1-33498924-vmss000001 -it --image=mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11source-ip-ap
Curl to fetch the /healthz endpoint.
curl localhost:30107/healthz
There are no Endpoints on this node.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.