默认情况
发送到Type=NodePort的Service的数据包会经过源NAT处理,如下图所示:
- 客户端发送数据包到
node2:nodeport - node2使用它自己的IP地址替换数据包的源IP地址(SNAT)
- node2将数据包上的目标IP替换为Pod IP
- 数据包被路由到
node1,然后到Endpoint - Pod 的回复被路由回
node2 - Pod 的回复被发送回给客户端
这个获取到的client_address就是集群内node的IP,而不是真正客户端的IP。Kubernetes有一个特性可以保留客户端源IP。可以将 service.spec.externalTrafficPolicy 设置为 Local,这样kube-proxy只会将代理请求代理到本地端点,而不会将流量转发到其他节点,可以保留客户端的源IP。
kubectl patch svc xxx -p '{"spec":{"externalTrafficPolicy":"Local"}}'
- 客户端将数据包发送到没有任何端点的
node2:nodePort - 数据包被丢弃
- 客户端发送数据包到必有端点的
node1:nodePort - node1 使用正确的源 IP 地址将数据包路由到端点
在实际使用此方法时需要注意的是必须保证pod一定分配到某个节点,比如:
Node1,否则会出现无法正常请求的问题。