首页 > 解决方案 > Nginx 入口将 X-Real-IP 的私有 IP 发送到服务

问题描述

我使用以下代码创建了一个 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 入口: 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 而不是入口 pod IP?还有一种方法可以知道 ELB 将哪些标头发送到入口?

标签: kuberneteskubernetes-ingressamazon-eksamazon-elbingress-nginx

解决方案


一种解决方案是使用externalTrafficPolicy:(Local请参阅文档)。

事实上,根据kubernetes documentation

由于此功能的实现,目标容器中看到的源 IP 不是客户端的原始源 IP。... service.spec.externalTrafficPolicy - 表示此服务是否希望将外部流量路由到节点本地或集群范围的端点。有两个可用选项:集群(默认)和本地。集群掩盖了客户端源 IP,可能会导致第二次跳转到另一个节点,但应该具有良好的整体负载分布。Local 保留客户端源 IP 并避免 LoadBalancer 和 NodePort 类型服务的第二跳,但存在潜在的流量传播不平衡的风险。

如果您想遵循此路线,请更新您的nginx ingress controller Service并添加externalTrafficPolicy字段:

apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-controller
spec:
  ...
  externalTrafficPolicy: Local

一种可能的替代方法是使用代理协议(请参阅文档


推荐阅读