docker - Kubernetes Nodeport 保留源 IP

标签 docker networking kubernetes rancher calico

我有一个小型 Kubernetes on prem 集群 (Rancher 2.3.6),由三个节点组成。 集群内的部署由外部应用程序动态配置,并且始终将其副本计数设置为 1,因为这些是有状态应用程序,不需要高可用性。

应用程序通过 NodePort 服务向互联网公开,其中具有随机端口,并且外部流量策略设置为集群。因此,如果用户请求三个节点之一,k8s 代理将通过应用程序 pod 将请求路由和 s-NAT 到正确的节点。

到目前为止,一切正常。

当我们添加依赖请求源 IP 的应用程序时,问题就开始了。由于 s-NAT 将请求 IP 替换为内部 IP,因此该应用程序无法正常工作。

我知道,将服务ExternalTrafficPolicy设置为本地将禁用s-natting。但这也会破坏架构,因为并非每个 Pod 都有一个正在运行的应用程序实例。

有没有办法保留原始客户端IP并仍然使用内部路由,这样我就不必担心请求将到达哪个节点?

最佳答案

这取决于流量如何进入您的集群。但让我们稍微分解一下:

一般来说,处理源IP保留的策略有两种:

  • SNAT(数据包 IP)
  • 代理/ header (在附加 header 中传递原始 IP)

1) SNAT

默认情况下,发往NodePortLoadBalancer的数据包均经过SourceNAT(发往接收请求的节点的IP),而数据包则发送至ClusterIP> 进行 SourceNAT。

正如您已经提到的,有一种方法可以通过设置 service.spec.externalTrafficPolicy: Local 来关闭 NodePort 和 LoadBalancer 服务的 SNAT它保留了原始源 IP 地址,但会产生不良影响:kube-proxy 仅将代理请求代理到本地端点,而不将流量转发到其他节点。

2) header +代理IP保存

a) Nginx Ingress Controller 和 L7 LoadBalancer

  • 当使用发送 X-Forwarded-For 的 L7 LoadBalancers 时 header ,如果我们在 proxy-real-ip-cidr 中设置了 LB CIDR/地址,Nginx 默认情况下会评估包含源 IP 的 header 。
  • 您可能需要设置 use-forwarded-headers 明确让nginx转发头信息
  • 此外,您可能需要启用 enable-real-ip 所以realip_module替换了X-Forwarded-For中设置的真实ip由 proxy-real-ip-cidr 中指定的可信 LB 提供的 header .

b) 代理协议(protocol)和 L4 LoadBalancer

  • 启用 use-proxy-protocol: "true" 评估 header ,并且在转发 TCP 实际连接之前将发送连接详细信息。 LB 必须支持这一点。

关于docker - Kubernetes Nodeport 保留源 IP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61210920/

相关文章:

azure - 使用具有所有者角色的帐户创建 LoadBalancer 服务时 AKS 授权失败

docker - 使用docker-compose启动容器时,如何以编程方式获取其ip?

node.js - docker找不到模块 'Sequelize'

linux - 我们是否应该一开始就从 Docker Hub 安装一个 docker 镜像?

python - docker compose Django nginx

ios - 优化 4 人对等网络拓扑

file - SSIS 脚本任务看不到网络驱动器上的文件

kubernetes - 如何使用 hostPath 将单个文件映射到 kubernetes pod?

networking - UNC 上的 PowerShell 操作挂起太久

bash - 在具有 root 访问权限的 kubernetes pod 上执行命令