今天要來建立牧場的智慧流量分配系統!就像牧場主需要設計多條道路讓訪客能順利進入不同的牛舍,而不會在單一入口造成大塞車,MetalLB 就是 Kubernetes 世界的交通管制中心。在地端環境中,我們沒有雲端供應商提供的 LoadBalancer 服務,MetalLB 正是解決這個問題的最佳方案,讓我們的 Service 也能擁有真正的外部 IP!
在雲端環境中,當你建立 type: LoadBalancer
的 Service 時,雲端供應商會自動幫你配置負載均衡器和外部 IP。但在地端環境中,Service 本身會正常建立並運作,只是 EXTERNAL-IP
欄位會一直顯示 <pending>
狀態,因為沒有任何組件負責提供外部 IP 地址。此時 Service 仍可透過 ClusterIP 或 NodePort 的方式正常存取。
傳統地端解決方案的限制:
NodePort vs externalIPs 實務比較:
# NodePort 適用場景:
- 開發測試環境快速存取
- 臨時性的服務暴露
- 不在意端口號的內部工具
# externalIPs 適用場景:
- 需要固定 IP 和標準端口 (80/443)
- 有現成的外部 IP 資源
- 願意手動管理 IP 分配
# 兩者共同問題:
- 缺乏企業級的負載均衡和故障轉移
- 難以整合監控和日誌系統
- 無法提供雲端級的服務體驗
# 社群技術專家觀點:
- externalIPs 被認為是「規格不足的安全蟲洞」
- 允許非管理員使用者直接對節點網路程式設計
- LoadBalancer + Controller 是更安全的權限控制模型
MetalLB 是專門為裸機(Bare Metal)Kubernetes 集群設計的負載均衡器實現,它使用標準的網路協議來實現真正的 LoadBalancer 功能。
MetalLB 核心價值:
type: LoadBalancer
MetalLB 採用簡潔的雙組件架構:
架構圖示:
MetalLB 提供兩種工作模式,適用於不同的網路環境:
工作原理:
Layer 2 模式通過 ARP(Address Resolution Protocol,地址解析協議) 響應來告知外部網路「這個 IP 地址在我這台機器上」。
技術名詞解釋:
流程示例:
優缺點分析:
✅ 優點:
❌ 缺點:
工作原理:
BGP 模式使用 BGP (Border Gateway Protocol,邊界閘道協議) 向路由器廣播路由信息,告知外部網路「要到達這個 IP,請走這條路」。
技術名詞解釋:
流程示例:
優缺點分析:
✅ 優點:
❌ 缺點:
# 選擇 Layer 2 模式的情況:
- 小型環境(< 10 節點)
- 使用一般的交換器設備
- 家用路由器環境(如 TP-Link、ASUS、Netgear 等)
- 對高可用性要求不嚴格
- 網路管理員不熟悉 BGP 協議
# 選擇 BGP 模式的情況:
- 大型生產環境
- 有企業級路由器支援 BGP
- 需要真正的負載均衡
- 對故障轉移時間要求嚴格
# 本文實驗環境:
- 使用 TP-Link 家用路由器,因此選擇 Layer 2 模式
- 適合個人學習和小型實驗環境
在安裝 MetalLB 前,需要確認幾個重要的前置條件:
# 檢查 K8s 版本(需要 v1.13.0 或以上)
kubectl version --short
# 輸出範例:
# Server Version: v1.28.8+rke2r1
RKE2 預設使用 iptables 模式,如果要使用 IPVS 模式才需要特殊配置:
# RKE2 中檢查 kube-proxy 模式
kubectl get nodes -o wide
# 直接查看 kube-proxy 進程參數(最可靠的方法)
ps aux | grep kube-proxy
# 檢查目前使用的代理模式
ps aux | grep kube-proxy | grep -o "proxy-mode=[a-z]*"
# 如果輸出是 proxy-mode=iptables,表示使用 iptables 模式
# 如果輸出是 proxy-mode=ipvs,表示使用 IPVS 模式
範例輸出解讀:
# iptables 模式(RKE2 預設)
kube-proxy --proxy-mode=iptables --cluster-cidr=10.42.0.0/16 ...
# IPVS 模式(需要手動配置)
kube-proxy --proxy-mode=ipvs --ipvs-strict-arp=true --cluster-cidr=10.42.0.0/16 ...
IPVS 模式配置(選用):
重要提醒:本文使用 iptables 模式即可,MetalLB 運作完全正常。
如果未來需要切換到 IPVS 模式,可以透過 Rancher UI 編輯集群 YAML:
spec:
rkeConfig:
machineGlobalConfig:
kube-proxy-arg:
- proxy-mode=ipvs
- ipvs-strict-arp=true
切換後需要重新建立集群讓配置生效。
iptables 模式(RKE2 預設):
IPVS 模式(需手動啟用):
比較項目 | iptables | IPVS |
---|---|---|
小規模環境 | ✅ 足夠快速 | ⚡ 稍快但差異不大 |
大規模環境 | ❌ 規模增長時效能下降 | ✅ 效能相對穩定 |
CPU 使用率 | 較高(線性查找) | 較低(雜湊查找) |
記憶體使用 | 較低 | 較高 |
設定複雜度 | 簡單(預設) | 複雜(需配置) |
# 選擇 iptables 模式的情況:
- 小型到中型集群
- 追求穩定性和簡單性
- 資源有限的環境
- 預設配置已滿足需求(推薦)
# 選擇 IPVS 模式的情況:
- 大規模生產環境
- 對效能有特殊要求
- 需要進階負載均衡算法
- 願意承擔額外的配置複雜性
# 本文實驗環境:
- 使用 RKE2 預設的 iptables 模式
- Cilium CNI 也有取代 kube-proxy 的能力
- 小規模環境下 iptables 已經足夠
重要資訊:無論使用哪種模式,MetalLB 都能正常運作!
strict ARP
技術名詞解釋:
# 檢查目前使用的 CNI
kubectl get pods -n kube-system | grep -E "(cilium|flannel|calico|weave)"
# 確認 CNI 與 MetalLB 相容(大多數主流 CNI 都支援)
使用 Helm 進行安裝(推薦方式):
# 添加 MetalLB Helm repository
helm repo add metallb https://metallb.github.io/metallb
# 更新 Helm repository
helm repo update
# 安裝 MetalLB
helm install metallb metallb/metallb -n metallb-system --create-namespace
# 確認安裝狀態
kubectl get pods -n metallb-system
Helm 安裝優勢:
helm list
檢查部署狀態檢查安裝狀態:
# 檢查 Helm 部署狀態
helm list -n metallb-system
# 檢查 MetalLB CRDs 是否已建立
kubectl get crd | grep metallb
在配置前,需要先規劃可用的 IP 地址範圍:
IP 規劃考量:
# 家用路由器環境範例:
# - 路由器通常是網段的第一個 IP (如 192.168.x.1)
# - K8s 節點分配固定 IP 範圍
# - 檢查路由器 DHCP 設定,避開自動分配範圍
# - MetalLB 使用 DHCP 範圍外的靜態 IP
# IP 規劃原則:
# 1. 不與現有設備衝突
# 2. 與集群節點在同一網段
# 3. 避開 DHCP 保留範圍(重要!)
# 4. 建議使用網段末端的 IP 範圍
# 建立 IP 地址池配置檔案
cat > metallb-ippool.yaml << 'EOF'
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: production-pool
namespace: metallb-system
spec:
addresses:
# 使用範圍格式(避開 DHCP 保留範圍)
- 192.168.0.250-192.168.0.254
# 或者單一 IP 指定
# - 192.168.0.250
# - 192.168.0.251
autoAssign: true
EOF
# 套用設定
kubectl apply -f metallb-ippool.yaml
# 確認 IP 池建立成功
kubectl get ipaddresspool -n metallb-system
技術名詞解釋:
對於大多數地端環境,Layer 2 模式是最簡單的選擇:
# 建立 Layer 2 廣播配置
cat > metallb-l2advertisement.yaml << 'EOF'
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: production-l2adv
namespace: metallb-system
spec:
# 關聯到指定的 IP 池
ipAddressPools:
- production-pool
# 可以指定特定節點(可選)
# nodeSelectors:
# - matchLabels:
# kubernetes.io/hostname: node1
EOF
# 套用設定
kubectl apply -f metallb-l2advertisement.yaml
# 確認 L2Advertisement 建立成功
kubectl get l2advertisement -n metallb-system
建立一個簡單的 nginx 測試環境:
# 建立測試應用
cat > nginx-loadbalancer-test.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-lb-test
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: nginx-lb-test
template:
metadata:
labels:
app: nginx-lb-test
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 100m
memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
name: nginx-loadbalancer
namespace: default
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: nginx-lb-test
EOF
# 部署測試應用
kubectl apply -f nginx-loadbalancer-test.yaml
# 檢查 Service 狀態
kubectl get svc nginx-loadbalancer
# 注意觀察 EXTERNAL-IP 是否已分配(不再是 <pending>)
# 檢查 IP 分配詳情
kubectl describe svc nginx-loadbalancer
# 測試外部連線(IP 會是 250-254 範圍中的一個)
curl http://192.168.0.250
在初次測試時遇到:
基本檢查:
# 檢查 Service 是否正確分配 IP
kubectl get svc nginx-loadbalancer
# 檢查 MetalLB 狀態
kubectl get pods -n metallb-system
kubectl logs -n metallb-system -l app.kubernetes.io/component=speaker
# 檢查外部設備的 ARP 表
arp -a | grep 192.168.0.250
今天我們成功部署了 MetalLB 負載均衡器,讓地端 Kubernetes 集群也能享受 LoadBalancer Service 的便利!從基本概念到實際部署,從 Layer 2 到 BGP 模式,我們建立了完整的外部流量分配機制。記住選擇合適的工作模式:簡單環境用 Layer 2,企業環境考慮 BGP。
明天我們要繼續完善基礎設施,學習 Ingress Controller 的流量路由設定,建立更靈活的 HTTP/HTTPS 流量管理機制!
💡 牧場主小提示:MetalLB 就像牧場的智慧門禁系統,Layer 2 模式像是單一大門管制,BGP 模式像是多個入口分流!記住三個關鍵:IP 規劃要仔細、模式選擇看環境、監控測試不能少。有了 MetalLB,你的服務就能像雲端一樣擁有真正的外部 IP 了!