使用 MetalLB 進行套裝組合負載平衡

本文說明如何設定 Google Distributed Cloud,透過 MetalLB 負載平衡器使用隨附的負載平衡功能。本文適用於負責設計及建構貴機構網路,以及安裝、設定和支援網路設備的網路專家。如要進一步瞭解內容中提及的常見角色和範例工作,請參閱「常見的 GKE Enterprise 使用者角色和工作」。 Google Cloud

在 Google Distributed Cloud 中,MetalLB 會以第 2 層模式執行。

MetalLB 設定範例

以下是執行 MetalLB 負載平衡器的叢集設定範例:

MetalLB 負載平衡器設定。
MetalLB 負載平衡器設定

上圖顯示 MetalLB 部署作業。MetalLB 會直接在叢集節點上執行。在本範例中,管理員叢集和使用者叢集位於兩個不同的 VLAN,且每個叢集都位於不同的子網路:

叢集 子網路
管理員叢集 172.16.20.0/24
使用者叢集 172.16.40.0/24

admin-cluster.yaml

管理員叢集設定檔的下列部分顯示上圖中的設定:

  • 高可用性控制層

  • MetalLB 負載平衡器

  • 管理員叢集 Kubernetes API 伺服器的 MetalLB VIP

network:
  ...
  controlPlaneIPBlock:
    netmask: "255.255.255.0"
    gateway: "172.16.20.1"
    ips:
    - ip: "172.16.20.50"
      hostname: "admin-cp-1"
    - ip: "172.16.20.51"
      hostname: "admin-cp-2"
    - ip: "172.16.20.52"
      hostname: "admin-cp-3"
loadBalancer:
  kind: "MetalLB"
  ...
  vips:
    controlPlaneVIP: "172.16.20.100"
...
adminMaster:
  cpus: 4
  memoryMB: 16384
  replicas: 3

user-cluster.yaml

使用者叢集設定檔的下列部分顯示以下設定:

  • 供 MetalLB 控制器選擇並指派給 LoadBalancer 類型服務的位址集區。Ingress VIP 位於這個集區中。

  • 為使用者叢集的 Kubernetes API 伺服器指定的 VIP,以及您選擇為 Ingress Proxy 設定的 Ingress VIP。

  • 已啟用 MetalLB 的節點集區。MetalLB 會部署在這個節點集區的節點上。

enableControlplaneV2: true
...
network:
  hostConfig:
  ...

  ipMode:
    type: "static"
    ipBlockFilePath: "config-folder/user-cluster-ipblock.yaml"
...
  controlPlaneIPBlock:
    netmask: "255.255.255.0"
    gateway: "172.16.40.1"
    ips:
    - ip: "172.16.40.21"
      hostname: "user-cp"
loadBalancer:
  kind: MetalLB
  metalLB:
    addressPools:
    - name: "address-pool-1"
      addresses:
      - "172.16.40.101-172.16.40.112
      avoidBuggyIPs: true
  ...

  vips:
    controlPlaneVIP: "172.16.20.100"
    ingressVIP: "172.16.40.101"
...
nodePools:
- name: "node-pool-1"
  cpus: 4
  memoryMB: 8192
  replicas: 3
  enableLoadBalancer: true

上述範例中的設定指定一組可供服務使用的位址。應用程式開發人員在使用者叢集中建立 LoadBalancer 類型的 Service 時,MetalLB 控制器會從這個集區中選擇 IP 位址。

user-cluster-ipblock.yaml

以下 IP 區塊檔案範例顯示使用者叢集工作站節點的 IP 位址指派情形。包括在叢集升級、更新和自動修復期間使用的額外 IP 位址。

blocks:
- netmask: "255.255.255.0"
  gateway: "17.16.40.1"
  ips:
  - ip: 172.16.40.22
    hostname: user-vm-1
  - ip: 172.16.40.23
    hostname: user-vm-2
  - ip: 172.16.40.24
    hostname: user-vm-3
  - ip: 172.16.40.25
    hostname: user-vm-4
  - ip: 172.16.40.26
    hostname: user-vm-5
  - ip: 172.16.40.27
    hostname: user-vm-6

設定 MetalLB

開放防火牆通訊埠

MetalLB 使用 Go memberlist 程式庫進行領導者選舉。memberlist 程式庫會使用 TCP 通訊埠 7946 和 UDP 通訊埠 7946 交換資訊。請確保所有負載平衡器節點都能存取這些通訊埠,以處理傳入和傳出流量。

為新的管理員叢集啟用 MetalLB

管理員叢集設定檔中,將 loadBalancer.kind 設為 "MetalLB"

loadBalancer:
  kind: "MetalLB"

填寫管理員叢集設定檔的其餘部分,然後按照「建立管理員叢集」一文的說明建立管理員叢集。

指定位址集區

MetalLB 控制器會為 Service 指派 IP 位址。應用程式開發人員在使用者叢集中建立 LoadBalancer 類型的服務時,MetalLB 控制器會自動為該服務指派 IP 位址。MetalLB 控制器會從您指定的位址集區中選取 IP 位址。

為確保使用者叢集有足夠的 IP 位址,請考量可能處於啟用狀態的 LoadBalancer 服務數量上限。然後在使用者叢集的設定檔中,於 loadBalancer.metalLB.addressPools 區段指定足夠的 IP 位址。

集區中的位址必須採用 CIDR 格式或範圍格式。如要指定個別地址,請使用 /32 CIDR。例如:

addresses:
  -   "192.0.2.0/26"
  -   "192.0.2.64-192.0.2.72"
  -   "192.0.2.75/32"

如果需要在叢集建立後調整集區中的位址,可以使用 gkectl update cluster。詳情請參閱「更新 MetalLB」。

為新的使用者叢集啟用 MetalLB

使用者叢集設定檔中:

  • loadBalancer.kind 設為 "MetalLB"
  • 為服務指定一或多個位址集區。Ingress VIP 必須位於其中一個集區。
  • 將叢集中至少一個節點集區的 enableLoadBalancer 設為 true。 設為 true 時,這個欄位可讓 MetalLB 揚聲器在集區中的節點上執行。

    請注意,當enableAdvancedCluster設為 true (已啟用進階叢集) 時,enableLoadBalancer欄位的行為有以下差異:在 1.31 版中,如果啟用進階叢集,這個欄位不會有任何作用,因為 MetalLB 揚聲器一律會在使用者叢集的控制層節點上執行。在 1.32 版中,如果啟用進階叢集,這項限制就會移除,您必須指定至少一個要執行 MetalLB 揚聲器的節點集區。

填寫使用者叢集設定檔的其餘部分,然後按照「建立使用者叢集」一文的說明建立使用者叢集。

手動指派服務地址

如不希望 MetalLB 控制器自動將特定集區的 IP 位址指派給 Service,請將集區的 manualAssign 欄位設為 true。接著,開發人員可以建立 LoadBalancer 類型的 Service,然後手動指定集區中的其中一個位址。例如:

loadBalancer:
  metalLB:
    addressPools:
    - name: "my-address-pool-2"
      addresses:
      - "192.0.2.73-192.0.2.80"
      manualAssign: true

避免使用發生錯誤的 IP 位址

如果將位址集區的 avoidBuggyIPs 欄位設為 true,MetalLB 控制器就不會使用結尾為 .0 或 .255 的集區位址。這樣可避免有問題的消費裝置誤將傳送至這些特殊 IP 位址的流量捨棄。例如:

loadBalancer:
  metalLB:
    addressPools:
    - name: "my-address-pool-1"
      addresses:
      - "192.0.2.0/24"
      avoidBuggyIPs: true

建立 LoadBalancer 類型的服務

以下是兩個資訊清單:一個用於 Deployment,另一個用於 Service:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      greeting: hello
  replicas: 3
  template:
    metadata:
      labels:
        greeting: hello
    spec:
      containers:
      - name: hello
        image: gcr.io/google-samples/hello-app:2.0
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  selector:
    greeting: hello
  ports:
  - name: metal-lb-example-port
    protocol: TCP
    port: 60000
    targetPort: 8080

請注意,Service 資訊清單未指定外部 IP 位址。 MetalLB 控制器會從您在使用者叢集設定檔中指定的位址集區,選擇外部 IP 位址。

將資訊清單儲存到名為 my-dep-svc.yaml 的檔案。然後建立 Deployment 和 Service 物件:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-dep-svc.yaml

查看 Service:

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get service my-service --output wide

輸出內容會顯示自動指派給 Service 的外部 IP 位址。例如:

NAME         TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)           AGE   SELECTOR
my-service   LoadBalancer   10.96.2.166   192.0.2.2   60000:31914/TCP   28s

確認指派的外部 IP 位址來自您在使用者叢集設定檔中指定的位址集區。舉例來說,192.0.2.2 位於這個位址集區:

metalLB:
  addressPools:
  - name: "address-pool-1"
    addresses:
     - "192.0.2.0/24"
     - "198.51.100.1-198.51.100.3"

呼叫服務:

curl EXTERNAL_IP_ADDRESS:60000

輸出內容會顯示 Hello, world! 訊息:

Hello, world!
Version: 2.0.0

更新 MetalLB

建立叢集後,您可以更新節點集區中的 MetalLB 位址集區和 enableLoadBalancer 欄位。在使用者叢集設定檔中進行所需變更,然後呼叫 gkectl update cluster

gkectl update cluster --kubeconfig ADMIN_CLUSTER_KUBECONIFG --config USER_CLUSTER_CONFIG

MetalLB Pod 和 ConfigMap

MetalLB 控制器會以 Deployment 形式執行,而 MetalLB 揚聲器則會在集區中的節點上以 DaemonSet 形式執行,且 enableLoadBalancer 設為 true。MetalLB 控制器會管理指派給 Service 的 IP 位址。MetalLB 揚聲器會選出領導者,並公布 Service 虛擬 IP。

查看所有 MetalLB Pod:

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get pods --namespace kube-system --selector app=metallb

您可以使用 MetalLB Pod 的記錄檔排解問題。

MetalLB 設定會以 MetalLB 可辨識的格式儲存在 ConfigMap 中。 請勿直接變更 ConfigMap。請改用先前所述的 gkectl update cluster。如要查看 ConfigMap 以進行疑難排解:

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get configmap metallb-config --namespace kube-system

使用 MetalLB 的優點

  • MetalLB 可直接在叢集節點上執行,不需要額外的 VM。

  • MetalLB 控制器會管理 Service 的 IP 位址,因此您不必為每個 Service 手動選擇 IP 位址。

  • 不同服務的 MetalLB 現用執行個體可以在不同節點上執行。

  • 您可以在不同服務之間共用 IP 位址

MetalLB 與 F5 BIG-IP 和 Seesaw 的比較

  • VIP 必須與叢集節點位於相同的子網路。這也是 Seesaw 的必要條件,但 F5 BIG-IP 則不需要。

  • 沒有流量指標。

  • 沒有無中斷容錯移轉,現有連線會在容錯移轉期間重設。

  • 特定 Service 的 Pod 外部流量會通過執行 MetalLB 揚聲器的單一節點。這表示在 Pod 中執行的容器通常看不到用戶端 IP 位址。