我创建了一个Nginx入口和服务,代码如下:
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安装:helm install ingress-nginx ingress-nginx/ingress-nginx
.
我还为ELB启用了代理协议。但在nginx日志中,我看不到X-Forwarded-For和X-Real-IP头的真实的客户端IP。这是我在应用日志中看到的最后一个头:
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]
我如何获得真实的的客户端IP而不是ingress Pod IP?是否有方法知道ELB正在向ingress发送哪些报头?
4条答案
按热度按时间qncylg1j1#
一个解决方案是使用
externalTrafficPolicy
:Local
(参见文档)。事实上,根据
kubernetes documentation
:由于此功能的实现,在目标容器中看到的源IP不是客户端的原始源IP。.... service.spec.externalTrafficPolicy -表示此Service是否希望将外部流量路由到节点本地或群集范围的端点。有两个可用选项:群集(默认)和本地。群集会隐藏客户端源IP,并可能导致到另一个节点的第二跳,但应具有良好的总体负载分布。本地会保留客户端源IP,并避免LoadBalancer和NodePort类型服务的第二跳,但存在潜在的不平衡流量分布风险。
如果你想遵循这个路线,更新你的
nginx ingress controller
Service
并添加externalTrafficPolicy
字段:一种可能的替代方法是使用Proxy protocol(参见文档)。
6qftjkof2#
应在ConfigMap中为入口控制器和ELB启用代理协议。
L4使用代理协议
对于L7使用use-forwarded-header
https://kubernetes.github.io/ingress-nginx/user-guide/miscellaneous/#proxy-protocol
ngynwnxp3#
只是在@strongjz上扩展答案。
默认情况下,将在AWS中为
LoadBalancer
类型的服务创建的负载均衡器将是经典负载均衡器,在第4层上运行,即在TCP协议级别代理。对于这种情况,保留真实的IP的最佳方法是使用代理协议,因为它能够在TCP级别执行此操作。
为此,您应该在负载均衡器和Nginx-ingress上启用代理协议。
对于nginx-ingress的Helm安装,这些值应该可以做到:
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
annotation将告诉aws-load-balancer-controller
创建启用代理协议的LoadBalancer。我不确定如果将其添加到预先存在的Ingress-nginx会发生什么,但它应该也可以工作。use-proxy-protocol
和real-ip-header
是传递给Nginx的选项,也可以在那里启用代理协议。参考文献:
deyfvvtc4#
如果您使用helm安装ingress-nginx,请运行以下命令使ingress-nginx转发客户端IP
如果它起作用了,就投赞成票吧,不是为了帮助我,而是为了帮助其他面临这个问题的求职者:)