kubernetes - 如何在没有云提供商或 LB 的情况下获取 pod 内的客户端 ip

标签 kubernetes kubernetes-ingress flannel

我需要在 Kubernetes 中获取客户端 IP,但我只能获取 Flannel 内部 IP 10.244.X.1(在 nginx 中通过 $remote_addr $http_x_forwarded_for 始终是 -)。

网络拓扑是:
客户端浏览器 -> k8s集群节点ip -> k8s服务(A) -> pod(需要客户端ip) -> 其他服务

我已经在 A 中尝试了 externalTrafficPolicy,但是没有用。它只适用于云提供商,还是在 LB 之后? [1]
我也试过 ingress-nginx [2] , 得到相同的结果。

我的环境:

 Kernel Version:             3.10.0-1062.4.1.el7.x86_64
 OS Image:                   CentOS Linux 7 (Core)
 Operating System:           linux
 Architecture:               amd64
 Container Runtime Version:  docker://18.6.2
 Kubelet Version:            v1.16.2
 Kube-Proxy Version:         v1.16.2
 Network Add-on:             Flannel

我看过一些类似的问题[3] [4] [5] , 看起来答案暗示云提供商或 LB。

最佳答案

Kubernetes 服务以三种代理模式之一工作:用户空间、iptables 和 IPVS。我不熟悉 IPVS,但在用户空间和 iptables 模式下,客户端 IP 将针对 NodePort 和负载平衡器服务进行更改 [ docs ].

由于这种代理行为,客户端 IP 必然会发生变化,并且只有在客户端和服务器使用“更高层”协议(protocol)并且存在可以捕获原始客户端的“更高层”代理时才能保留该数据IP 并将其注入(inject)到请求中,然后再转发。如果客户端和服务器使用 HTTP,那么 IaaS L7/HTTP(S) 负载均衡器或 nginx 可以为您注入(inject)标准 header ,但是如果您使用的是 nginx-ingress,那么问题就出在 NodePort 后面或 LoadBalancer 服务,因此当它到达实际的 nginx 进程时,客户端 IP 已被更改。您需要让 nginx 在集群外运行才能完成这项工作。

如果您在公共(public)云上运行它,我认为大多数云的 L7 LB 解决方案会立即为这些 X-Forwarded-ForForwarded header 注入(inject)你。或者,考虑设计您的服务器,使其不需要客户端 IP——如果客户端 IP 用于对客户端进行身份验证或授权请求,则可以使用其他更多的云原生模式。

关于kubernetes - 如何在没有云提供商或 LB 的情况下获取 pod 内的客户端 ip,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59483886/

相关文章:

elasticsearch - 如何排除journalbeat中的日志/事件

java - 如何使用 Spark 3.0.0 读写 S3?

docker - 如何与 Kubernetes 集群外部的数据库通信

spring-boot - 尝试访问作为 HTTPS Ingress 部署在 GKE 中的应用程序时出现密码不匹配错误

amazon-web-services - Kubernetes DNS 大多数时候无法解析,但有时可以解决。我能做什么来解决这个问题?

具有单个 Pod 的 Kubernetes 作业与具有重启策略 OnFailure 的单个 Pod

nginx - 可以从Nginx入口 Controller 中的https重定向中排除一页

ssl - Google 管理的 SSL 证书停留在 "Provisioning"上,域的 FAILED_NOT_VISIBLE

centos - Kube-api 服务器没有出现在 Baremetal 上

kubernetes - 网桥 `docker0`在k8s with flannel中扮演什么角色