首页/云/Kubernetes 速查/MetalLB 与裸金属 LoadBalancer
网络与服务55 条

MetalLB 与裸金属 LoadBalancer

裸金属集群的 LoadBalancer 实现:从配置的地址池给 Service 分配外部 IP,L2 模式用 ARP/NDP 宣告,BGP 模式与路由器对接。

Kubernetes 速查云更新于 2026-10-13

裸金属上的负载均衡从哪来

云环境里 LoadBalancer 型 Service 由云控制器分配外部地址;裸金属集群没有这层能力,MetalLB 就是补上这一环的实现:管理员预先声明地址池,MetalLB 从池中给 LoadBalancer 型 Service 分配外部 IP,再通过 L2(用 ARP/NDP 宣告)或 BGP(与上游路由器建邻居)把外部流量引到集群节点。L2 模式部署简单,但同一个 IP 同一时刻只由一个节点应答;BGP 模式配合路由器可实现更均衡的入口。

基本信息

适用场景裸金属或自建环境,缺少云厂商负载均衡能力
核心对象IPAddressPool 与 L2Advertisement;BGP 模式另有邻居与宣告类对象
地址分配从池中自动分配,也可按注解指定具体地址
前置条件地址池必须在网络侧可达,且与节点所在网段规划一致
观察入口kubectl get ipaddresspool、kubectl get svc 的 EXTERNAL-IP 列

典型使用场景

  • 自建机房暴露入口:给对外服务分配固定外部地址
  • 迁移替换:把原硬件负载均衡的 VIP 逐步改由集群宣告
  • 预生产环境:在没有云负载均衡的测试集群里模拟真实入口
  • 入口固定化:给白名单场景提供稳定不变的外部地址
  • 多机房部署:按机房划分地址池,控制入口就近

地址池与宣告示例

地址池与宣告示例
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: prod-pool
  namespace: metallb-system
spec:
  addresses:
    - 203.0.113.10-203.0.113.20      # 池内地址范围
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: prod-l2
  namespace: metallb-system
spec:
  ipAddressPools: ["prod-pool"]      # 用 L2 方式宣告该池

验证

验证
kubectl get ipaddresspool -A
kubectl get svc web-lb -n prod                   # EXTERNAL-IP 应显示池内地址
kubectl -n metallb-system logs deploy/speaker --tail=30
kubectl get events -n prod | grep -i -E 'loadbalancer|external'

两种宣告模式

模式工作方式特点
L2节点用 ARP 或 NDP 应答地址部署简单,同一 IP 同一时刻单节点应答,故障切换有秒级窗口
BGP与路由器建立邻居并宣告路由可多节点等价负载,需要网络侧配合
地址池预先声明的可用地址范围规划不当会与现有设备地址冲突
地址池要与节点所在二层网络同网段(L2 模式),并且不与现有设备地址、其他 VIP、DHCP 池冲突,否则会出现地址争用,影响范围不止集群内部。
升级 MetalLB 前先确认 CRD 与配置对象的版本兼容性:不同大版本之间字段有调整,配置无法识别时新建的 Service 将拿不到外部地址。

易错点

  • 地址池与现有 VIP 或设备地址冲突:内网出现地址争用,故障范围可能扩展到集群之外
  • 在 L2 模式下按多节点分担容量做规划:实际只有单节点应答,容量与故障切换都得按单节点估算
  • 把任意网段当作地址池:地址必须由网络侧路由可达,随便选公网段对外不可达
  • 升级时不核对 CRD 与对象结构:旧配置无法被识别,新服务长期停在待分配状态

数据来源与参考

  • MetalLB 官方文档 · 配置与概念
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌