1. 项目背景解析:当K8s遇上裸金属

在Kubernetes集群中对外暴露服务时,云环境有现成的LoadBalancer解决方案,但裸金属环境却面临特殊挑战。传统方案中,Ingress Controller需要与外部负载均衡器配合工作,而MetalLB的出现彻底改变了这个局面——它让裸金属集群也能获得"云原生"的服务暴露体验。

这个标题用诙谐的比喻揭示了MetalLB的核心价值:作为裸金属环境下的负载均衡器实现,它默默承担了Ingress Controller背后的流量分发重任。就像健身搭档帮助完成负重训练一样,MetalLB让Ingress这个"老将"能够在没有云厂商LB支持的环境下继续发挥全部能力。

2. 核心架构拆解:MetalLB如何实现负重前行

2.1 二层模式(Layer 2)工作原理

MetalLB通过ARP/NDP协议响应,让集群中的某个节点"认领"虚拟IP。当外部请求到达该IP时:

  1. 被选中的节点通过kube-proxy规则将流量转发到对应Service
  2. 节点间通过memberlist协议保持状态同步
  3. 当前节点故障时,其他节点会接管虚拟IP

注意:二层模式需要确保所有节点位于同一广播域,且存在单节点瓶颈问题

2.2 BGP模式深度解析

对于需要水平扩展的场景:

  1. 每个节点与上游路由器建立BGP会话
  2. 通过ECMP实现多节点负载均衡
  3. 可配置本地优先级(localPref)控制流量走向
  4. 支持BFD协议快速检测链路故障
# 典型BGP配置示例
apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:
  name: sample-peer
spec:
  myASN: 64500
  peerASN: 64501
  peerAddress: 192.168.1.1
  holdTime: 90s

3. 与Ingress的黄金组合实践

3.1 典型部署架构

  1. MetalLB分配外部IP给Ingress Controller Service
  2. Ingress Controller根据规则路由到后端Pod
  3. 流量路径:客户端 → MetalLB IP → Ingress Pod → 业务Pod

3.2 性能优化配置

# Nginx Ingress优化示例
controller:
  config:
    use-forwarded-headers: "true"
    upstream-keepalive-connections: "1000"
  service:
    annotations:
      metallb.universe.tf/loadBalancerIPs: 203.0.113.10
    externalTrafficPolicy: Local  # 保持源IP且减少跳数

4. 生产环境避坑指南

4.1 常见故障排查

现象 检查点 解决方案
IP无法访问 防火墙规则 放行节点间7946/tcp(memberlist)
BGP会话中断 路由器配置 检查AS号匹配和密码设置
流量不均衡 ECMP配置 启用BGP multipath

4.2 高可用设计要点

  1. 部署至少3个Speaker Pod(DaemonSet模式)
  2. 为Controller配置Pod反亲和性
  3. 在BGP模式下配置多个对等体
  4. 监控关键指标:
    • metallb_allocator_ips_in_use
    • metallb_bgp_session_up

5. 进阶场景实践

5.1 多租户IP分配

通过AddressPool的namespace限制实现:

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: tenant-a
spec:
  addresses:
  - 192.168.1.100-192.168.1.150
  autoAssign: false
  allowedNamespaces:
    matchLabels:
      tenant: team-a

5.2 与网络策略配合

结合Calico NetworkPolicy实现安全隔离:

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-metallb
spec:
  selector: app == 'my-app'
  ingress:
  - action: Allow
    protocol: TCP
    source:
      namespaceSelector: projectcalico.org/name == 'metallb-system'

6. 监控与调优实战

6.1 Prometheus监控配置

scrape_configs:
  - job_name: 'metallb'
    kubernetes_sd_configs:
      - role: pod
        namespaces:
          names: ['metallb-system']
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_app]
        action: keep
        regex: 'metallb'

6.2 性能调优参数

  1. 调整BGP hold时间(默认90s)
  2. 配置合理的IP地址回收时间(默认5m)
  3. 对于大规模集群:
    speaker:
      nodeSelector:
        node-role.kubernetes.io/worker: ""
      tolerations:
        - key: "node-role.kubernetes.io/master"
          effect: "NoSchedule"
    

在实际生产环境中,我们发现当集群规模超过200节点时,需要特别注意Speaker Pod的资源限制,建议配置至少500m CPU和512Mi内存。同时,定期检查BGP路由表规模,避免超过路由器处理能力。

更多推荐