MetalLB によるバンドルされたロード バランシング

このドキュメントでは、MetalLB ロードバランサによるバンドル型ロード バランシングを使用するように Google Distributed Cloud を構成する方法を説明します。このページは、組織のネットワークを設計し、ネットワーク機器の設置、構成、サポートを行うネットワーク スペシャリストを対象としています。Google Cloud のコンテンツで参照する一般的なロールとタスク例の詳細については、一般的な GKE Enterprise ユーザーのロールとタスクをご覧ください。

Google Distributed Cloud では、MetalLB はレイヤ 2 モードで実行されます。

MetalLB 構成の例

MetalLB ロードバランサを実行するクラスタの構成例を以下に示します。

MetalLB ロードバランサの構成。
MetalLB ロードバランサの構成

上の図は、MetalLB のデプロイを示しています。MetalLB は、クラスタノードで直接実行されます。この例では、管理クラスタとユーザー クラスタが 2 つの別々の 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

以下のユーザー クラスタの構成ファイルは、次の構成を示しています。

  • 選択して LoadBalancer タイプの Service に割り当てる、MetalLB コントローラのアドレスプール。Ingress VIP はこのプールにあります。

  • ユーザー クラスタの Kubernetes API サーバー用に指定された VIP と、Ingress プロキシ用に構成するように選択した 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

上記の構成例では、Service に使用できるアドレスのセットが指定されています。アプリケーション デベロッパーがユーザー クラスタに 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 タイプの Service を作成する際に、Service の IP アドレスを手動で指定する必要はありません。代わりに MetalLB コントローラが、クラスタ作成時に指定されたアドレスプールから IP アドレスを選択します。

ユーザー クラスタで常にアクティブである可能性が高い、LoadBalancer タイプの Service の数を考慮します。次に、ユーザー クラスタの構成ファイルの loadBalancer.metalLB.addressPools セクションで、それらの Service に対応する十分な IP アドレスを指定します。

ユーザー クラスタの Ingress VIP は、アドレスプールで指定したアドレス内にある必要があります。これは、Ingress プロキシが LoadBalancer タイプの Service によって公開されるためです。

アプリケーション デベロッパーが LoadBalancer タイプの Service を作成する必要がない場合は、Ingress VIP 以外のアドレスを指定する必要はありません。

アドレスは 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" に設定します。
  • Service のアドレスプールを 1 つ以上指定します。Ingress VIP をプールの 1 つに含める必要があります。
  • クラスタ内の少なくとも 1 つのノードプールで、enableLoadBalancertrue に設定します。

ユーザー クラスタ構成ファイルの残りの部分を入力し、ユーザー クラスタを作成するの説明のとおりにユーザー クラスタを作成します。

サービス アドレスの手動割り当て

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 に設定すると、末尾が .0 または .255 のプールのアドレスは、MetalLB コントローラでは使用されなくなります。これにより、バグの多いコンシューマ デバイスが、これらの特別な IP アドレスに送信されたトラフィックを誤って破棄するという問題を回避できます。次に例を示します。

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

LoadBalancer タイプの Service を作成する

以下は、Deployment と Service の 2 つのマニフェストです。

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"

Service を呼び出します。

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 スピーカーは、enableLoadBalancertrue に設定されているプール内のノードで DaemonSet として実行されます。MetalLB コントローラは、Service に割り当てられた IP アドレスを管理します。MetalLB スピーカーはリーダー選出を行い、Service VIP を通知します。

すべての 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 アドレスを選択する必要はありません。

  • 異なる Service の MetalLB のアクティブなインスタンスを複数のノードで実行できます。

  • 異なる Service 間でIP アドレスを共有できます。

MetalLB と F5 BIG-IP および Seesaw との比較

  • VIP はクラスタノードと同じサブネット内に存在する必要があります。この要件は Seesaw にもありますが、F5 BIG-IP にはありません。

  • トラフィックの指標はありません。

  • ヒットレス フェイルオーバーは発生しません。既存の接続がフェイルオーバー中にリセットされます。

  • 特定の Service の Pod への外部トラフィックは、MetalLB スピーカーを実行している 1 つのノードを通過します。つまり、通常、クライアント IP アドレスは Pod で実行されているコンテナには認識されません。