23.4. MetalLB を使用するためのサービスの設定

クラスター管理者は、タイプ LoadBalancer のサービスを追加するときに、MetalLB が IP アドレスを割り当てる方法を制御できます。

23.4.1. 特定の IP アドレスの要求

他のロードバランサーの実装と同様に、MetalLB はサービス仕様の spec.loadBalancerIP フィールドを受け入れます。

要求された IP アドレスが任意のアドレスプールの範囲内にある場合、MetalLB は要求された IP アドレスを割り当てます。要求された IP アドレスが範囲外の場合、MetalLB は警告を報告します。

特定の IP アドレスのサービス YAML の例

apiVersion: v1
kind: Service
metadata:
  name: <service_name>
  annotations:
    metallb.universe.tf/address-pool: <address_pool_name>
spec:
  selector:
    <label_key>: <label_value>
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
  type: LoadBalancer
  loadBalancerIP: <ip_address>

MetalLB が要求された IP アドレスを割り当てることができない場合、サービスの EXTERNAL-IP<pending> を報告し、oc describe service <service_name> の実行には、以下の例のようなイベントが含まれます。

MetalLB が要求された IP アドレスを割り当てることができない場合のイベントの例

  ...
Events:
  Type     Reason            Age    From                Message
  ----     ------            ----   ----                -------
  Warning  AllocationFailed  3m16s  metallb-controller  Failed to allocate IP for "default/invalid-request": "4.3.2.1" is not allowed in config

23.4.2. 特定のプールからの IP アドレスの要求

特定の範囲から IP アドレスを割り当てても、特定の IP アドレスを気にしない場合は、metallb.universe.tf/address-pool アノテーションを使用して、指定したアドレスプールから IP アドレスを要求できます。

特定プールからの IP アドレスのサービス YAML の例

apiVersion: v1
kind: Service
metadata:
  name: <service_name>
  annotations:
    metallb.universe.tf/address-pool: <address_pool_name>
spec:
  selector:
    <label_key>: <label_value>
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
  type: LoadBalancer

<address_pool_name> に指定するアドレスプールが存在しない場合、MetalLB は、自動割り当てを許可する任意のプールから IP アドレスを割り当てようとします。

23.4.3. 任意の IP アドレスを許可します。

デフォルトでは、アドレスプールは自動割り当てを許可するように設定されます。MetalLB は、これらのアドレスプールから IP アドレスを割り当てます。

自動割り当て用に設定されたプールから IP アドレスを受け入れるには、特別なアノテーションや設定は必要ありません。

任意の IP アドレスを受け入れるサービス YAML の例

apiVersion: v1
kind: Service
metadata:
  name: <service_name>
spec:
  selector:
    <label_key>: <label_value>
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP
  type: LoadBalancer

23.4.4. 特定の IP アドレスを共有

デフォルトでは、サービスは IP アドレスを共有しません。ただし、単一の IP アドレスにサービスを配置する必要がある場合は、metallb.universe.tf/allow-shared-ip アノテーションをサービスに追加することで、選択的な IP 共有を有効にできます。

apiVersion: v1
kind: Service
metadata:
  name: service-http
  annotations:
    metallb.universe.tf/address-pool: doc-example
    metallb.universe.tf/allow-shared-ip: "web-server-svc"  1
spec:
  ports:
    - name: http
      port: 80  2
      protocol: TCP
      targetPort: 8080
  selector:
    <label_key>: <label_value>  3
  type: LoadBalancer
  loadBalancerIP: 172.31.249.7  4
---
apiVersion: v1
kind: Service
metadata:
  name: service-https
  annotations:
    metallb.universe.tf/address-pool: doc-example
    metallb.universe.tf/allow-shared-ip: "web-server-svc"  5
spec:
  ports:
    - name: https
      port: 443  6
      protocol: TCP
      targetPort: 8080
  selector:
    <label_key>: <label_value>  7
  type: LoadBalancer
  loadBalancerIP: 172.31.249.7  8
1 5
metallb.universe.tf/allow-shared-ip アノテーションに同じ値を指定します。この値は共有キーと呼ばれます。
2 6
サービスに異なるポート番号を指定します。
3 7
externalTrafficPolicy: local を指定し、サービスが同じ Pod のセットにトラフィックを送信できるようにするために、同じ Pod セレクターを指定します。cluster の外部トラフィックポリシーを使用する場合、Pod セレクターは同じである必要はありません。
4 8
オプション: 上記の 3 つの項目を指定すると、MetalLB は同じ IP アドレスにサービスを配置する場合があります。サービスが IP アドレスを共有することを確認するには、共有する IP アドレスを指定します。

デフォルトで、Kubernetes はマルチプロトコルロードバランサーサービスを許可しません。この制限は通常、TCP と UDP の両方をリッスンする必要がある DNS などのサービスを実行できなくなります。MetalLB を使用して Kubernetes のこの制限を回避するには、2 つのサービスを作成します。

  • 1 つのサービスには TCP を指定し、2 番目のサービスには UDP を指定します。
  • 両方のサービスで、同じ Pod セレクターを指定します。
  • 同じ共有キーと spec.loadBalancerIP 値を指定して、TCP サービスと UDP サービスを同じ IP アドレスに配置します。

23.4.5. MetalLB を使用したサービスの設定

アドレスプールから外部 IP アドレスを使用するように、負荷分散サービスを設定することができます。

前提条件

  • OpenShift CLI (oc) がインストールされている。
  • MetalLB Operator をインストールして、MetalLB を起動します。
  • 1 つ以上のアドレスプールを設定します。
  • トラフィックをクライアントからクラスターのホストネットワークにルーティングするようにネットワークを設定します。

手順

  1. <service_name>.yaml ファイルを作成します。このファイルで、spec.type フィールドが LoadBalancer に設定されていることを確認します。

    MetalLB がサービスに割り当てる外部 IP アドレスを要求する方法については、例を参照してください。

  2. サービスを作成します。

    $ oc apply -f <service_name>.yaml

    出力例

    service/<service_name> created

検証

  • サービスを記述します。

    $ oc describe service <service_name>

    出力例

    Name:                     <service_name>
    Namespace:                default
    Labels:                   <none>
    Annotations:              metallb.universe.tf/address-pool: doc-example  <.>
    Selector:                 app=service_name
    Type:                     LoadBalancer  <.>
    IP Family Policy:         SingleStack
    IP Families:              IPv4
    IP:                       10.105.237.254
    IPs:                      10.105.237.254
    LoadBalancer Ingress:     192.168.100.5  <.>
    Port:                     <unset>  80/TCP
    TargetPort:               8080/TCP
    NodePort:                 <unset>  30550/TCP
    Endpoints:                10.244.0.50:8080
    Session Affinity:         None
    External Traffic Policy:  Cluster
    Events:  <.>
      Type    Reason        Age                From             Message
      ----    ------        ----               ----             -------
      Normal  nodeAssigned  32m (x2 over 32m)  metallb-speaker  announcing from node "<node_name>"

    <.> 特定のプールから IP アドレスを要求すると、アノテーションが表示されます。<.> サービスタイプは LoadBalancer を示す必要があります。<.> サービスが正しく割り当てられている場合、ロードバランサーの Ingress フィールドは外部 IP アドレスを示します。<.> events フィールドは、外部 IP アドレスを通知するために割り当てられたノード名を示します。エラーが発生した場合、events フィールドはエラーの理由を示します。