J.V.'s Blog

MetalLB负载均衡器

MetalLB是一个为裸机Kubernetes集群提供网络负载均衡器实现的纯软件解决方案,本文详细介绍MetalLB的工作原理、安装配置及使用方法

什么是 MetalLB?

MetalLB 是一个为裸机 Kubernetes 集群提供网络负载均衡器实现的纯软件解决方案。它解决了裸机环境缺乏云厂商负载均衡器的问题。

MetalLB 工作原理

传统云环境 vs 裸机环境

云环境

裸机环境

MetalLB Layer 2 模式工作流程

  1. IP 分配

    • ingress-nginx Service 创建时,MetalLB 从 IP 池中选择一个 IP
    • 将这个 IP 分配给 Service 的 EXTERNAL-IP 字段
  2. ARP 响应

    • MetalLB 选择一个节点作为 "leader"
    • 这个节点开始响应对分配 IP 的 ARP 请求
    • 当外部设备询问 IP 的 MAC 地址时,选中的节点回答
  3. 流量路由

    • 外部流量发送到分配的 IP 时,实际到达选中的节点
    • 节点上的 iptables 规则将流量转发到 ingress-nginx Pod
    • kube-proxy 负责正确路由到实际的 Pod

简单类比

想象 MetalLB 就像一个"代理人":

使用 MetalLB

场景说明

在云服务器环境中,每个节点都有公网 IP 和内网 IP,但为了避免云厂商 LB 费用,选择使用 MetalLB。

网络环境示例

# 节点信息示例
kubectl get nodes -o wide
NAME      STATUS   ROLES    INTERNAL-IP    EXTERNAL-IP
node-1    Ready    master   10.0.1.10      47.100.1.10
node-2    Ready    worker   10.0.1.11      47.100.1.11  
node-3    Ready    worker   10.0.1.12      47.100.1.12

MetalLB 安装

helm repo add metallb https://metallb.github.io/metallb

# 基本使用默认配置即可
helm install metallb metallb/metallb \
  --namespace metallb-system \
  --create-namespace

# 官方文档中没有指定ns,创建后pod在default ns下
helm install metallb metallb/metallb

# 如果需要更多自定义配置
helm show values metallb/metallb > metallb-values.yaml

等待 MetalLB 组件启动

# 检查安装状态
kubectl get pods -n metallb-system

# 等待所有 Pod 就绪
kubectl wait --namespace metallb-system \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/name=metallb \
  --timeout=90s

MetalLB 配置 IP 地址池

metallb-config.yaml

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default-pool
  namespace: metallb-system
spec:
  addresses: # 通常与集群所在网络的子网一致
  - 10.0.0.200-10.0.0.230  # 服务器环境,填服务器内网IP
  autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: default-l2advertise
  namespace: metallb-system
spec:
  ipAddressPools:
  - default-pool
kubectl apply -f metallb-config.yaml

当用户创建一个 spec.type: LoadBalancer 的 Service 时,MetalLB 会检测到该 Service,并从配置的 IPAddressPool 中选择一个未使用的 IP 地址。

如果 Service 的 spec.loadBalancerIP 字段指定了一个特定 IP,MetalLB 会尝试分配该 IP(前提是该 IP 在地址池内且未被占用)。

举例说明: 假设你的云服务器内网段IPv4 CIDR是 10.0.0.0/24 节点IP: 10.0.0.10, 10.0.0.150, 10.0.0.175 选择未使用的IP段作为MetalLB池,通常与集群所在网络的子网一致 - 10.0.0.200-10.0.0.230

验证 MetalLB 安装

# 检查 MetalLB 组件状态
kubectl get all -n metallb-system

# 检查 IP 地址池配置
kubectl get ipaddresspool -n metallb-system
kubectl get l2advertisement -n metallb-system

参考文档

#k8s #开发