我是山姆鍋

本文屬於「我的 K8S DevOps 實驗環境」文章系列,說明如何利用 MetalLB 來作為此實驗環境的服務負載均衡器方案,看看這個 K8S 裸機負載均衡器是否可以不負眾望。

本文假設您已經了解 Kubernetes 的「服務 (service)」概念。

[Kubernetes] What Is Service?
hwchiu 關於 Kubernetes service 的文章

MetalLB 簡介

在雲端託管的 K8S 叢集系統,當建立型態 (type) 為 LoadBalancer 的服務 (service) 資源時 (以下統稱 LoadBalancer 服務),雲端服務供應商會自動建立對應的網路負載均衡器 (NLB) 並設定必要的健康檢查機制,如此,其它系統可以從外部存取叢集服務。如果選擇自建 K8S 叢集,很有可能就沒有這樣的機制存在。MetalLB 就是特別針對自行部署的 K8S 叢集提供 LoadBalancer 服務。當有 LoadBalancer 服務物件需要建立時,MetalLB 就從預先指定的 IP 位址池 (address pool) 中配置一個給該服務使用,位址池中可以是私有 (private) 或者公開 (public) 的 IP。MetalLB 透過兩種機制來進行節點故障時 IP 位址的錯誤轉移 (failover),以確保 LoadBalancer 服務的 IP 位址的可用性 (availability),目前 MetalLB 透過下列方式來將 IP 位址從故障的節點轉而綁定的新的節點:

  1. ARP(for IPv4)/NDP(for IPv6):屬於第 2 層網路協定,可以在區網 (LAN) 廣播節點的 IP 位址達到重新綁定 IP 的目的。

  2. BGP:屬於第 3 層網路協定,MetaLB 的每個節點會跟機房中支援 BGP 的路由器 (router) 建立連線,透過該路由器廣播 LoadBalancer 服務的 IP 位址資訊。

提醒:第 1 種方式 MetalLB 其實並沒有提供額外的負載均衡功能,服務的負載均衡依然只由 Kubernetes 的 kube-proxy 來提供。第 2 種方式除了使用 Kubernetes 內建的負載均衡外,也額外利用了 BGP 特性來分散請求到多個 Kubernetes 節點。,

MetalLB
MetalLB 官網

部署 MetalLB

在 SPK Cluster 實驗環境中,部署 MetalLB 是由 scripts/metallb-deploy.sh 此腳本實現,在 spkmaster-1 節點命令列介面執行 bash /vagrant/scripts/metallb-deploy.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
vagrant@spkmaster-1:~$ bash /vagrant/scripts/metallb-deploy.sh
[TASK] Deploy MetalLB system v0.9.3
namespace/metallb-system created
podsecuritypolicy.policy/controller created
podsecuritypolicy.policy/speaker created
serviceaccount/controller created
serviceaccount/speaker created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
role.rbac.authorization.k8s.io/config-watcher created
role.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/config-watcher created
rolebinding.rbac.authorization.k8s.io/pod-lister created
daemonset.apps/speaker created
deployment.apps/controller created
secret/memberlist created
[TASK] Configure IP range for service load balancers: 172.42.42.201-172.42.42.250
configmap/config created

成功完成啟動後,下面是 metallb-system 這個命名空間 (namespace) 中的資源物件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vagrant@spkmaster-1:~$ kubectl get all -n metallb-system
NAME READY STATUS RESTARTS AGE
pod/controller-57f648cb96-7h6pq 1/1 Running 0 115s
pod/speaker-26ls5 1/1 Running 0 115s
pod/speaker-cs7vc 1/1 Running 0 115s
pod/speaker-n4mxx 1/1 Running 0 115s
pod/speaker-vw87w 1/1 Running 0 115s

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/speaker 4 4 4 4 4 beta.kubernetes.io/os=linux 115s

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/controller 1/1 1 1 115s

NAME DESIRED CURRENT READY AGE
replicaset.apps/controller-57f648cb96 1 1 1 115s
  • 可以看出 MetalLB 系統由 ControllerSpeaker 兩種元件組成。
  • 此實驗環境設置的 LoadBalancer IP 範圍: 172.42.42.201~250。

驗證 LoadBalancer 服務

先部署一個範例 LoadBalancer 服務:

1
2
3
vagrant@spkmaster-1:~$ kubectl apply -f  /vagrant/examples/metallb/loadbalancer-service.yaml
deployment.apps/nginx created
service/nginx created

檢查服務狀態:

1
2
3
4
vagrant@spkmaster-1:~$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d1h
nginx LoadBalancer 10.107.107.254 172.42.42.201 80:30236/TCP 14s

如果 EXTERNAL-IP 如上面所示有出現 IP 位址 (172.42.42.2xx) 則表示 MetalLB 正常運作。

小結

MetalLB Layer 2 機制提供類似 Keepalived 的 IP 錯誤移轉功能,但與 Kubernetes 高度整合可以方便管理 IP 位址以及實現 LoadBalancer 服務。雖然 MetalLB 是否適合用在正式生產環境還需要多加考量,但用在此實驗環境來模擬雲端託管 K8S 服務倒是恰得其所。