裸金属上的负载均衡从哪来
云环境里 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 将拿不到外部地址。