![在 Kubernetes 中分离“主机”和“外部”(负载均衡器)网络?](https://linux22.com/image/749730/%E5%9C%A8%20Kubernetes%20%E4%B8%AD%E5%88%86%E7%A6%BB%E2%80%9C%E4%B8%BB%E6%9C%BA%E2%80%9D%E5%92%8C%E2%80%9C%E5%A4%96%E9%83%A8%E2%80%9D%EF%BC%88%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E5%99%A8%EF%BC%89%E7%BD%91%E7%BB%9C%EF%BC%9F.png)
因为我喜欢把所有东西分开(出于安全考虑),所以我目前正在试验是否可以在 Kubernetes 中为“主机”网络和“外部”网络设置完全独立的网络。金属LB来管理交通。
作为一个实验设置,我现在有两个独立的 VLAN 和一个 VMware 虚拟机,它只看到两个正常的网络接口。
在该虚拟机上,我安装了 CentOS 7、Kubernetes 1.17、Calico 3.13.1 和 MetalLB 0.8.2
我认为不需要在“外部”接口上为节点提供 IP 地址,因为MetalLB 手册我读
第 2 层模式不需要将 IP 绑定到工作节点的网络接口。它通过直接响应本地网络上的 ARP 请求来工作,从而将机器的 MAC 地址提供给客户端。
这很好,因为这样一来,该节点实际上就无法从“外部”网络访问。
为了进行测试,我已配置 metallb 来管理两个网络上的一系列 IP(仅用于测试)
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 10.123.123.100-10.123.123.199
- 10.123.45.100-10.123.45.199
在虚拟机上,我为主机接口指定了一个 IP 地址 (DHCP),一切正常。我没有为“外部”接口指定 IP/路由/…,但我已确保它处于“启动”状态。
所以我看到这个(ens192 = 主机,ens224 = 外部)
[root@node1 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:ca:06:13 brd ff:ff:ff:ff:ff:ff
inet 10.123.123.6/24 brd 10.123.123.255 scope global dynamic ens192
valid_lft 75786sec preferred_lft 75786sec
3: ens224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:ca:06:1d brd ff:ff:ff:ff:ff:ff
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:dc:25:87:ec brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
(以及很多 cali* 接口)
[root@node1 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.123.123.1 0.0.0.0 UG 0 0 0 ens192
10.123.123.0 0.0.0.0 255.255.255.0 U 0 0 0 ens192
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.135.192 0.0.0.0 255.255.255.192 U 0 0 0 *
192.168.135.242 0.0.0.0 255.255.255.255 UH 0 0 0 calia47abf08c66
…
为了测试,我有一个简单的 Web 应用程序并且我已经将两个 K8s 服务附加到它:一个在“主机”网络上具有 loadBalancerIP,另一个在“外部”网络上具有 loadBalancerIP。
[root@node1 ~]# kubectl -n yauaa get all
NAME READY STATUS RESTARTS AGE
pod/yauaa-7d7bffd9fc-tdhg9 1/1 Running 5 2d6h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/yauaa LoadBalancer 10.104.33.179 10.123.123.100 80:31908/TCP 2d3h
service/yauaa-pub LoadBalancer 10.105.4.161 10.123.45.100 80:30695/TCP 2d7h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/yauaa 1/1 1 1 2d7h
NAME DESIRED CURRENT READY AGE
replicaset.apps/yauaa-7d7bffd9fc 1 1 1 2d6h
在 k8s 节点本身上本地运行,我可以对任一 IP 执行 curl,并且两者都会立即响应。因此,metallb 为服务提供的绑定似乎有效。
现在,在我的防火墙(Linux 设备)上,我可以对任一 IP 执行 curl,主机 IP 会响应,外部 IP 则不会。我确实看到此防火墙的 arp 表中存在正确的 IP-MAC 映射。但我没有收到响应。
# arp -a | fgrep 10.123
node1.k8s.basjes.nl (10.123.123.6) at 00:0c:29:ca:06:13 [ether] on eth1.2222
? (10.123.123.100) at 00:0c:29:ca:06:13 [ether] on eth1.2222
? (10.123.45.100) at 00:0c:29:ca:06:1d [ether] on eth1.2345
我尝试将 ens224 设置为混杂模式,也尝试为该接口的网关添加路由条目,但没有帮助。
我确实设法通过给这个 ens224 接口一个 IP 地址来让它运行,但这是我不希望有的,而且(如果我理解文档正确的话)也不需要。
显然我做错了什么。
正确的配置方法是什么?