I have created a Nginx Ingress and Service with the following code:
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
type: ClusterIP
selector:
name: my-app
ports:
- port: 8000
targetPort: 8000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myingress
annotations:
kubernetes.io/ingress.class: nginx
labels:
name: myingress
spec:
rules:
- host: mydomain.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-service
port:
number: 8000
Nginx ingress installed with:
helm install ingress-nginx ingress-nginx/ingress-nginx
.
I have also enabled proxy protocols for ELB. But in nginx logs I don’t see the real client ip for X-Forwarded-For and X-Real-IP headers. This is the final headers I see in my app logs:
X-Forwarded-For:[192.168.21.145] X-Forwarded-Port:[80] X-Forwarded-Proto:[http] X-Forwarded-Scheme:[http] X-Real-Ip:[192.168.21.145] X-Request-Id:[1bc14871ebc2bfbd9b2b6f31] X-Scheme:[http]
How do I get the real client ip instead of the ingress pod IP? Also is there a way to know which headers the ELB is sending to the ingress?
4
Answers
One solution is to use
externalTrafficPolicy
:Local
(see documentation).In fact, according to the
kubernetes documentation
:If you want to follow this route, update your
nginx ingress controller
Service
and add theexternalTrafficPolicy
field:A possible alternative could be to use Proxy protocol (see documentation)
The proxy protocol should be enabled in the ConfigMap for the ingress-controller as well as the ELB.
L4 uses proxy-protocol
For L7 use use-forwarded-headers
https://kubernetes.github.io/ingress-nginx/user-guide/miscellaneous/#proxy-protocol
Just expanding on @strongjz answer.
By default, the Load balancer that will be created in AWS for a Service of type
LoadBalancer
will be a Classic Load Balancer, operating on Layer 4, i.e., proxying in the TCP protocol level.For this scenario, the best way to preserve the real ip is to use the Proxy Protocol, because it is capable of doing this at the TCP level.
To do this, you should enable the Proxy Protocol both on the Load Balancer and on Nginx-ingress.
Those values should do it for a Helm installation of nginx-ingress:
The
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
annotation will tell theaws-load-balancer-controller
to create your LoadBalancer with Proxy Protocol enabled. I’m not sure what happens if you add it to a pre-existing Ingress-nginx, but it should work too.The
use-proxy-protocol
andreal-ip-header
are options passed to Nginx, to also enable Proxy Protocol there.Reference:
If you used helm to install ingress-nginx then run following command to make ingress-nginx forward client ip
If it works do upvote it, not to help me but to help other seekers who face this problems 🙂