クラシック: NLB 2.0 による DSR ロード・バランシングのセットアップ

バージョン 2.0 NLB はクラシック・クラスターでのみ作成でき、VPC クラスターでは作成できません。 VPC クラスターでロード・バランシングを行うには、VPC ロード・バランサーを使用したアプリの公開を参照してください。

ポートを公開し、レイヤー 4 のネットワーク・ロード・バランサー (NLB) のポータブル IP アドレスを使用してコンテナー化アプリに公開します。 バージョン 2.0 NLB について詳しくは、NLB 2.0 のコンポーネントおよびアーキテクチャーを参照してください。

前提条件

既存のバージョン 1.0 NLB を 2.0 に更新することはできません。 新規 NLB 2.0 を作成する必要があります。 1.0 および 2.0 のNLBを、クラスタ内で同時に実行することができます。 NLB 2.0 を使用するには、クラスターで Red Hat OpenShift バージョン 4 を実行する必要があります。

NLB 2.0 を作成する前に、前提条件として次の手順を実行する必要があります。

  1. NLB 2.0 で複数ゾーン内のアプリ・ポッドに要求を転送できるようにするには、サポート Case を開いて VLAN の容量集約を要求します。 この構成設定によって、ネットワークの中断や障害が発生することはありません。

    1. IBM Cloud コンソール にログインします。
    2. メニュー・バーの**「サポート」をクリックし、「Case の管理」タブをクリックして、「新規 Case の作成 (Create new case)」**をクリックします。
    3. Case フィールドに、以下の情報を入力します。 トピック:ネットワーク - プロビジョニング サブトピック:クラシック - VLAN
    4. 説明に Please set up the network to allow capacity aggregation on the public and private VLANs associated with my account. This is related to /docs/openshift?topic=openshift-loadbalancer-v2#ipvs_provision, and is needed so I can configure NLB v2.0 LoadBalancers in my Classic Kubernetes Cluster. という情報を追加します。 特定の VLAN (1 つのクラスターのみに対するパブリック VLAN など) について容量集約を許可する場合は、説明でこれらの VLAN ID を指定できます。
    5. **「送信」**をクリックします。
  2. IBM Cloud インフラストラクチャー・アカウントの仮想ルーター機能 (VRF) を有効にする必要があります。 VRF を有効にするには、VRF の有効化を参照してください。 VRF が既に有効になっているかどうかを確認するには、ibmcloud account show コマンドを使用します。 VRF を有効にできない、または有効にしない場合は、VLAN スパンニングを有効にします。 VRF または VLAN スパンニングが有効になると、NLB 2.0 は、アカウント内のさまざまなサブネットにパケットをルーティングできるようになります。

  3. Calico pre-DNAT ネットワーク・ポリシーを使用して NLB 2.0 へのトラフィックを管理する場合は、applyOnForward: true フィールドと doNotTrack: true フィールドをポリシーの spec セクションに追加し、preDNAT: true を削除する必要があります。applyOnForward: true は、トラフィックがカプセル化されて転送されるときに、Calico ポリシーが適用されるようにします。doNotTrack: true は、ワーカー・ノードが DSR を使用して接続を追跡する必要なしに、応答パケットをクライアントに直接返せるようにします。 例えば、Calico ポリシーを使用して特定の IP アドレスから NLB IP アドレスへのトラフィックのみを許可する場合、ポリシーは以下のようになります。

    apiVersion: projectcalico.org/v3
    kind: GlobalNetworkPolicy
    metadata:
      name: allowlist
    spec:
      applyOnForward: true
      doNotTrack: true
      ingress:
      - action: Allow
        destination:
          nets:
          - <loadbalancer_IP>/32
          ports:
          - 80
        protocol: TCP
        source:
          nets:
          - <client_address>/32
      selector: ibm.role=='worker_public'
      order: 500
      types:
      - Ingress
    

次は、複数ゾーン・クラスターでの NLB 2.0 のセットアップまたは単一ゾーン・クラスターでの NLB 2.0 のセットアップの手順に従ってください。

複数ゾーン・クラスターでの NLB 2.0 のセットアップ

開始前に

先に進む前に、 NLBの「 2.0 」の前提条件 を満たしておいてください。

  • パブリック NLB を複数のゾーンに作成するためには、ゾーンごとに 1 つ以上のパブリック VLAN にポータブル・サブネットを用意する必要があります。 プライベート NLB を複数のゾーンに作成するためには、ゾーンごとに 1 つ以上のプライベート VLAN にポータブル・サブネットを用意する必要があります。 クラスター用のサブネットの構成に記載されているステップに従うことにより、サブネットを追加できます。

  • default ネームスペース用の「 作家 または、 マネージャー IBM Cloud IAM サービスのアクセスロール 」がインストールされていることを確認してください。

  • 必要な数のワーカー・ノードがあることを確認します。

    • クラシック・クラスター: ネットワーク・トラフィックをエッジ・ワーカー・ノードに制限する場合は、NLB が均等にデプロイされるように、各ゾーンで 2 つ以上のエッジ・ワーカー・ノードを有効にしてください。
  • クラスター・ノードが再ロードされるか、クラスター・マスターの更新に新しい keepalived イメージが含まれる場合、ロード・バランサーの仮想 IP は新しいノードのネットワーク・インターフェースに移動されます。 これが発生した場合は、ロード・バランサーへの長期接続を再確立する必要があります。 接続の再確立が迅速に行われるよう、アプリケーションに再試行ロジックを組み込むことを検討してください。

複数ゾーン・クラスターで NLB 2.0 をセットアップするには、次の手順を実行します。

  1. アプリをクラスターにデプロイします。 構成ファイルの metadata セクションで、デプロイメントにラベルを追加しておく必要があります。 このカスタム・ラベルにより、アプリが実行されるすべてのポッドが識別されてロード・バランシングに含められます。

  2. パブリック・インターネットまたはプライベート・ネットワークに公開するアプリのロード・バランサー・サービスを作成します。

    1. myloadbalancer.yaml などの名前のサービス構成ファイルを作成します。
    2. 公開するアプリのロード・バランサー・サービスを定義します。 ゾーン、VLAN、および IP アドレスを指定できます。
        apiVersion: v1
        kind: Service
        metadata:
          name: myloadbalancer
          annotations:
            service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: <public_or_private>
            service.kubernetes.io/ibm-load-balancer-cloud-provider-zone: "<zone>"
            service.kubernetes.io/ibm-load-balancer-cloud-provider-vlan: "<vlan_id>"
            service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "ipvs"
            service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler: "<algorithm>"
        spec:
          type: LoadBalancer
          selector:
            <selector_key>: <selector_value>
          ports:
           - protocol: TCP
             port: 8080
             targetPort: 8080 # Optional. By default, the `targetPort` is set to match the `port` value unless specified otherwise.
          loadBalancerIP: <IP_address>
          externalTrafficPolicy: Local
        ```
        `service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type`
        :   `private` または `public` ロード・バランサーを指定するアノテーション。
    
        `service.kubernetes.io/ibm-load-balancer-cloud-provider-zone`
        :   ロード・バランサー・サービスのデプロイ先のゾーンを指定するアノテーション。 ゾーンを表示するには、`ibmcloud oc zone ls` を実行します。
    
        `service.kubernetes.io/ibm-load-balancer-cloud-provider-vlan`
        :   ロード・バランサー・サービスのデプロイ先の VLAN を指定するアノテーション。 VLAN を表示するには、`ibmcloud oc vlan ls --zone ZONE` を実行します。
    
        `service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "ipvs"`
        :   バージョン 2.0 のロード・バランサーを指定するアノテーション。
    
        `service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler`
        :   オプション: スケジューリング・アルゴリズムを指定するアノテーション。 指定可能な値は、ラウンドロビン(デフォルト)の場合は ` `"rr"` `、ソースハッシュの場合は ` `"sh"` ` です。 詳しくは、[2.0: スケジューリング・アルゴリズム](#scheduling)を参照してください。
    
        `selector`
        :   アプリ・デプロイメント YAML  `<selector_key>` セクションで使用したラベル・キー (`<selector_value>`) と値 (`spec.template.metadata.labels`)。
    
        `port`
        :   サービスが listen するポート。
    
        `loadBalancerIP`
        :   オプション: プライベート NLB を作成するには、またはパブリック NLB 用に特定のポータブル IP アドレスを使用するには、使用する IP アドレスを指定します。 IP アドレスは、アノテーションで指定するゾーンと VLAN になければなりません。 IP アドレスを指定しない場合:
            :   クラスターがパブリック VLAN 上にある場合、ポータブル・パブリック IP アドレスが使用されます。 ほとんどのクラスターはパブリック VLAN 上にあります。
            :   クラスターがプライベート VLAN 上にのみ存在する場合は、ポータブル・プライベート IP アドレスが使用されます。
    
        `externalTrafficPolicy: Local`
        :   `Local` に設定します。
    
    
        `dal12` で、ラウンドロビン方式のスケジューリングアルゴリズムを使用する NLB 2.0 サービスを作成するための設定ファイルの例:
    
        ```yaml {: codeblock}
        apiVersion: v1
        kind: Service
        metadata:
          name: myloadbalancer
          annotations:
            service.kubernetes.io/ibm-load-balancer-cloud-provider-zone: "dal12"
            service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "ipvs"
            service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler: "rr"
        spec:
          type: LoadBalancer
          selector:
            app: nginx
          ports:
           - protocol: TCP
             port: 8080
             targetPort: 8080 # Optional. By default, the `targetPort` is set to match the `port` value unless specified otherwise.
          externalTrafficPolicy: Local
        ```
    3. オプション:「 `spec.loadBalancerSourceRanges` 」フィールドにIPアドレスを指定することで、NLBサービスを特定のIPアドレス範囲に限定して利用可能にすることができます。「 `loadBalancerSourceRanges` 」は、クラスター内の `kube-proxy` によって、ワーカーノード上のiptablesルールを使用して実装されます。 詳細については、『 [Kubernetes 』のドキュメント](https://kubernetes.io/docs/concepts/services-networking/){: external}を参照してください。
    
    4. クラスター内にサービスを作成します。
    
    ```sh {: pre}
        oc apply -f myloadbalancer.yaml
        ```
    
  3. NLB サービスが正常に作成されたことを確認します。 NLB サービスが適切に作成され、アプリが利用可能になるまでに数分かかることがあります。

    oc describe service myloadbalancer
    

    出力例:

    NAME:                   myloadbalancer
    Namespace:              default
    Labels:                 <none>
    Selector:               app=liberty
    Type:                   LoadBalancer
    Zone:                   dal10
    IP:                     172.21.xxx.xxx
    LoadBalancer Ingress:   169.xx.xxx.xxx
    Port:                   <unset> 8080/TCP
    NodePort:               <unset> 32040/TCP
    Endpoints:              172.30.xxx.xxx:8080
    Session Affinity:       None
    Events:
        FirstSeen    LastSeen    Count    From            SubObjectPath    Type     Reason                      Message
        ---------    --------    -----    ----            -------------    ----     ------                      -------
        10s            10s            1        {service-controller }      Normal CreatingLoadBalancer    Creating load balancer
        10s            10s            1        {service-controller }        Normal CreatedLoadBalancer    Created load balancer
    

    LoadBalancer Ingress IP アドレスは、NLB サービスに割り当てられたポータブル・パブリック IP アドレスです。

  4. パブリック NLB を作成した場合、インターネットからアプリにアクセスします。

    1. 任意の Web ブラウザーを開きます。
    2. NLB のポータブル・パブリック IP アドレスとポートを入力します。
        http://169.xx.xxx.xxx:8080
        ```
    
  5. 高可用性を実現するには、手順 2~4 を繰り返し、アプリケーションインスタンスが存在する各ゾーンに NLB 2.0 を追加してください。

  6. オプション: NLB サービスは、サービスの NodePort を介してアプリを使用できるようにします。 NodePort には、クラスター内のすべてのノードのすべてのパブリック IP アドレスおよびプライベート IP アドレスでアクセスできます。 NLB サービスを使用しつつ、NodePort へのトラフィックをブロックするには、ロード・バランサー・サービスまたはノード・ポート・サービスへのインバウンド・トラフィックの制御を参照してください。

次に、NLB サブドメインを登録できます。

単一ゾーン・クラスターでの NLB 2.0 のセットアップ

開始前に

先に進む前に、 NLBの「 2.0 」の前提条件 を満たしておいてください。

  • NLB サービスに割り当てることのできるポータブル・パブリック IP アドレスまたはポータブル・プライベート IP アドレスが必要です。 詳しくは、クラスター用のサブネットの構成を参照してください。

  • default ネームスペース用の「 作家 または、 マネージャー IBM Cloud IAM サービスのアクセスロール 」がインストールされていることを確認してください。

  • クラスター・ノードが再ロードされるか、クラスター・マスターの更新に新しい keepalived イメージが含まれる場合、ロード・バランサーの仮想 IP は新しいノードのネットワーク・インターフェースに移動されます。 これが発生した場合は、ロード・バランサーへの長期接続を再確立する必要があります。 接続の再確立が迅速に行われるよう、アプリケーションに再試行ロジックを組み込むことを検討してください。

単一ゾーン・クラスターで NLB 2.0 サービスを作成するには、以下のようにします。

  1. アプリをクラスターにデプロイします。 デプロイメント構成ファイルの metadata セクションに、ラベルを追加しておく必要があります。 このカスタム・ラベルにより、アプリが実行されるすべてのポッドが識別されてロード・バランシングに含められます。

  2. パブリック・インターネットまたはプライベート・ネットワークに公開するアプリのロード・バランサー・サービスを作成します。

    1. myloadbalancer.yaml などの名前のサービス構成ファイルを作成します。

    2. 公開するアプリのロード・バランサー 2.0 サービスを定義します。

        apiVersion: v1
        kind: Service
        metadata:
          name: myloadbalancer
          annotations:
            service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: <public_or_private>
            service.kubernetes.io/ibm-load-balancer-cloud-provider-vlan: "<vlan_id>"
            service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "ipvs"
            service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler: "<algorithm>"
        spec:
          type: LoadBalancer
          selector:
            <selector_key>: <selector_value>
          ports:
           - protocol: TCP
             port: 8080
             targetPort: 8080 # Optional. By default, the `targetPort` is set to match the `port` value unless specified otherwise.
          loadBalancerIP: <IP_address>
          externalTrafficPolicy: Local
        ```
        `service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type`
        :   `private` または `public` ロード・バランサーを指定するアノテーション。
    
        `service.kubernetes.io/ibm-load-balancer-cloud-provider-vlan`
        :   オプション: ロード・バランサー・サービスのデプロイ先の VLAN を指定するアノテーション。 VLAN を表示するには、`ibmcloud oc vlan ls --zone ZONE` を実行します。
    
        `service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "ipvs"`
        :   ロード・バランサー 2.0 を指定するアノテーション。
    
        `service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler`
        :   オプション: スケジューリング・アルゴリズムを指定するアノテーション。 指定可能な値は、ラウンドロビン(デフォルト)の場合は ` `"rr"` `、ソースハッシュの場合は ` `"sh"` ` です。 詳しくは、[2.0: スケジューリング・アルゴリズム](#scheduling)を参照してください。
    
    
        `selector`
        :   アプリ・デプロイメント YAML  `<selector_key>` セクションで使用したラベル・キー (`<selector_value>`) と値 (`spec.template.metadata.labels`)。
    
    
        `port`
        :   サービスが listen するポート。
    
    
        `loadBalancerIP`
        :   オプション: プライベート NLB を作成するには、またはパブリック NLB 用に特定のポータブル IP アドレスを使用するには、使用する IP アドレスを指定します。 IP アドレスは、アノテーションで指定する VLAN 上になければなりません。 IP アドレスを指定しない場合:
            - クラスターがパブリック VLAN 上にある場合、ポータブル・パブリック IP アドレスが使用されます。 ほとんどのクラスターはパブリック VLAN 上にあります。
            - クラスターがプライベート VLAN 上にのみ存在する場合は、ポータブル・プライベート IP アドレスが使用されます。
    
    
        `externalTrafficPolicy: Local`
        :   `Local` に設定します。
    
    3. オプション:「 `spec.loadBalancerSourceRanges` 」フィールドにIPアドレスを指定することで、NLBサービスを特定のIPアドレス範囲に限定して利用可能にすることができます。「 `loadBalancerSourceRanges` 」は、クラスター内の `kube-proxy` によって、ワーカーノード上のiptablesルールを使用して実装されます。 詳細については、『 [Kubernetes 』のドキュメント](https://kubernetes.io/docs/concepts/services-networking/){: external}を参照してください。
    
    4. クラスター内にサービスを作成します。
    
    ```sh {: pre}
        oc apply -f myloadbalancer.yaml
        ```
    
  3. NLB サービスが正常に作成されたことを確認します。 サービスが作成され、アプリが利用可能になるまでに数分かかることがあります。

    oc describe service myloadbalancer
    

    出力例:

    NAME:                   myloadbalancer
    Namespace:              default
    Labels:                 <none>
    Selector:               app=liberty
    Type:                   LoadBalancer
    Location:               dal10
    IP:                     172.21.xxx.xxx
    LoadBalancer Ingress:   169.xx.xxx.xxx
    Port:                   <unset> 8080/TCP
    NodePort:               <unset> 32040/TCP
    Endpoints:              172.30.xxx.xxx:8080
    Session Affinity:       None
    Events:
        FirstSeen    LastSeen    Count    From            SubObjectPath    Type     Reason                      Message
        ---------    --------    -----    ----            -------------    ----     ------                      -------
        10s            10s            1        {service-controller }      Normal CreatingLoadBalancer    Creating load balancer
        10s            10s            1        {service-controller }        Normal CreatedLoadBalancer    Created load balancer
    

    LoadBalancer Ingress IP アドレスは、NLB サービスに割り当てられたポータブル・パブリック IP アドレスです。

  4. パブリック NLB を作成した場合、インターネットからアプリにアクセスします。

    1. 任意の Web ブラウザーを開きます。
    2. NLB のポータブル・パブリック IP アドレスとポートを入力します。
        http://169.xx.xxx.xxx:8080
        ```
    
  5. オプション: NLB サービスは、サービスの NodePort を介してアプリを使用できるようにします。 NodePort には、クラスター内のすべてのノードのすべてのパブリック IP アドレスおよびプライベート IP アドレスでアクセスできます。 NLB サービスを使用しつつ、NodePort へのトラフィックをブロックするには、ロード・バランサー・サービスまたはノード・ポート・サービスへのインバウンド・トラフィックの制御を参照してください。

次に、NLB サブドメインを登録できます。

スケジューリング・アルゴリズム

NLB 2.0 がネットワーク接続をアプリ・ポッドにどのように割り当てるかは、スケジューリング・アルゴリズムによって決まります。 クライアント要求がクラスターに到着すると、NLB は、スケジューリング・アルゴリズムに基づいて要求パケットをワーカー・ノードにルーティングします。 スケジューリングアルゴリズムを使用するには、NLB サービス設定ファイルのスケジューラ注釈で、その Keepalived という短縮名を指定してください: service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler: "rr"。 以下のリストで、Red Hat OpenShift on IBM Cloud でサポートされるスケジューリング・アルゴリズムを確認してください。 スケジューリングアルゴリズムを指定しない場合、デフォルトではラウンドロビンアルゴリズムが使用されます。 詳細については、 Keepalivedのドキュメントを参照してください。

サポートされるスケジューリング・アルゴリズム

ラウンドロビン (rr)
NLB は、ワーカー・ノードに接続をルーティングするときにアプリ・ポッドのリストを循環し、各アプリ・ポッドを同等に扱います。 ラウンドロビンは、バージョン 2.0 NLB のデフォルトのスケジューリング・アルゴリズムです。
ソース・ハッシュ (sh)
NLB は、クライアント要求パケットのソース IP アドレスに基づいてハッシュ・キーを生成します。 次に NLB は、静的に割り当てられたハッシュ・テーブルでそのハッシュ・キーを検索し、該当範囲のハッシュを処理するアプリ・ポッドに要求をルーティングします。 このアルゴリズムにより、特定のクライアントからの要求は常に同じアプリ・ポッドに送信されるようになります。 Kubernetes は、Iptables ルールを使用します。これにより、ワーカー上のランダム・ポッドに要求が送信されます。 このスケジューリング・アルゴリズムを使用するには、ワーカー・ノード 1 つにつきアプリ・ポッドが 1 つのみデプロイされるようにする必要があります。 例えば、各ポッドのラベルが run=<app_name> である場合は、アプリ・デプロイメントの spec セクションに以下のアンチアフィニティー・ルールを追加します:
spec:
  affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: run
            operator: In
            values:
            - <APP_NAME>
        topologyKey: kubernetes.io/hostname

サポートされないスケジューリング・アルゴリズム

宛先ハッシュ (dh)
パケットの宛先 (NLB の IP アドレスとポート) を使用して、着信要求を処理するワーカー・ノードが決定されます。 ただし、Red Hat OpenShift on IBM Cloud 内の NLB の IP アドレスとポートは変わりません。 NLB が存在するワーカー・ノードから要求が出ていかず、1 つのワーカー上のアプリ・ポッドのみがすべての着信要求を処理することになります。
動的接続カウント・アルゴリズム
以下のアルゴリズムは、クライアントと NLB の間の動的な接続数に基づくものです。 しかし、直接サービス・リターン (DSR) では NLB 2.0 のポッドがパケットのリターン・パスに含まれないため、NLB は確立された接続を追跡しません。
  • 最小接続数 (lc)
  • 局所性ベースの最小接続 (lblc)
  • レプリケーションによる局所性ベースの最小接続 (lblcr)
  • キューなし (nq)
  • 最短予想遅延 (seq)
加重型ポッド・アルゴリズム
以下のアルゴリズムは、重みづけされたアプリ・ポッドに基づくものです。 しかし、Red Hat OpenShift on IBM Cloud のロード・バランシングでは、すべてのアプリ・ポッドに等しい重みが割り当てられます。
  • 重み付き最小接続 (wlc)
  • 重み付きラウンドロビン (wrr)