MetalLB负载均衡器
MetalLB是一个为裸机Kubernetes集群提供网络负载均衡器实现的纯软件解决方案,本文详细介绍MetalLB的工作原理、安装配置及使用方法
什么是 MetalLB?
MetalLB 是一个为裸机 Kubernetes 集群提供网络负载均衡器实现的纯软件解决方案。它解决了裸机环境缺乏云厂商负载均衡器的问题。
MetalLB 工作原理
传统云环境 vs 裸机环境
云环境:
- 创建 LoadBalancer Service 时,云提供商自动分配外部 IP
- 云负载均衡器将流量转发到集群节点
裸机环境:
- 没有云提供商的负载均衡器
- LoadBalancer Service 会一直处于
<pending>状态 - MetalLB 填补了这个空白
MetalLB Layer 2 模式工作流程
IP 分配:
- ingress-nginx Service 创建时,MetalLB 从 IP 池中选择一个 IP
- 将这个 IP 分配给 Service 的
EXTERNAL-IP字段
ARP 响应:
- MetalLB 选择一个节点作为 "leader"
- 这个节点开始响应对分配 IP 的 ARP 请求
- 当外部设备询问 IP 的 MAC 地址时,选中的节点回答
流量路由:
- 外部流量发送到分配的 IP 时,实际到达选中的节点
- 节点上的 iptables 规则将流量转发到 ingress-nginx Pod
- kube-proxy 负责正确路由到实际的 Pod
简单类比
想象 MetalLB 就像一个"代理人":
- 你想找"192.168.1.100先生"
- 实际上没有这个人,但是某个节点说:"我就是192.168.1.100"
- 你把请求给了这个节点,它再转交给真正的 nginx 服务
使用 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