网站Logo 小城的博客

Kubernetes 集群负载均衡器:MetalLB

admin
6
2025-02-19

一、引言

在云原生架构中,Kubernetes 对负载均衡能力的实现呈现出鲜明的环境依赖性:当部署在公有云环境时,LoadBalancer 类型的 Service 可无缝对接 AWS ELB、GCP LB 等云厂商提供的负载均衡服务,实现外部流量的高效分发;但在裸机服务器或本地数据中心环境中,由于缺乏云厂商的基础设施支持,这一核心功能出现 “断层”——LoadBalancer 类型的 Service 往往长期处于 Pending 状态,成为制约裸机 Kubernetes 集群对外提供服务的关键瓶颈。​

正是在这一背景下,MetalLB 作为专为裸机 Kubernetes 环境设计的负载均衡方案应运而生,它填补了原生 K8s 在非云环境中负载均衡能力的空白,为集群外部流量接入提供了稳定可靠的解决方案。

二、什么是 MetalLB?

MetalLB 是一个专为裸机 Kubernetes 集群设计的开源负载均衡器,通过标准路由协议(如 ARP/NDP 或 BGP)实现外部流量的接入。其核心功能包括:

IP 地址分配:从预配置的地址池中动态分配 IP 给 LoadBalancer 类型的 Service。

IP 广播:通过 Layer2(ARP/NDP)或 BGP 协议,将分配的 IP 通告给外部网络,实现流量路由256。

与云厂商方案不同,MetalLB 无需依赖特定硬件或云服务,特别适用于本地数据中心、边缘计算等场景。

什么是Layer2和BGP协议?

Layer2 是数据链路层,ARP(地址解析协议)用于 IPv4 环境,将 IP 地址解析为 MAC 地址,以实现局域网内设备通信;NDP(邻居发现协议)用于 IPv6 环境,功能类似 ARP。BGP(边界网关协议)是网络层协议,用于在不同自治系统之间传递路由信息,实现跨网络的流量转发和路径选择。

用简单的话来说就是:

Layer2 就是网络中的 “邻居找邻居” 这件事。ARP 好比在 IPv4 这条街上,A 家要找 B 家,但不知道 B 家的门牌号(MAC 地址),就喊一嗓子问谁是 B 家,B 家听到后就告诉 A 家自己的门牌号。NDP 则是 IPv6 这条街上干类似活的。

而 BGP 就像是快递公司(自治系统)之间的 “指路牌”,告诉快递员(路由器)包裹该走哪条路、怎么转,才能把包裹从发件地送到收件地。

部署与测试

1.此次K8S环境使用的是K8S1.23.17版本,CNI用的是Calico,CRI为Docker
 
 
2.修改kube-proxy的configMap
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/"  | \
sed -e 's#mode: ""#mode: "ipvs"#' | \
kubectl apply -f - -n kube-system
 
 
3.下载metallb
[root@master231 metallb]# wget https://raw.githubusercontent.com/metallb/metallb/v0.14.9/config/manifests/metallb-native.yaml
 
 
 
4.部署metallb
[root@master231 /manifests/metallb]# kubectl apply -f metallb-native.yaml 
namespace/metallb-system created
.....
validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-webhook-configuration configured
 
6.查看metallb的状态
[root@master231 /manifests/metallb]# kubectl get deploy,rs,svc,po -n metallb-system 
NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/controller   1/1     1            1           54s
 
NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/controller-686c7db689   1         1         1       54s
 
NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/metallb-webhook-service   ClusterIP   10.200.59.227   <none>        443/TCP   54s
 
NAME                              READY   STATUS    RESTARTS   AGE
pod/controller-686c7db689-cqg9l   1/1     Running   0          54s
pod/speaker-dqlwr                 1/1     Running   0          54s
pod/speaker-mxrzl                 1/1     Running   0          53s
pod/speaker-zxzcp                 1/1     Running   0          53s
 
7.创建MetalLB地址池
[root@master231 /manifests/metallb]# cat metallb-ip-pool.yaml 
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: linuxnet
  namespace: metallb-system
spec:
  addresses:
  - 10.0.0.150-10.0.0.180
 
---
 
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: xixi
  namespace: metallb-system
spec:
  ipAddressPools:
  - linuxnet
[root@master231 /manifests/metallb]# kubectl apply -f metallb-ip-pool.yaml
ipaddresspool.metallb.io/linux96 created
l2advertisement.metallb.io/xixi created
 
8.验证LoadBalancer是否可用
[root@master231 /manifests/metallb]# cat deploy-ns-svc.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: haha
 
---
 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-xiuxian
  namespace: haha
  labels:
    apps: xiuxian
spec:
  replicas: 5
  selector:
    matchLabels:
      version: v1
  template:
    metadata:
      labels:
        version: v1
        school: haha
        class: linux
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/nginx-k8s/apps:v1
        name: xiuxian
 
---
 
apiVersion: v1
kind: Service
metadata:
  name: svc-xiuxian-lb
  namespace: haha
spec:
  type: LoadBalancer  
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30120
  selector:
    version: v1
 
# 
[root@master231 metallb]# kubectl apply -f deploy-ns-svc.yaml
[root@master231 /manifests/metallb]# kubectl get deploy,rs,po,svc -n haha
NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/deploy-xiuxian   5/5     5            5           53s
 
NAME                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/deploy-xiuxian-9ddcfd7db   5         5         5       53s
 
NAME                                 READY   STATUS    RESTARTS   AGE
pod/deploy-xiuxian-9ddcfd7db-4dwd2   1/1     Running   0          53s
pod/deploy-xiuxian-9ddcfd7db-9x2db   1/1     Running   0          53s
pod/deploy-xiuxian-9ddcfd7db-bkfcc   1/1     Running   0          53s
pod/deploy-xiuxian-9ddcfd7db-mxq2x   1/1     Running   0          53s
pod/deploy-xiuxian-9ddcfd7db-zq88k   1/1     Running   0          53s
 
NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/svc-xiuxian-lb   LoadBalancer   10.200.244.45   10.0.0.150    80:30120/TCP   53s
 
访问测试:
	基于NodePort端口访问 
http://10.0.0.231:30120/
http://10.0.0.232:30120/
http://10.0.0.233:30120/
 
	基于LoadBalancer访问
10.0.0.150

四、MetalLB 工作流程

MetalLB 由两个核心组件协作:

Controller:监听 Service 事件,负责 IP 地址分配与回收。

Speaker:以 DaemonSet 形式运行,根据配置模式(Layer2/BGP)广播 IP2610。

新增 Service 流程:

Controller:检测到 LoadBalancer 类型 Service 后,从地址池分配 IP 并写入 Service 的 status.loadBalancer.ingress 字段。

Speaker:根据模式通告 IP。Layer2 模式下,通过 ARP/NDP 响应;BGP 模式下,向路由器发布路由表10。

故障切换:Layer2 模式通过 memberlist 库实现 Leader 选举,故障时重新选举并更新 ARP 响应(耗时约数秒)25。

Layer2 模式和BGP 模式

Layer2 模式

原理:选举一个 Leader 节点,通过 ARP/NDP 将 Service IP 绑定到该节点的 MAC 地址。流量经 Leader 节点转发至 Pod。

优点:配置简单,无需 BGP 路由器支持。

缺点:

单点瓶颈:流量集中到 Leader 节点,带宽受限于单节点性能。

故障转移延迟:客户端 ARP 缓存可能导致短暂服务中断(约 5-10 秒)16。

适用场景:中小规模集群、测试环境或对高可用性要求较低的场景。

BGP 模式

原理:每个节点与 BGP 路由器建立对等会话,将 Service IP 作为等价多路径(ECMP)路由通告,实现流量负载均衡。

优点:

真正负载均衡:流量分散到多个节点。

扩展性强:支持大规模集群。

挑战:

路由器依赖:需支持 BGP 协议,且配置复杂。

哈希算法限制:路由器基于五元组哈希分配连接,节点故障时可能导致部分连接重置210。

优化建议:

使用支持弹性 ECMP 的路由器,减少节点变更对连接的影响。

将服务拆分至多个 IP,结合 DNS 逐步迁移流量10。

适用场景:生产环境、高吞吐量服务。

使用建议

IP 地址规划:

预留充足 IP 段,避免与现有网络冲突。

使用 IPAddressPool 的 autoAssign 属性控制自动分配范围36。

网络兼容性验证:

确保节点间 7946 端口(memberlist)互通。

Calico 用户需禁用 BGP 或调整 Peer 配置36。

监控与告警:

监控 metallb_allocator_ips_total 指标,避免地址池耗尽。

集成 Prometheus 抓取 Speaker 和 Controller 指标10。

动物装饰