MetalLB K8S 负载均衡器教程
在云平台(AWS、GCP、Azure)的 Kubernetes 中,创建 LoadBalancer 类型的 Service 会自动分配一个外部 IP。但在搬瓦工 VPS 这样的裸金属环境中,Kubernetes 本身不提供负载均衡器实现,LoadBalancer 类型的 Service 会一直处于 Pending 状态。MetalLB 填补了这个空缺,它为裸金属 Kubernetes 集群提供了网络负载均衡器的实现。
一、MetalLB 工作模式
- Layer2 模式:使用 ARP(IPv4)或 NDP(IPv6)协议在本地网络中宣告 IP。配置简单,不需要特殊网络设备,适合搬瓦工 VPS 单节点或小型集群。
- BGP 模式:通过 BGP 协议与网络路由器交换路由信息。适合大规模部署,但需要支持 BGP 的路由设备。
对于搬瓦工 VPS 环境,Layer2 模式是最简单实用的选择。
二、安装 MetalLB
2.1 使用 Manifest 安装
# 安装 MetalLB
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.3/config/manifests/metallb-native.yaml
# 等待 Pod 就绪
kubectl wait --namespace metallb-system \
--for=condition=Ready pods \
--all --timeout=120s
2.2 使用 Helm 安装
helm repo add metallb https://metallb.github.io/metallb
helm repo update
helm install metallb metallb/metallb \
--namespace metallb-system \
--create-namespace
三、配置 Layer2 模式
# 创建 IP 地址池
cat > metallb-config.yaml <<'EOF'
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-pool
namespace: metallb-system
spec:
addresses:
- 你的VPS公网IP/32
# 如果有多个IP,可以配置范围
# - 192.168.1.200-192.168.1.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default
namespace: metallb-system
spec:
ipAddressPools:
- default-pool
EOF
kubectl apply -f metallb-config.yaml
在搬瓦工 VPS 单 IP 环境中,将 VPS 的公网 IP 作为地址池。注意这种配置下只能有一个 LoadBalancer Service 使用该 IP,不同服务通过端口区分。
四、使用 LoadBalancer Service
# 创建 LoadBalancer 类型的 Service
cat > nginx-lb.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-lb
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 80
protocol: TCP
EOF
kubectl apply -f nginx-lb.yaml
# 查看分配的 External IP
kubectl get svc nginx-lb
五、指定 IP 地址
# 在 Service 中指定特定 IP
apiVersion: v1
kind: Service
metadata:
name: myapp-lb
annotations:
metallb.universe.tf/address-pool: default-pool
spec:
type: LoadBalancer
loadBalancerIP: 指定IP地址
selector:
app: myapp
ports:
- port: 443
targetPort: 8443
六、多地址池配置
cat > multi-pool.yaml <<'EOF'
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: internal-pool
namespace: metallb-system
spec:
addresses:
- 10.0.0.200-10.0.0.250
autoAssign: false
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: external-pool
namespace: metallb-system
spec:
addresses:
- 公网IP/32
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: internal-adv
namespace: metallb-system
spec:
ipAddressPools:
- internal-pool
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: external-adv
namespace: metallb-system
spec:
ipAddressPools:
- external-pool
EOF
kubectl apply -f multi-pool.yaml
七、与 Ingress Controller 配合
在搬瓦工 VPS 上,推荐用 MetalLB 为 Ingress Controller 提供 LoadBalancer IP,再由 Ingress 路由到不同服务:
# 安装 Nginx Ingress Controller 并使用 MetalLB
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.service.type=LoadBalancer
# 查看 Ingress Controller 获取的外部 IP
kubectl get svc -n ingress-nginx
所有 HTTP/HTTPS 流量通过 Ingress Controller 的 LoadBalancer IP 进入,再根据域名和路径规则分发到后端 Service。
八、监控和排错
# 查看 MetalLB 控制器日志
kubectl logs -n metallb-system -l app=metallb,component=controller
# 查看 Speaker 日志
kubectl logs -n metallb-system -l app=metallb,component=speaker
# 查看 IP 分配情况
kubectl get ipaddresspools -n metallb-system
kubectl get svc --all-namespaces | grep LoadBalancer
九、常见问题
Service External IP 一直 Pending
# 检查 MetalLB Pod 是否正常运行
kubectl get pods -n metallb-system
# 检查 IP 地址池是否配置正确
kubectl get ipaddresspool -n metallb-system -o yaml
# 检查 L2Advertisement 是否创建
kubectl get l2advertisement -n metallb-system
Layer2 模式下的故障转移
Layer2 模式中,某一时刻只有一个节点响应 ARP 请求。当该节点故障时,MetalLB 会自动将 IP 切换到另一个健康节点,切换时间约 10 秒。
总结
MetalLB 让搬瓦工 VPS 上的 Kubernetes 集群也能使用 LoadBalancer 类型的 Service,填补了裸金属环境下的负载均衡缺口。搭配 External DNS 实现域名自动配置,可以构建完整的服务暴露方案。更多 Kubernetes 管理工具请参考 Kustomize 和 ArgoCD。选购搬瓦工 VPS 请访问 bwh81.net,购买时使用优惠码 NODESEEK2026 可享受 6.77% 的折扣。