kubernetes - 如何将 kube-proxy 配置为仅从本地节点提供服务
问题描述
我只需要从当前节点上运行的 Pod 将 kube-proxy 配置为服务器,并避免连接在不同节点之间反弹。
解决方案
在文档中找到了解决方案:
从 Kubernetes 1.5 开始,发送到 Type=NodePort 的服务的数据包默认是源 NAT'd。您可以通过创建 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 }')
如果您在云提供商上运行,您可能需要为上面报告的节点打开防火墙规则: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地址(SNAT)替换为自己的IP地址 node2将数据包上的目标IP替换为pod IP数据包被路由到节点1,然后到端点 pod 的回复被路由回 node2 pod 的回复被发送回客户端
视觉上:
client
\ ^
\ \
v \
node 1 <--- node 2
| ^ SNAT
| | --->
v |
endpoint
为避免这种情况,Kubernetes 具有保留客户端源 IP 的功能(请在此处查看功能可用性)。将 service.spec.externalTrafficPolicy 设置为值 Local 只会将请求代理到本地端点,从不将流量转发到其他节点,从而保留原始源 IP 地址。如果没有本地端点,则发送到节点的数据包将被丢弃,因此您可以在任何数据包处理规则中依赖正确的源 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 的一个节点收到了一个具有正确客户端 IP 的回复。这会发生:客户端将数据包发送到 node2:nodePort,它没有任何端点 数据包被丢弃 客户端将数据包发送到 node1:nodePort,它有端点 node1 将数据包路由到具有正确源 IP 的端点
视觉上:
client
^ / \
/ / \
/ v X
node 1 node 2
^ |
| |
| v
endpoint
推荐阅读
- json - 在 Flutter 中使用条件将数据解析为两个单独的列表
- c - 在接收()之前发送()
- android - 在主要活动中为 editText id 获取“未解决的参考”错误
- python - 选择特定值时数据框未正确过滤(熊猫)
- python - 从 CSV 文件中删除相似但不相等的行的最佳方法是什么?
- javascript - 如何将元组并集转换为对象类型
- android - 将原始音频数据文件从 Android 应用程序发送到 Node.js 服务器
- swift - 在页面左上角快速打印视图
- javascript - 从具有序列输出的每个数组数组中获取数据
- php - 我的 PHP curl Post 请求没有按预期工作