我在 microk8s 上安装了 cilium 和 Metallb,在其中运行 docker 注册表 pod。pod 被分配了一个从 metallb 获取 IP 地址的服务,如果我从不同 VLAN 中的客户端对存储库运行 curl,一切都会正常工作。当我尝试从节点本身执行 curl 时,我只能访问内部 IP 上的注册表。
具体来说,该集群有 4 个节点位于一个 VLAN 中,并且有大量支持基础设施,其中不同的功能位于各自的 VLAN 中。VLAN 之间的所有流量都经过路由器/防火墙。
集群节点是多宿主的,即它们在每个 VLAN(本机 VLAN 和多个标记 VLAN)中都有一个 IP 地址。如果我再次从节点的本机 VLAN 为注册表提供一个外部 IP,那么一切都会正常工作,我可以使用外部 IP 访问注册表。
我觉得奇怪的是,当我向外部 VLAN 发送 curl 请求时,路由器将目标视为 pod 的内部 IP。这就是我完全迷茫的地方。
再次,外部 IP 可以轻松地从运行在不同 VLAN 中的机器上的客户端使用,而不是从节点本身使用,有人可以帮助我解决我可能遗漏的内容吗?
metallb 配置为使用第 2 层广告 (ARP)。
如果需要,我可以提供更多细节,但目前我还不确定从哪里开始。节点上的 tcpdump 不会记录任何流量,而在路由器上,它将目的地显示为 pod 的内部 IP。然后路由器不知道如何处理它。
编辑->添加更多上下文:
当从远程机器到达注册表 pod 时,来自路由器的 tcpdump:
IP 10.253.0.8.61859 > 10.9.40.146.5000: Flags [.], ack 2048, win 1025, length 0
从节点:
IP 10.9.40.148.13204 > 10.1.3.82.5000: Flags [S], seq 490446341, win 64240, options [mss 1460,sackOK,TS val 898569173 ecr 0,nop,wscale 7], length 0
因此,与其试图达到10.9.40.146.5000,它会尝试路由到10.1.3.82.5000。
第一个 IP 是服务的 IP 和预期结果,另一个 IP 是 Pod 的内部 IP,由 Cilium Cidr 块给出(10.1.0.0/16)
编辑-> 如果我从节点调用注册表,它也会有效,特别是使用默认 VLAN 中的节点 IP:
curl --interface 10.9.41.52 -k -X GET https://10.9.40.146:5000/v2/_catalog
但是当指定仅运行时:
curl -k -X GET https://10.9.40.146:5000/v2/_catalog
它使用 VLAN 12 IP 10.9.40.148 作为源,问题发生在路由器将目标视为 10.1.3.82(内部 pod IP)
编辑 -> 节点上的 tcpdump:
tcpdump -i ens2.12 src 10.9.40.148 and dst 10.1.3.82
获取流量:
IP 10.9.40.148.4167 > 10.1.3.82.5000: Flags [S], seq 2235907990, win 64240, options [mss 1460,sackOK,TS val 907774853 ecr 0,nop,wscale 7], length 0
执行请求时:
curl --interface 10.9.40.148 -k -X GET https://10.9.40.146:5000/v2/_catalog
编辑 -> 我已经设置的路由策略
vlans:
ens2.12:
link: ens2
id: 12
dhcp4: false
addresses:
- 10.9.40.148/29
routes:
- to: default
via: 10.9.40.145
table: 12
routing-policy:
- from: 10.9.40.148/29
table: 12
谢谢。
答案1
如果您尝试从 docker registry Pod 本身访问服务 IP,请检查:极端情况:Pod 无法通过服务 IP 访问自身。