本頁說明如何為 Google Distributed Cloud 設定與 MetalLB 搭配使用的套裝負載平衡。MetalLB 負載平衡器會在專屬的工作站節點集區中運作,也可以與控制層位於相同的節點。
如需 Google Distributed Cloud 提供的負載平衡拓撲範例,請參閱負載平衡器總覽。
需求條件
- 所有負載平衡器節點都必須位於同一個第 2 層子網路。
- 所有 VIP 都必須位於負載平衡器節點子網路中,且可透過子網路的閘道路由。
- 負載平衡器子網路的閘道必須監聽無故 ARP 訊息,並將 ARP 封包轉送至負載平衡器節點。
設定欄位
編輯叢集設定檔的 cluster.spec.loadBalancer
區段,設定隨附的負載平衡功能。如要瞭解叢集設定檔和有效設定的範例,請參閱下列其中一個頁面:
loadBalancer.mode
如要啟用組合式負載平衡,這個值必須為 bundled
。
loadBalancer.ports.controlPlaneLBPort
這個值會指定 Kubernetes 控制層 (Kubernetes API 伺服器) 接收流量適用的目的地通訊埠。
loadBalancer.vips.controlPlaneVIP
這個值會指定 Kubernetes 控制層 (Kubernetes API 伺服器) 接收流量適用的目的地 IP 位址。這個 IP 位址必須與叢集中的節點位於同一個第 2 層子網路。請勿在設定檔的 address pools
區段中列出這個地址。
loadBalancer.vips.ingressVIP
這個值會指定負載平衡器後方服務的 IP 位址,用於輸入流量。管理員叢集設定檔不得包含這個欄位。這個位址必須列在設定的「位址集區」部分。
loadBalancer.addressPools
設定的這部分包含一或多個位址集區。每個位址集區都會指定 IP 位址範圍清單。建立LoadBalancer
類型的 Service 時,系統會從這些範圍中選擇 Service 的外部 IP 位址。
地址集格式如下:
- name: POOL_NAME
avoidBuggyIPs: BOOLEAN
manualAssign: BOOLEAN
addresses:
- IP_RANGE
- IP_RANGE2
name
:地址集區的名稱 (pool-name),僅供機構內部使用。這個欄位無法變更。avoidBuggyIPs
:(選用)true
或false
。如果為true
,集區會省略以.0
和.255
結尾的 IP 位址。部分網路硬體會捨棄傳送至這些特殊位址的流量。你可以省略這個欄位,預設值為false
。這個欄位可變更。manualAssign
:(選用)true
或false
。如果true
,系統不會自動將這個集區中的位址指派給 Kubernetes 服務。如果true
,只有在服務明確指定時,才會使用這個集區中的 IP 位址。您可以省略這個欄位,預設值為false
。這個欄位可變更。addresses
一或多個不重疊 IP 位址範圍的清單。ip-range 可以 CIDR 標記法 (如198.51.100.0/24
) 或範圍標記法 (如198.51.100.0-198.51.100.10
,破折號周圍不得有空格) 指定。這個欄位無法變更。
addresses
清單中的 IP 位址範圍不得重疊,且必須與執行負載平衡器的節點位於同一個子網路。
loadBalancer.nodePoolSpec
這項設定會指定要執行負載平衡器的節點清單。根據預設,負載平衡器節點可以執行一般工作負載,這些節點上沒有特殊汙點。雖然負載平衡器節點集區中的節點可以執行工作負載,但與工作站節點集區中的節點不同。您無法將特定叢集節點納入多個節點集區。節點集區之間若有節點 IP 位址重疊,會導致叢集無法建立,以及其他叢集作業無法執行。
如要防止工作負載在負載平衡器節點集區的節點上執行,請在節點中新增下列汙點:
node-role.kubernetes.io/load-balancer:NoSchedule
Google Distributed Cloud 會為負載平衡所需的 Pod 新增此汙點的容許度。
以下範例顯示具有兩個節點的負載平衡節點集區。第一個節點具有標準 IP 位址 nodePoolSpec.nodes.address
(「1.2.3.4」) 和 Kubernetes IP 位址 nodePoolSpec.nodes.k8sIP
(10.0.0.32
)。為節點指定選用的 k8sIP
位址時,該位址會專門處理節點的資料流量,例如 Kubernetes API、kubelet 和工作負載的要求和回應。在這種情況下,標準 IP 位址 nodePoolSpec.nodes.address
會用於節點的 SSH 連線,以進行管理叢集作業。如未指定 k8sIP
位址,標準節點 IP 位址會處理節點的所有流量。
nodePoolSpec:
nodes:
- address: 1.2.3.4
k8sIP: 10.0.0.32
- address: 10.0.0.33
根據預設,負載平衡器節點集區中的所有節點,都必須與設定檔 loadBalancer.addressPools
區段中設定的負載平衡器 VIP 位於同一個第 2 層子網路。不過,如果您為節點指定 Kubernetes IP 位址 k8sIP
,則只有該位址需要與其他負載平衡器 VIP 位於相同的第 2 層子網路。
如果未設定 nodePoolSpec
,系統會透過控制層節點執行隨附的負載平衡器。建議您盡可能在不同的節點集區上執行負載平衡器。
控制層負載平衡
控制層負載平衡器會提供控制層虛擬 IP 位址 (VIP)。Google Distributed Cloud 會在負載平衡器節點上,以 Kubernetes 靜態 Pod 形式執行 Keepalived 和 HAProxy,藉此發布控制層 VIP。Keepalived 會在負載平衡器節點上使用 Virtual Router Redundancy Protocol (VRRP),確保高可用性。
資料平面負載平衡
資料平面負載平衡器適用於所有類型為 LoadBalancer
的 Kubernetes 服務。Google Distributed Cloud 會使用以第 2 層模式執行的 MetalLB,進行資料平面負載平衡。資料層負載平衡只能透過 Google Distributed Cloud 設定,請勿直接修改 MetalLB ConfigMap。您可以使用所有 MetalLB 功能,包括在服務之間共用 IP 位址。如需功能資訊,請參閱 MetalLB 說明文件。
MetalLB 會使用 daemonset 在每個節點上執行 speaker Pod,並使用成員清單確保高可用性。每個 Kubernetes 服務都有專屬的 MetalLB 負載平衡器節點,而不是整個叢集共用一個。如果有多項服務,流量就會以這種方式分配到負載平衡器節點。
資料層負載平衡器可以在控制層節點或部分工作站節點上執行。將資料層負載平衡器與控制層節點綁在一起,可提高控制層節點的利用率。此外,在控制層節點上進行組合也會增加控制層過載的風險,並提高控制層上機密資訊 (例如 SSH 金鑰) 的風險狀況。
負載平衡器分離
在 1.32 版之前,使用 MetalLB 設定第 2 層負載平衡時,控制層負載平衡器和資料層負載平衡器會在相同節點上執行。視設定而定,負載平衡器會在控制層節點上執行,或是在負載平衡器節點集區中執行。
下圖顯示預設的隨附負載平衡器設定,其中控制層和資料層負載平衡器都在控制層節點上執行,或都在負載平衡器節點集區中執行:
在 1.32 版叢集中,您可以設定控制層負載平衡器在控制層節點上執行,並設定資料層負載平衡器在負載平衡器節點集區中執行。建立 1.32 版叢集時,您可以指定負載平衡器是否要分開,也可以更新 1.32 版叢集,將資料層負載平衡器從控制層節點遷移至負載平衡器節點集區。
分離式負載平衡器的叢集設定應類似下列範例:
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
name: hybrid-ha-lb
namespace: cluster-hybrid-ha-lb
spec:
type: hybrid
profile: default
anthosBareMetalVersion: 1.32
gkeConnect:
projectID: project-fleet
controlPlane:
loadBalancer:
mode: bundled
nodePoolSpec:
nodes:
- address: 10.200.0.2
- address: 10.200.0.3
- address: 10.200.0.4
clusterNetwork:
pods:
cidrBlocks:
- 192.168.0.0/16
services:
cidrBlocks:
- 10.96.0.0/20
...
loadBalancer:
mode: bundled
...
nodePoolSpec:
nodes:
- address: 10.200.0.5
- address: 10.200.0.6
- address: 10.200.0.7
clusterOperations:
...
建立叢集時使用獨立負載平衡器
如果您要建立 1.32 以上版本的新叢集,可以設定負載平衡器,在控制層節點上執行控制層負載平衡器,並在負載平衡器節點集區上執行資料層負載平衡器。
下圖顯示控制層和資料層負載平衡器分別位於不同節點:
如要在建立叢集時區隔負載平衡器,請按照下列步驟操作:
在叢集設定檔中,指定具有
loadBalancer.nodePoolSpec
的負載平衡器節點集區,如本文的「loadBalancer.nodePoolSpec
」一節所述。將
controlPlane.loadBalancer.mode
新增至叢集設定檔,並將mode
值設為bundled
。完成叢集設定,然後執行
bmctl create cluster
建立叢集。
將資料層負載平衡器從控制層遷移
如果您有現有的 1.32 以上版本叢集,且未設定 controlPlane.loadBalancer.mode
或 loadBalancer.nodePoolSpec
,控制層負載平衡器和資料層負載平衡器都會在控制層節點集區中執行。您可以更新叢集,將資料平面負載平衡器遷移至負載平衡器節點集區。
下圖顯示資料層負載平衡器從控制層節點遷移後,控制層和資料層負載平衡器如何分離:
如要在更新叢集時,將資料平面負載平衡器遷移至負載平衡器節點集區,請按照下列步驟操作:
在叢集設定檔中,指定具有
loadBalancer.nodePoolSpec
的負載平衡器節點集區,如本文的「loadBalancer.nodePoolSpec
」一節所述。將
controlPlane.loadBalancer.mode
新增至叢集設定檔,並將mode
值設為bundled
。執行下列指令來更新叢集:
bmctl update cluster -c CLUSTER_NAME --kubeconfig=ADMIN_KUBECONFIG
更改下列內容:
CLUSTER_NAME
:您要更新的叢集名稱。ADMIN_KUBECONFIG
:管理員叢集 kubeconfig 檔案的路徑。
保留用戶端來源 IP 位址
使用隨附的第 2 層負載平衡解決方案建立的 LoadBalancer
Service,會使用外部流量政策的預設 Cluster
設定。這項設定 (spec.externalTrafficPolicy: Cluster
) 會將外部流量轉送至叢集範圍端點,但也會遮蓋用戶端來源 IP 位址。
Google Distributed Cloud 支援兩種保留用戶端來源 IP 位址的方法:
將負載平衡的轉送模式設為伺服器直接回傳 (DSR)。如要進一步瞭解 DSR 轉送模式,包括如何啟用這項模式,請參閱「設定負載平衡轉送模式」。
將
LoadBalancer
服務的外部流量政策設為本機,並相應設定相關服務和 Ingress。以下各節說明如何設定叢集,以使用這種方法。
LoadBalancer
服務
在 LoadBalancer
服務中使用 externalTrafficPolicy: Local
時,請將應用程式 Pod 設為在負載平衡器節點上執行。將下列 nodeSelector
新增至應用程式 Pod,即可進行這項變更:
apiVersion: v1
kind: Pod
...
spec:
nodeSelector:
baremetal.cluster.gke.io/lbnode: "true"
...
NodePort
服務
Kubernetes 會對 NodePort
執行來源網路位址轉譯 (SNAT)。如要保留用戶端來源 IP 位址,請將 service.spec.externalTrafficPolicy
設為 Local
。Kubernetes 不會再執行 SNAT,但您必須確保所選節點 IP 上有 Pod 正在執行。
Ingress
如果您的應用程式是 HTTP 服務,可以設定 Ingress 元件,讓用戶端 IP 位址可見:
開啟
istio-ingress
服務進行編輯:kubectl edit service -n gke-system istio-ingress
在
spec
中新增externalTrafficPolicy: Local
,然後儲存並結束編輯器。apiVersion: v1 kind: Service ... spec: ... externalTrafficPolicy: Local
開啟
istio-ingress
Deployment 進行編輯:kubectl edit deployment -n gke-system istio-ingress
將下列
nodeSelector
新增至 Deployment,然後儲存並結束編輯器。apiVersion: apps/v1 kind: Deployment ... spec: ... template: ... spec: ... nodeSelector: baremetal.cluster.gke.io/lbnode: "true" ...
現在,Ingress 後方的所有服務都會看到含有用戶端 IP 的 X-Forwarded-For
標頭,如下例所示:
X-Forwarded-For: 21.0.104.4