

 **このページの改善にご協力ください** 

このユーザーガイドに貢献するには、すべてのページの右側のペインにある「**GitHub でこのページを編集する**」リンクを選択してください。

# Network Load Balancer を使用して TCP および UDP トラフィックをルーティングする
<a name="network-load-balancing"></a>

**注記**  
 **新規:** Amazon EKS Auto Mode は、ロードバランシングの定型作業を自動化します。詳細については、以下を参照してください。  
 [サンプルロードバランサーワークロードを EKS 自動モードl にデプロイする](auto-elb-example.md) 
 [サービス注釈を使用して Network Load Balancer を設定する](auto-configure-nlb.md) 

ネットワークトラフィックは、OSI モデルの `L4` で負荷分散されます。`L7` でアプリケーショントラフィックの負荷を分散するには、Kubernetes `ingress` をデプロイし、これによって AWS Application Load Balancer をプロビジョニングします。詳細については、「[Application Load Balancer を使用してアプリケーションと HTTP トラフィックをルーティングする](alb-ingress.md)」を参照してください。2 種類の負荷分散の違いについては、AWS ウェブサイトの「[Elastic Load Balancing の特徴](https://aws.amazon.com/elasticloadbalancing/features/)」を参照してください。

タイプ `LoadBalancer` の Kubernetes `Service` を作成する際、デフォルトでは、AWS クラウドプロバイダーロードバランサーコントローラーにより AWS [Classic Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/introduction.html) が作成されますが、AWS [Network Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html) も作成できます。このコントローラーは、将来の重大なバグ修正のみを受けています。AWS クラウドプロバイダーのロードバランサーの使い方については、Kubernetes ドキュメントの「[AWS cloud provider load balancer controller](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer)」を参照してください。使用方法については、このトピックでは説明しません。

AWS クラウドプロバイダーロードバランサーコントローラーの代わりに、[AWS ロードバランサーコントローラー](aws-load-balancer-controller.md) のバージョン `2.7.2` 以降を使用することをお勧めします。AWS Load Balancer Controller では、AWS Network Load Balancer は作成できますが、AWS Classic Load Balancer は作成できません。このトピックの残りの部分では、AWS Load Balancer Controller の使用について説明します。

AWS Network Load Balancer では、Amazon EC2 IP およびインスタンス[ターゲット](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#target-type)、AWS Fargate IP ターゲット、または IP ターゲットとして Amazon EKS Hybrid Nodes にデプロイされた Pod にネットワークトラフィックを負荷分散できます。詳細については、GitHub の [AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/targetgroupbinding/targetgroupbinding/#targettype) を参照してください。

## 前提条件
<a name="_prerequisites"></a>

AWS Load Balancer Controller を使用してネットワークトラフィックの負荷分散を行うには、次の要件を満たす必要があります。
+ 既存のクラスターがある。既存のクラスターがない場合は、「[Amazon EKS の使用を開始する](getting-started.md)」を参照してください。既存のクラスターのバージョンを更新する必要がある場合は、[既存のクラスターを新しい Kubernetes バージョンに更新する](update-cluster.md) を参照して下さい。
+ クラスターに AWS Load Balancer Controller がデプロイされている。詳細については、「[AWS Load Balancer Controller を使用してインターネットトラフィックをルーティングする](aws-load-balancer-controller.md)」を参照してください。バージョン `2.7.2` 以降をお勧めします。
+ 少なくとも 1 つのサブネット。アベイラビリティーゾーンで複数のタグ付きサブネットが見つかった場合、コントローラーは、サブネット ID が辞書式順序で最初に来る最初のサブネットを選択します。サブネットには、利用可能な IP アドレスが最低 8 個必要です。
+ AWS Load Balancer Controller バージョン `2.1.1` 以前を使用している場合は、次のようにサブネットにタグ付けする必要があります。バージョン `2.1.2` 以降を使用している場合、このタグはオプションです。同じ VPC 内で複数のクラスターを実行していたり、VPC 内で複数の AWS のサービスがサブネットを共有していたりして、クラスターごとにロードバランサーがプロビジョニングされる場所をより詳細に制御したい場合は、サブネットにタグを付けることができます。サービスオブジェクトのアノテーションとしてサブネット ID を明示的に指定すると、Kubernetes と AWS Load Balancer Controller は、これらのサブネットを直接使用してロードバランサーを作成します。ロードバランサーのプロビジョニングにこの方法を使用することを選択した場合、サブネットのタグ付けは不要です。次のプライベートサブネットおよびパブリックサブネットのタグ付け要件は省略できます。*マイクラスター* の部分は自分のクラスター名に置き換えます。
  +  **キー** – `kubernetes.io/cluster/<my-cluster>` 
  +  **値** – `shared` または `owned` 
+ サービスオブジェクトまたは Ingress オブジェクトのアノテーションとしてサブネット ID を明示的に指定しない場合、パブリックサブネットとプライベートサブネットは次の要件を満たしている必要があります。サービスオブジェクトやイングレスオブジェクトのアノテーションとしてサブネット ID を明示的に指定してロードバランサーをプロビジョニングする場合、Kubernetes と AWS Load Balancer Controller はこれらのサブネットを直接使用してロードバランサーを作成します。次のタグは必要ありません。
  +  **プライベートサブネット** — 次の形式でタグ付けする必要があります。これは、Kubernetes と AWS Load Balancer Controller が、サブネットを内部ロードバランサーに使用できることを認識できるようするためです。`eksctl` または Amazon EKS AWS AWS CloudFormation テンプレートを使用して、2020 年 3 月 26 日以降に VPC を作成する場合、サブネットは、作成時に適切にタグ付けされます。Amazon EKS AWS AWS CloudFormation VPC テンプレートの詳細については、「[Amazon EKS クラスターの Amazon VPC を作成する](creating-a-vpc.md)」を参照してください。
    +  **キー** – `kubernetes.io/role/internal-elb` 
    +  **値** – `1` 
  +  **パブリックサブネット** — 次の形式でタグ付けする必要があります。これは、各アベイラビリティーゾーンでパブリックサブネットを選択するのではなく (サブネット ID の辞書順)、Kubernetes がそれらのサブネットのみを外部ロードバランサーに使用することを認識できるようにするためです。`eksctl` または Amazon EKS AWS CloudFormation テンプレートを使用して、2020 年 3 月 26 日以降に VPC を作成する場合、サブネットは、作成時に適切にタグ付けされます。Amazon EKS AWS CloudFormation VPC テンプレートの詳細については、「[Amazon EKS クラスターの Amazon VPC を作成する](creating-a-vpc.md)」を参照してください。
    +  **キー** – `kubernetes.io/role/elb` 
    +  **値** – `1` 

  サブネットロールタグが明示的に追加されていない場合、Kubernetes サービスコントローラーはクラスター VPC サブネットのルートテーブルを調べて、サブネットがプライベートであるかパブリックであるかを判断します。この動作に頼らず、プライベートまたはパブリックロールタグを明示的に追加することをお勧めします。AWS Load Balancer Controller では、ルートテーブルを検査しないため、自動検出を正常に実行するにはプライベートタグとパブリックタグが必要です。

## 考慮事項
<a name="_considerations"></a>
+ ロードバランサーの設定は、サービス用のマニフェストに追加された注釈により制御されます。AWS Load Balancer Controller を使用する場合のサービスアノテーションは、AWS クラウドプロバイダーロードバランサーコントローラーを使用する場合のサービスアノテーションとは異なります。サービスをデプロイする前に、必ず AWS Load Balancer Controller の[アノテーション](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/service/annotations/)を確認してください。
+ [Amazon VPC CNI plugin for Kubernetes](managing-vpc-cni.md) を使用する場合、AWS Load Balancer Controller は Amazon EC2 の IP ターゲットかインスタンスターゲット、および Fargate の IP ターゲットに負荷分散できます。[互換性のある代替 CNI プラグイン](alternate-cni-plugins.md)を使用する場合、コントローラーはインスタンスターゲットにのみ負荷分散できます (Amazon EKS Hybrid Nodes に負荷分散している場合を除く)。ハイブリッドノードの場合、コントローラーは IP ターゲットを負荷分散できます。Network Load Balancer のターゲットタイプの詳細については、「Network Load Balancer のユーザーガイド」の「[Target type](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#target-type)」(ターゲットタイプ) を参照してください。
+ ロードバランサーの作成時 (または作成後) にタグを追加する場合は、サービス仕様に次のアノテーションを追加します。詳細については、AWS Load Balancer Controller ドキュメントの[AWS リソースタグ](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/service/annotations/#aws-resource-tags)を参照してください。

  ```
  service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags
  ```
+ [Elastic IP アドレス](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html)を Network Load Balancer に割り当てるには、次のアノテーションを追加します。サンプル値を Elastic IP アドレスの `Allocation IDs` に置き換えます。`Allocation IDs` の数は、ロードバランサーに使用されるサブネットの数に一致する必要があります。詳細については、[AWS Load Balancer Controller](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/service/annotations/#eip-allocations) ドキュメントを参照してください。

  ```
  service.beta.kubernetes.io/aws-load-balancer-eip-allocations: eipalloc-xxxxxxxxxxxxxxxxx,eipalloc-yyyyyyyyyyyyyyyyy
  ```
+ Amazon EKS は、クライアントトラフィック用のインバウンドルールをノードのセキュリティグループに 1 つ追加し、VPC 内のロードバランサーのサブネットごとに、作成する各 Network Load Balancer のヘルスチェック用のルールを 1 つずつ追加します。タイプ `LoadBalancer` のサービスの展開は、Amazon EKS が、セキュリティグループに許可されているルールの最大数に対するクォータを超えるルールを作成しようとした場合に失敗することがあります。詳細については、Amazon VPC ユーザーガイドの「[セキュリティグループ](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-security-groups)」を参照してください。セキュリティグループのルールの最大数を超える可能性を最小限に抑えるために、次のオプションを検討します。
  + セキュリティグループクォータあたりのルールの増加をリクエストする。詳細については、Service Quotas ユーザーガイドの「[Requesting a quota increase (クォータの引き上げのリクエスト)](https://docs.aws.amazon.com/servicequotas/latest/userguide/request-quota-increase.html)」を参照してください。
  + インスタンスターゲットではなく IP ターゲットを使用する。IP ターゲットを使用すると、同じターゲットポートでルールを共有できます。ロードバランサーのサブネットは、アノテーションを使用して手動で指定できます。詳細については、GitHub の 「[アノテーション](https://kubernetes-sigs.github.io/aws-load-balancer-controller/latest/guide/service/annotations/)」 を参照してください。
  + タイプ `LoadBalancer` のサービスの代わりにイングレスを使用して、サービスにトラフィックを送信します。AWS Application Load Balancer では、Network Load Balancer よりも必要なルールは少なくなります。複数のイングレス間で ALB を共有できます。詳細については、「[Application Load Balancer を使用してアプリケーションと HTTP トラフィックをルーティングする](alb-ingress.md)」を参照してください。複数のサービス間で Network Load Balancer を共有することはできません。
  + クラスターを複数のアカウントにデプロイする。
+ Pod が Amazon EKS クラスター内の Windows で実行されている場合、ロードバランサーを使用する 1 つのサービスで最大 1,024 個のバックエンド Pod をサポートできます。各ポッドには固有の IP アドレスがあります。
+ 新しい Network Load Balancer の作成には、AWS Load Balancer Controller を使用することをおすすめします。AWS クラウドプロバイダーロードバランサーコントローラーで作成された既存の Network Load Balancer を置き換えようとすると、複数の Network Load Balancer でアプリケーションのダウンタイムを引き起こす可能性があります。

## ネットワークロードバランサーを作成する
<a name="network-load-balancer"></a>

IP またはインスタンスのターゲットを含むネットワークロードバランサーを作成できます。

### Network Load Balancer の作成 — IP ターゲット
<a name="_create_network_load_balancerip_targets"></a>
+ Amazon EC2 ノード、Fargate、または Amazon EKS Hybrid Nodes にデプロイされた Pod で IP ターゲットを使用できます。Kubernetes サービスはタイプ `LoadBalancer` として作成する必要があります。詳細については、Kubernetes ドキュメントの「[Garbage Collecting Load Balancers (ガベージコレクションを行うロードバランサー](https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer)」を参照してください。

  IP ターゲットを使用するロードバランサーを作成するには、次のアノテーションをサービスマニフェストに追加し、サービスをデプロイします。`aws-load-balancer-type` の `external` 値により、AWS クラウドプロバイダーロードバランサーコントローラーではなく、AWS Load Balancer Controller によって Network Load Balancer が作成されます。アノテーション付きの[サンプルサービスマニフェスト](#network-load-balancing-service-sample-manifest)を表示できます。

  ```
  service.beta.kubernetes.io/aws-load-balancer-type: "external"
  service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "ip"
  ```
**注記**  
`IPv6` Pod に負荷分散する場合は、次のアノテーションを追加します。`IPv6` を使用して負荷分散を行えるのは、IP ターゲットにのみです。インスタンスターゲットには行えません。このアノテーションを使用しない場合、負荷分散には `IPv4` が使用されます。

  ```
  service.beta.kubernetes.io/aws-load-balancer-ip-address-type: dualstack
  ```

  デフォルトでは、Network Load Balancer は `internal` `aws-load-balancer-scheme` を使用して作成されます。Network Load Balancer は、クラスターの VPC 内の任意のサブネットで起動できます。これには、クラスターの作成時に指定されていないサブネットも含まれます。

  Kubernetes は、サブネットがパブリックかプライベートかどうかをルートテーブルで調べます。パブリックサブネットには、インターネットゲートウェイを使ったインターネットへの直接の経路がありますが、プライベートサブネットにはありません。

  パブリックサブネットに Network Load Balancer を作成して Amazon EC2 ノードへの負荷分散を行う場合 (Fargate はプライベートのみ可能)、次のアノテーションを付けて `internet-facing` を指定します。

  ```
  service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
  ```
**注記**  
`service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip"` アノテーションは、下位互換性のために引き続きサポートされています。ただし、新しいロードバランサーには、`service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip"` の代わりに以前のアノテーションを使用することをお勧めします。
**重要**  
サービスの作成後は、このアノテーションを編集しないでください。変更する必要がある場合は、サービスオブジェクトを削除し、このアノテーションを希望する値にして再度作成します。

### Network Load Balancer の作成 — インスタンスターゲット
<a name="_create_network_load_balancerinstance_targets"></a>
+ AWS クラウドプロバイダーロードバランサーコントローラーでは、インスタンスターゲットのみを使用して Network Load Balancer を作成します。バージョン `2.2.0` 以降の AWS Load Balancer Controller でも同様に、インスタンスターゲットを使用して Network Load Balancer を作成します。新しい Network Load Balancer の作成には、AWS クラウドプロバイダーロードバランサーコントローラーではなく、こちらを使用することをお勧めします。Network Load Balancer のインスタンスターゲットは、Amazon EC2 ノードにデプロイされた Pod では使用できますが、Fargate にデプロイされた Pod では使用できません。Fargate にデプロイされたポッド間でネットワークトラフィックを負荷分散するには、IP ターゲットを使用する必要があります。

  Network Load Balancer をプライベートサブネットにデプロイするには、サービスの仕様に次のアノテーションが必要です。アノテーション付きの[サンプルサービスマニフェスト](#network-load-balancing-service-sample-manifest)を表示できます。`aws-load-balancer-type` の `external` 値により、AWS クラウドプロバイダーロードバランサーコントローラーではなく、AWS Load Balancer Controller によって Network Load Balancer が作成されます。

  ```
  service.beta.kubernetes.io/aws-load-balancer-type: "external"
  service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance"
  ```

  デフォルトでは、Network Load Balancer は `internal` `aws-load-balancer-scheme` を使用して作成されます。内部 Network Load Balancer の場合、Amazon EKS クラスターは、VPC 内で少なくとも 1 つのプライベートサブネットを使用するように設定されている必要があります。Kubernetes は、サブネットがパブリックかプライベートかどうかをルートテーブルで調べます。パブリックサブネットには、インターネットゲートウェイを使ったインターネットへの直接の経路がありますが、プライベートサブネットにはありません。

  パブリックサブネットに Network Load Balancer を作成して Amazon EC2 ノードへの負荷分散を行う場合、次のアノテーションを付けて `internet-facing` を指定します。

  ```
  service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
  ```
**重要**  
サービスの作成後は、このアノテーションを編集しないでください。変更する必要がある場合は、サービスオブジェクトを削除し、このアノテーションを希望する値にして再度作成します。

## (オプション) サンプルアプリケーションをデプロイする
<a name="load-balancer-sample-application"></a>
+ クラスター VPC に少なくとも 1 つのパブリックサブネットまたはプライベートサブネットが存在する。
+ クラスターに AWS Load Balancer Controller がデプロイされている。詳細については、「[AWS Load Balancer Controller を使用してインターネットトラフィックをルーティングする](aws-load-balancer-controller.md)」を参照してください。バージョン `2.7.2` 以降をお勧めします。

  1. Fargate にデプロイする場合は、VPC 内に利用可能なプライベートサブネットがあることを確認し、Fargate プロファイルを作成します。Fargate にデプロイしない場合は、このステップを省略してください。次のコマンドを実行するか、コマンドにある AWS マネジメントコンソール と `name` に同じ値を使用して、[`namespace`](fargate-profile.md#create-fargate-profile) でプロファイルを作成できます。example values は実際に使用する値に置き換えます。

     ```
     eksctl create fargateprofile \
         --cluster my-cluster \
         --region region-code \
         --name nlb-sample-app \
         --namespace nlb-sample-app
     ```

  1. サンプルアプリケーションをデプロイします。

     1. アプリケーションの名前空間を作成します。

        ```
        kubectl create namespace nlb-sample-app
        ```

     1. 次の内容をコンピュータ上の `sample-deployment.yaml` という名前のファイルに保存します。

        ```
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: nlb-sample-app
          namespace: nlb-sample-app
        spec:
          replicas: 3
          selector:
            matchLabels:
              app: nginx
          template:
            metadata:
              labels:
                app: nginx
            spec:
              containers:
                - name: nginx
                  image: public.ecr.aws/nginx/nginx:1.23
                  ports:
                    - name: tcp
                      containerPort: 80
        ```

     1. マニフェストをクラスターに適用します。

        ```
        kubectl apply -f sample-deployment.yaml
        ```

  1. IP ターゲットに負荷分散を行うインターネット向け Network Load Balancer を使用して、サービスを作成します。

     1.   次の内容をコンピュータ上の `sample-service.yaml` という名前のファイルに保存します。Fargate ノードにデプロイする場合は、`service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing` 行を削除します。

        ```
        apiVersion: v1
        kind: Service
        metadata:
          name: nlb-sample-service
          namespace: nlb-sample-app
          annotations:
            service.beta.kubernetes.io/aws-load-balancer-type: external
            service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
            service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
        spec:
          ports:
            - port: 80
              targetPort: 80
              protocol: TCP
          type: LoadBalancer
          selector:
            app: nginx
        ```

     1. マニフェストをクラスターに適用します。

        ```
        kubectl apply -f sample-service.yaml
        ```

  1.  サービスがデプロイされたことを確認します。

     ```
     kubectl get svc nlb-sample-service -n nlb-sample-app
     ```

     出力例は次のとおりです。

     ```
     NAME            TYPE           CLUSTER-IP         EXTERNAL-IP                                                                    PORT(S)        AGE
     sample-service  LoadBalancer   10.100.240.137   k8s-nlbsampl-nlbsampl-xxxxxxxxxx-xxxxxxxxxxxxxxxx.elb.region-code.amazonaws.com  80:32400/TCP   16h
     ```
**注記**  
*10.100.240.137* および *xxxxxxxxxx*-*xxxxxxxxxxxxxxxx* の値は出力例とは異なります (ロードバランサーに固有のものになります)。*us-west-2* は、クラスターがどの AWS リージョンにあるかによって異なる場合があります。

  1. [Amazon EC2 AWS マネジメントコンソール](https://console.aws.amazon.com/ec2) を開きます。左側のナビゲーションペインで、(**[Load Balancing]** (ロードバランシング) の下の) **[Target Groups]** (ターゲットグループ) を選択します。**[名前]** 列で、前のステップの出力である `EXTERNAL-IP` 列に入っている名前の一部と **[ロードバランサー]** 列の値が一致するターゲットグループの名前を選択します 。例えば、出力が以前の出力と同じ場合は、`k8s-default-samplese-xxxxxxxxxx ` という名前のターゲットグループを選択します。**[Target type]** (ターゲットタイプ) は `IP` です。これは、サービスのサンプルマニフェストで指定されているためです。

  1. [**ターゲットグループ**] を選択し、[**ターゲット**] タブを選択します。[**登録済みターゲット**] の下に、前のステップでデプロイされた 3 つのレプリカの 3 つの IP アドレスが表示されます。すべてのターゲットのステータスが [**正常**] になってから次に進みます。すべてのターゲットが `healthy` になるまで数分かかることがあります。ターゲットは、`healthy` 状態に変更される前の `unhealthy` 状態である可能性があります。

  1. *xxxxxxxxxx-xxxxxxxxxxxxxxxx* および *us-west-2* を `EXTERNAL-IP` の[前のステップ](#nlb-sample-app-verify-deployment)の出力で返された値に置き換え、サービスにトラフィックを送信します。プライベートサブネットにデプロイした場合は、踏み台ホストなどの VPC 内のデバイスからページを表示する必要があります。詳細については、[AWS での Linux 踏み台ホスト](https://aws.amazon.com/quickstart/architecture/linux-bastion/)を参照してください。

     ```
     curl k8s-default-samplese-xxxxxxxxxx-xxxxxxxxxxxxxxxx.elb.region-code.amazonaws.com
     ```

     出力例は次のとおりです。

     ```
     <!DOCTYPE html>
     <html>
     <head>
     <title>Welcome to nginx!</title>
     [...]
     ```

  1. サンプルのデプロイ、サービス、および名前空間の使用が終了したら、それらを削除します。

     ```
     kubectl delete namespace nlb-sample-app
     ```