虽然 kubernetes 集群默认定义了 Ingress 和 LoadBalancer Service 资源,但都没有实现。
Ingress 问题不大,只需要安装官方另外做的 Ingress-nginx 控制器就可以了。甚至在 1.22 中正式引入了 IngressClasses ,以允许集群中同时包含多个 Ingress 控制器。
但 LoadBalancer 要考虑的就多了。它需要向集群外部的网络设备声明一些 IP 地址,以便集群外部的用户,在访问这些 IP 地址的时候,网络设备可以正确的路由和转发用户流量。
先说安装
首先你需要准备好镜像,我们把它们都推送到内网仓库中
FROM=quay.io
TOTO=192.168.1.10:8083
for NAME in metallb/{controller,speaker}:v0.14.5 frrouting/frr:9.0.2
do
docker pull $FROM/$NAME
docker tag $FROM/$NAME $TOTO/$NAME
docker push $TOTO/$NAME
docker rmi $TOTO/$NAME
done
然后再 helm
一把梭
helm repo add metallb https://metallb.github.io/metallb
helm upgrade -i --create-namespace metallb metallb/metallb \
--version 0.13.11 \
--namespace metallb-system \
--set controller.image.repository=metallb/controller \
--set speaker.image.repository=metallb/speaker \
--set speaker.frr.image.repository=frrouting/frr
使用默认参数即可,helm 参数只需要修改镜像地址到我们刚才推送的仓库中即可
再说配置
如何向集群外部的网络设施声明 IP 地址?我们有两种方法。
走二层,用 arp 协议宣告 mac 地址
在使用二层访问时,访问者或网关必须和集群所有主机同在一个二层网络下、且访问者/网关的 ip 子网必须包含 MetalLB 所声明的子网。满足这些条件,双方才能访问。
或者,我们用最简单的场景:直接从局域网内分配 ip 段给 metallb 用。例如,假设集群主机所在的网络和网关为 192.168.1.254/24
,我们将 192.168.1.48-63
这 16 个 ip 地址交给 Metal LB 分配:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: firewall-lan-p28
namespace: metallb-system
spec:
addresses:
- 192.168.1.48/28
注意,这里的 /28
并不是子网,因此可用地址数并不用跳过网络地址和广播地址,MetalLB 可以完整地使用整个 /28
地址空间。
上述配置只定义了地址池,还需要告诉 Metal LB,使用二层协议,向外部网络设施宣告地址:
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: firewall-lan-p28
namespace: metallb-system
spec:
ipAddressPools:
- firewall-lan-p28
走三层,用 bgp 协议宣告路由
三层的地址空间就大多了,我们可以选择非现有网络的任意网段。
先定义一个地址池:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: firewall-bgp
namespace: metallb-system
spec:
addresses:
- 10.42.0.0/16
同样的,这里的 /16
也不是子网,只是用来表示一个 ip 地址的范围。当你在看到第一个 LoadBalancer Service 的 External IP 为 10.42.0.0
时,不要惊讶它是一个“网络地址”,因为这不是一个子网。
配置 bgp 协议的对端:
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
name: firewall
namespace: metallb-system
spec:
myASN: 64512
peerASN: 64512
peerAddress: 192.168.1.254
这里我们在集群网络的网关上已经提前配置好了 bgp 协议,方法与之前 《使用 Calico CNI 打通集群网络》一致。
配置 bgp 声明:
apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:
name: metallb-advertisment
namespace: metallb-system
spec:
ipAddressPools:
- firewall-bgp
aggregationLength: 32
配置完成。从此只要有新的 LoadBalancer Service 被创建,Metal LB 控制器就会从地址池中分配未使用的 IP 地址,作为 External IP 分配给新的 LoadBalancer Service。
与 Calico CNI 的冲突
如果你的集群使用了 Calico CNI 的 bgp 模式,即集群已经在使用 bgp 协议向网关同步路由表的情况下,你将无法使用 Metal LB 的三层模式。
在大型机房中,你可能有机会让 Metal LB 与 Calico 分别与不通层级的 bgp peer 同步路由表。而在简单环境中,当你的网关已经在与 Calico CNI 同步路由表的情况下,你就只能使用集群网段剩余未分配的 IP 地址,来使 MetalLB 工作在二层模式了。