【发布时间】:2020-02-07 18:34:52
【问题描述】:
我试图深入了解从公开的负载平衡器的第 2 层 VIP 转发到服务的集群 IP 的工作原理。我已经阅读了MetalLB does it 的高级概述,并尝试通过设置 keepalived/ucarp VIP 和 iptables 规则手动复制它。但是我必须遗漏一些东西,因为它不起作用;-]
我采取的步骤:
创建了一个包含
kubeadm的集群,该集群由一个主节点 + 3 个在单台计算机上的 libvirt/KVM 虚拟机上运行 k8s-1.17.2 + calico-3.12 的节点组成。所有虚拟机都在192.168.122.0/24虚拟网络中。创建了一个简单的 2 pod 部署并将其公开为
NodePort服务,externalTrafficPolicy设置为cluster:$ kubectl get svc dump-request NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dump-request NodePort 10.100.234.120 <none> 80:32292/TCP 65s
我已经验证我可以从主机上的每个节点的 IP 上的 32292 端口访问它。在所有 3 个节点上使用
ucarp创建了一个 VIP:ucarp -i ens3 -s 192.168.122.21 -k 21 -a 192.168.122.71 -v 71 -x 71 -p dump -z -n -u /usr/local/sbin/vip-up.sh -d /usr/local/sbin/vip-down.sh(来自 knode1 的示例)
我已经验证我可以 ping192.168.122.71VIP。我什至可以通过 ssh 连接到当前持有 VIP 的虚拟机。
现在,如果 kube-proxy 处于iptables模式,我还可以通过http://192.168.122.71:32292的 VIP 访问其节点端口上的服务。然而,令我惊讶的是,在ipvs模式下,这总是导致连接超时。在每个节点上添加了一个 iptables 规则,用于将传入
192.168.122.71的数据包转发到服务的集群 IP10.100.234.120:iptables -t nat -A PREROUTING -d 192.168.122.71 -j DNAT --to-destination 10.100.234.120
(后来我也尝试将规则缩小到相关端口,但并没有以任何方式改变结果:iptables -t nat -A PREROUTING -d 192.168.122.71 -p tcp --dport 80 -j DNAT --to-destination 10.100.234.120:80)
结果:
在iptables 模式下,对http://192.168.122.71:80/ 的所有请求都导致连接超时。
在ipvs 模式下它部分工作:
如果192.168.122.71 VIP 被一个有 pod 的节点持有,那么大约 50% 的请求是成功的,并且它们总是由本地 pod 提供服务。该应用程序还获得了主机的真实远程 IP (192.168.122.1)。其他 50%(大概被发送到另一个节点上的 pod)正在超时。
如果 VIP 被没有 pod 的节点持有,那么所有请求都会超时。
我还检查了它是否无论如何都会影响结果,以始终将规则保留在所有节点上,而不是将其仅保留在持有 VIP 的节点上并在 VIP 释放时将其删除:结果是两种情况都一样。
有谁知道它为什么不起作用以及如何解决它?我会很感激这方面的帮助:)
【问题讨论】:
标签: kubernetes iptables kube-proxy metallb