如何将 kube-proxy 配置为仅从本地节点提供服务

How to configure kube-proxy to serve from local node only

我只需要在当前节点上从 pods 运行 配置 kube-proxy 到服务器,并避免连接在不同节点之间反弹。

参考documentation,使用标志:

--bind-address 127.0.0.1

对于这个flag,你需要添加kube-proxy的运行脚本。 对于 systemd,它存储在这里:

/etc/systemd/system/kube-proxy.service

重启 kube-proxy 服务:

systemctl restart kube-proxy

在文档中找到解决方案:

从 Kubernetes 1.5 开始,发送到 Type=NodePort 的服务的数据包默认是源 NAT。您可以通过创建 NodePort 服务来测试它:

$ kubectl expose deployment source-ip-app --name=nodeport --port=80 --target-port=8080 --type=NodePort
service/nodeport exposed

$ NODEPORT=$(kubectl get -o jsonpath="{.spec.ports[0].nodePort}" services nodeport)
$ NODES=$(kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="ExternalIP")].address }')

如果您 运行 正在使用云提供商,您可能需要为上面报告的 nodes:nodeport 打开防火墙规则。现在您可以尝试通过上面分配的节点端口从集群外部访问服务。

$ for node in $NODES; do curl -s $node:$NODEPORT | grep -i client_address; done
client_address=10.180.1.1
client_address=10.240.0.5
client_address=10.240.0.3

请注意,这些不是正确的客户端 IP,它们是集群内部 IP。这是发生了什么: 客户端将数据包发送到 node2:nodePort node2用自己的IP地址替换数据包中的源IP地址(SNAT) node2 将数据包上的目标 IP 替换为 pod IP 数据包被路由到节点 1,然后到端点 pod 的回复被路由回 node2 pod 的回复被发送回客户端

视觉上:

          client
             \ ^
              \ \
               v \
   node 1 <--- node 2
    | ^   SNAT
    | |   --->
    v |
 endpoint

为避免这种情况,Kubernetes 具有保留客户端源 IP 的功能(请在此处查看功能可用性)。将 service.spec.externalTrafficPolicy 设置为值 Local 只会将请求代理到本地端点,从不将流量转发到其他节点,从而保留原始源 IP 地址。如果没有本地端点,发送到该节点的数据包将被丢弃,因此您可以在任何数据包处理规则中依赖正确的 source-ip,您可能会应用一个数据包,使其通过到端点。 设置service.spec.externalTrafficPolicy字段如下:

$ kubectl patch svc nodeport -p '{"spec":{"externalTrafficPolicy":"Local"}}'
service/nodeport patched

现在,重新运行测试:

$ for node in $NODES; do curl --connect-timeout 1 -s $node:$NODEPORT | grep -i client_address; done
client_address=104.132.1.79

请注意,您只从端点 pod 运行ning 所在的一个节点收到一个具有正确客户端 IP 的回复。 这是发生了什么: 客户端将数据包发送到 node2:nodePort,它没有任何端点 数据包被丢弃 客户端将数据包发送到 node1:nodePort,它确实有端点 node1 使用正确的源 IP

将数据包路由到端点

视觉上:

        client
       ^ /   \
      / /     \
     / v       X
   node 1     node 2
    ^ |
    | |
    | v
 endpoint