

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

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

# VPC CNI モードと設定について説明します。
<a name="pod-networking-use-cases"></a>

Amazon VPC CNI plugin for Kubernetes は、Pod のネットワーキングを提供します。使用可能なネットワーク機能の詳細については次の表を参照してください。


| ネットワーキング機能 | 詳細はこちら | 
| --- | --- | 
|  クラスター、Pod、サービスに IPv6 アドレスを割り当てるようにクラスターを設定する  |   [クラスター、Pod、サービスに対する IPv6 アドレスの説明](cni-ipv6.md)   | 
|  Pod に IPv4 Source Network Address Translation を使用する  |   [Pod のアウトバウンドインターネットアクセスを有効にする](external-snat.md)   | 
|  Pod との間のネットワークトラフィックを制限する  |   [Kubernetes ネットワークポリシーを使用して Pod ネットワークトラフィックを制限する](cni-network-policy-configure.md)   | 
|  ノードでセカンダリネットワークインターフェイスをカスタマイズする  |   [カスタムネットワーキングを使用して代替サブネットに Pod をデプロイする](cni-custom-network.md)   | 
|  ノードの IP アドレスを増やす  |   [プレフィックスを使用して Amazon EKS ノードに割り当てる IP アドレスを増やす](cni-increase-ip-addresses.md)   | 
|  Pod ネットワークトラフィックにセキュリティグループを使用する  |   [セキュリティグループを個別の Pod に割り当てる](security-groups-for-pods.md)   | 
|  Pod に複数のネットワークインターフェイスを使用する  |   [複数のネットワークインターフェイスをポッドにアタッチする](pod-multiple-network-interfaces.md)   | 

# クラスター、Pod、サービスに対する IPv6 アドレスの説明
<a name="cni-ipv6"></a>

 **適用対象**: Amazon EC2 インスタンスを持つ Pod と Fargate Pod

Kubernetes のデフォルトでは、`IPv4` アドレスが Pod とサービスに割り当てられます。Pod とサービスに `IPv4` アドレスを割り当てる代わりに、`IPv6` アドレスを割り当てるようにクラスターを設定できます。Amazon EKS は、Kubernetes がサポートしていても、デュアルスタックのポッドまたはサービスをサポートしません。つまり、Pod とサービスに `IPv4` アドレスと `IPv6` アドレスの両方を割り当てることはできません。

そのクラスターに使用する IP ファミリーは、クラスターの作成時に選択します。クラスターの作成後は、ファミリーを変更できません。

Amazon EKS `IPv6` クラスターをデプロイするチュートリアルについては、「[Amazon EKS `IPv6` クラスターとマネージド Amazon Linux ノードをデプロイする](deploy-ipv6-cluster.md)」を参照してください。

この機能を使用する際の考慮事項を次に示します。

## `IPv6` の機能のサポート
<a name="_ipv6_feature_support"></a>
+  **Windows サポートなし**: Windows の Pod とサービスはサポートされていません。
+  **Nitro ベースの EC2 ノードが必要**: `IPv6` は、AWS Nitro ベースの Amazon EC2 または Fargate ノードでのみ使用が可能です。
+  **EC2 ノードおよび Fargate ノードがサポートされる**:`IPv6` は、Amazon EC2 ノードと Fargate ノードで [セキュリティグループを個別の Pod に割り当てる](security-groups-for-pods.md) とともに使用できます。
+  **Outposts はサポートされない**: `IPv6` は [AWS Outposts を使用して Amazon EKS をオンプレミスにデプロイする](eks-outposts.md) とともに使用できません。
+  **FSx for Lustre はサポートされない**: [Amazon FSx for Lustre で高性能なアプリケーションストレージを使用する](fsx-csi.md) はサポートされていません。
+  **カスタムネットワーキングはサポートされない**: IP アドレスの枯渇を緩和するために、これまで使用していた [カスタムネットワーキングを使用して代替サブネットに Pod をデプロイする](cni-custom-network.md) の代わりとして、`IPv6` を使用することができます。`IPv6` では、カスタムネットワーキングを使用することはできません。クラスターにおいて、ネットワークの分離用としてカスタムネットワーキングを使用する場合は、引き続き、`IPv4` ファミリーによるカスタムネットワーキングを使用する必要があります。

## IP アドレスの割り当て
<a name="_ip_address_assignments"></a>
+  **Kubernetes サービス**: Kubernetes サービスには `IPv6` アドレスのみが割り当てられます。これらには、IPv4 アドレスは割り当てられません。
+  **ポッド**: ポッドには IPv6 アドレスとホストローカル IPv4 アドレスが割り当てられます。ホストローカル IPv4 アドレスは、VPC CNI と連鎖されたホストローカル CNI プラグインを使用して割り当てられ、そのアドレスは Kubernetes コントロールプレーンに報告されません。これは、ポッドが別の Amazon VPC またはインターネット内の外部 IPv4 リソースと通信する必要がある場合にのみ使用されます。ホストローカル IPv4 アドレスは、ワーカーノードのプライマリ ENI のプライマリ IPv4 アドレスに (VPC CNI によって) SNAT されます。
+  **ポッドとサービス**: ポッドおよびサービスは `IPv4` アドレスではなく、`IPv6` アドレスのみを受け取ります。ポッドが外部 `IPv4` エンドポイントと通信する必要がある場合、ノード自体で NAT が使用されます。この組み込み NAT 機能により、[DNS64 および NAT64](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html#nat-gateway-nat64-dns64) が不要になります。パブリックインターネットアクセスを必要とするトラフィックの場合、ポッドのトラフィックはパブリック IP アドレスに変換されたソースネットワークアドレスになります。
+  **ルーティングアドレス**: ポッドが VPC の外部で通信する場合、元の `IPv6` アドレスは保持されます (ノードの `IPv6` アドレスに変換されない)。このトラフィックは、インターネットゲートウェイまたは Egress-Only のインターネットゲートウェイを介して直接ルーティングされます。
+  **ノード**: すべてのノードには、`IPv4` と `IPv6` のアドレスが割り当てられています。
+  **Fargate ポッド**: 各 Fargate Pod は、デプロイ先のサブネット用に指定された CIDR から、`IPv6` アドレスを受け取ります。Fargate Pod を実行するための基盤ハードウェアユニットは、そのユニットがデプロイされているサブネットに割り当てられている CIDR から、一意の `IPv4` および `IPv6` アドレスを取得します。

## EKS で `IPv6` を使用する方法
<a name="_how_to_use_ipv6_with_eks"></a>
+  **新しいクラスターを作成する**: 新しいクラスターを作成し、そのクラスターで `IPv6` ファミリーの使用を指定する必要があります。これより前のバージョンからクラスターを更新して、`IPv6` ファミリーを有効化することはできません。新しいクラスターを作成する手順については、「考慮事項」を参照してください。
+  **最新の VPC CNI を使用する**: Amazon VPC CNI バージョン `1.10.1` 以降をデプロイします。このバージョン以降がデフォルトでデプロイされます。アドオンのデプロイ後は、クラスター内のすべてのノードグループ内にあるすべてのノードを削除しない限り、Amazon VPC CNI アドオンを `1.10.1` より前のバージョンにダウングレードすることはできません。
+  **`IPv6` 用の VPC CNI を設定する**: Amazon EC2 ノードを使用する場合は、IP プレフィックスの委任と `IPv6` を使用して Amazon VPC CNI アドオンを設定する必要があります。クラスターの作成時に `IPv6` ファミリーを選択した場合は、バージョン `1.10.1` のアドオンが、この設定のデフォルトになります。これは、セルフマネージド型のアドオン、および Amazon EKS アドオンの両方に当てはまります。IP プレフィックス委任の詳細については、「[プレフィックスを使用して Amazon EKS ノードに割り当てる IP アドレスを増やす](cni-increase-ip-addresses.md)」を参照してください。
+  **`IPv4` アドレスと `IPv6` アドレスを設定する**: クラスターを作成する際に指定する VPC とサブネットには、それらに割り当てられた `IPv6` CIDR ブロックが必要です。同時に、`IPv4` CIDR ブロックも割り当てられている必要があります。これは、`IPv6` のみを使用する場合でも、VPC が機能するには `IPv4` CIDR ブロックが必要になるためです。詳細については、「Amazon VPC ユーザーガイド」の「[IPv6 CIDR ブロックと VPC の関連付け](https://docs.aws.amazon.com/vpc/latest/userguide/working-with-vpcs.html#vpc-associate-ipv6-cidr)」を参照してください。
+  **IPv6 アドレスをノードに自動割り当てする:** ノードを作成する際は、`IPv6` アドレスを自動割り当てするように設定されたサブネットを指定する必要があります。指定していない場合、ノードをデプロイできません。自動割り当ての設定はデフォルトで無効になっています｡ 詳細については、「Amazon VPC ユーザーガイド」の「[サブネットのパブリック IPv6 アドレス属性を変更する](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-ip-addressing.html#subnet-ipv6)」を参照してください。
+  **ルートテーブルを設定して `IPv6` を使用する**: サブネットに割り当てられるルートテーブルには、`IPv6` アドレス用のルートが必要です。詳細については、「Amazon VPC ユーザーガイド」の「[既存の VPC を IPv4 から IPv6 に移行する](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)」を参照してください。
+  **`IPv6` のセキュリティグループを設定する**: セキュリティグループは `IPv6` アドレスを許可する必要があります。詳細については、「Amazon VPC ユーザーガイド」の「[既存の VPC を IPv4 から IPv6 に移行する](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)」を参照してください。
+  **ロードバランサーを設定する**: AWS Load Balancer Controller のバージョン `2.3.1` 以降を使用して、「[Application Load Balancer を使用してアプリケーションと HTTP トラフィックをルーティングする](alb-ingress.md)」を使用した HTTP アプリケーションのロードバランシング、または、「[Network Load Balancer を使用して TCP および UDP トラフィックをルーティングする](network-load-balancing.md)」を使用したネットワークトラフィックの `IPv6` Pod へのロードバランシングを行います。いずれの場合もインスタンスモードではなく IP モードを使用してください。詳細については、「[AWS Load Balancer Controller を使用してインターネットトラフィックをルーティングする](aws-load-balancer-controller.md)」を参照してください。
+  **`IPv6` IAM ポリシーを追加する**: ノード IAM または CNI IAM ロールには、`IPv6` のIAM ポリシーをアタッチする必要があります。上記 2 つの中では、CNI IAM ロールへのアタッチが推奨されます。詳細については、「[`IPv6` ファミリーを使用するクラスター用に IAM ポリシーを作成します。](cni-iam-role.md#cni-iam-role-create-ipv6-policy)」および「[ステップ 1: Amazon VPC CNI plugin for Kubernetes の IAM ロールを作成する](cni-iam-role.md#cni-iam-role-create-role)」を参照してください。
+  **すべてのコンポーネントを評価する**: アプリケーション、Amazon EKS アドオン、および、`IPv6` クラスターのデプロイ前に統合した AWS サービスに関しては、包括的な評価を実施します。これにより、`IPv6` を使用した場合も、すべてが想定どおりに動作することを保証できます。

# Amazon EKS `IPv6` クラスターとマネージド Amazon Linux ノードをデプロイする
<a name="deploy-ipv6-cluster"></a>

このチュートリアルでは、`IPv6` ファミリーを使用する `IPv6` Amazon VPC と Amazon EKS クラスターのデプロイ、および Amazon EC2 Amazon Linux ノードを使用するマネージド型ノードグループのデプロイ方法を説明します。`IPv6` クラスター内では、Amazon EC2 Windows のノードをデプロイすることはできません。Fargate ノードをクラスターにデプロイすることもできますが、理解しやすくするため、これらの手順はこのトピックでは説明していません。

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

このチュートリアルを開始する前に以下を完了してください。

Amazon EKS クラスターの作成と管理に必要な次のツールおよびリソースをインストールおよび設定します。
+ すべての設定を習熟し、要件を満たす設定でクラスターをデプロイすることをお勧めします。詳細については、「[Amazon EKS クラスターを作成します。](create-cluster.md)」、「[マネージドノードグループを使用してノードライフサイクルを簡素化する](managed-node-groups.md)」、ならびにこのトピックの「[考慮事項](cni-ipv6.md)」を参照してください。一部の設定の有効化は、クラスターの作成時にのみ行えます。
+ デバイスまたは AWS クラウドシェル に、`kubectl` コマンドラインツールがインストールされていること。バージョンはご使用のクラスターの Kubernetes バージョンと同じか、1 つ前のマイナーバージョン以前、あるいはそれより新しいバージョンが使用できます。例えば、クラスターのバージョンが `1.29` である場合、`kubectl` のバージョン `1.28`、`1.29`、または `1.30` が使用できます。`kubectl` をインストールまたはアップグレードする方法については「[`kubectl` および `eksctl` のセットアップ](install-kubectl.md)」を参照してください。
+ 使用している IAM セキュリティプリンシパルは、Amazon EKS の IAM ロール、サービスにリンクされたロール、AWS CloudFormation、VPC、関連リソースを使用するために許可が必要です。詳細については、「IAM ユーザーガイド」の「[アクション](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonelastickubernetesservice.html)」および「[サービスにリンクされたロールの使用](https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html)」を参照してください。
+ eksctl を使用する場合は、コンピュータにバージョン `0.215.0` 以降をインストールします。インストールまたはアップグレードするには、`eksctl` ドキュメントの「[インストール](https://eksctl.io/installation)」を参照してください。
+ ご使用のデバイスまたは AWS CloudShell で、バージョン `2.12.3` 以降、または AWS コマンドラインインターフェイス (AWS CLI) のバージョン `1.27.160` 以降がインストールおよび設定されていること。現在のバージョンを確認するには「`aws --version | cut -d / -f2 | cut -d ' ' -f1`」を参照してください。`yum`、`apt-get`、macOS 用の Homebrew などのパッケージマネージャーは、多くの場合 AWS CLI の最新バージョンより数バージョン古くなっています。最新バージョンをインストールするには「*AWS コマンドラインインターフェイスユーザーガイド*」の「[インストール](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)」および「[aws configure を使用したクイック設定](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)」を参照してください。AWS クラウドシェル にインストールされている AWS CLI バージョンも最新バージョンより数バージョン遅れることがあります。更新するには、「*AWS CloudShell ユーザーガイド*」の「[ホームディレクトリへの AWS CLI のインストール](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software)」を参照してください。AWS CloudShell を使用する場合は、[バージョン 2.12.3 以降または 1.27.160 以降の AWS CLI をインストール](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software)する必要があります。AWS CloudShell には、デフォルトとして AWS CLI の古いバージョンがインストールされている可能性があります。

eksctl または CLI を使用して `IPv6` クラスターをデプロイできます。

## eksctl を使用して IPv6 クラスターをデプロイする
<a name="_deploy_an_ipv6_cluster_with_eksctl"></a>

1. `ipv6-cluster.yaml` ファイルの作成 デバイスに沿ったコマンドをコピーします。必要に応じてコマンドに次の変更を加え、変更したコマンドを実行してください：
   + *my-cluster* の部分は、自分のクラスター名に置き換えます。この名前には英数字 (大文字と小文字が区別されます) とハイフンのみを使用できます。先頭の文字は英数字である必要があります。また、100 文字より長くすることはできません。名前は、クラスターを作成する AWS リージョンおよび AWS アカウント内で一意である必要があります。
   + *region-code* は、Amazon EKS がサポートする任意の AWS リージョンに置き換えます。AWS リージョンの一覧については、AWS の全般的なリファレンスガイドの [Amazon EKS エンドポイントとクォータ](https://docs.aws.amazon.com/general/latest/gr/eks.html)を参照してください。
   + `version` の値には、クラスターのバージョンを設定する必要があります。詳細については、「[Amazon EKS supported versions](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)」を参照してください。
   + *my-nodegroup* を、ノードグループの名前に置き換えます。ノードグループ名は 63 文字以下である必要があります。先頭は文字または数字でなければなりませんが、残りの文字にはハイフンおよびアンダースコアを含めることもできます。
   + *t3.medium* の部分は、任意の [AWS Nitro System インスタンスタイプ](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances)に置き換えます。

     ```
     cat >ipv6-cluster.yaml <<EOF
     ---
     apiVersion: eksctl.io/v1alpha5
     kind: ClusterConfig
     
     metadata:
       name: my-cluster
       region: region-code
       version: "X.XX"
     
     kubernetesNetworkConfig:
       ipFamily: IPv6
     
     addons:
       - name: vpc-cni
         version: latest
       - name: coredns
         version: latest
       - name: kube-proxy
         version: latest
     
     iam:
       withOIDC: true
     
     managedNodeGroups:
       - name: my-nodegroup
         instanceType: t3.medium
     EOF
     ```

1. クラスターを作成する

   ```
   eksctl create cluster -f ipv6-cluster.yaml
   ```

   クラスターの作成には数分かかります。出力の最後の行が表示されるまで、次の手順には進まないでください。この行は、下記のような出力になります。

   ```
   [...]
   [✓]  EKS cluster "my-cluster" in "region-code" region is ready
   ```

1. デフォルトの Pod に、`IPv6` アドレスが割り当てられていることを確認します。

   ```
   kubectl get pods -n kube-system -o wide
   ```

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

   ```
   NAME                       READY   STATUS    RESTARTS   AGE     IP                                       NODE                                            NOMINATED NODE   READINESS GATES
   aws-node-rslts             1/1     Running   1          5m36s   2600:1f13:b66:8200:11a5:ade0:c590:6ac8   ip-192-168-34-75.region-code.compute.internal   <none>           <none>
   aws-node-t74jh             1/1     Running   0          5m32s   2600:1f13:b66:8203:4516:2080:8ced:1ca9   ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   coredns-85d5b4454c-cw7w2   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::                ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   coredns-85d5b4454c-tx6n8   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::1               ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   kube-proxy-btpbk           1/1     Running   0          5m36s   2600:1f13:b66:8200:11a5:ade0:c590:6ac8   ip-192-168-34-75.region-code.compute.internal   <none>           <none>
   kube-proxy-jjk2g           1/1     Running   0          5m33s   2600:1f13:b66:8203:4516:2080:8ced:1ca9   ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   ```

1. デフォルトのサービスに、`IPv6` アドレスが割り当てられていることを確認します。

   ```
   kubectl get services -n kube-system -o wide
   ```

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

   ```
   NAME       TYPE        CLUSTER-IP          EXTERNAL-IP   PORT(S)         AGE   SELECTOR
   kube-dns   ClusterIP   fd30:3087:b6c2::a   <none>        53/UDP,53/TCP   57m   k8s-app=kube-dns
   ```

1. (オプション) [サンプルアプリケーションをデプロイする](sample-deployment.md)か、[AWS Load Balancer コントローラーとサンプルアプリケーションをデプロイ](aws-load-balancer-controller.md)して、「[Application Load Balancer を使用してアプリケーションと HTTP トラフィックをルーティングする](alb-ingress.md)」に従い HTTP アプリケーションをロードバランシングするか、「[Network Load Balancer を使用して TCP および UDP トラフィックをルーティングする](network-load-balancing.md)」に従いネットワークトラフィックを `IPv6` Pod にロードバランシングします。

1. このチュートリアルのために作成したクラスターとノードの使用が終了したら、それらのリソースは、次のコマンドにより削除しておきます。

   ```
   eksctl delete cluster my-cluster
   ```

## AWS CLI を使用して IPv6 クラスターをデプロイする
<a name="deploy_an_ipv6_cluster_with_shared_aws_cli"></a>

**重要**  
この手順のすべてのステップは、同一のユーザーとして実行する必要があります。現在のユーザーを確認するには、次のコマンドを実行します。  

  ```
  aws sts get-caller-identity
  ```
この手順のすべてのステップは、同一のシェル内で実行する必要があります。いくつかのステップには、これより前のステップで設定した変数を使用します。変数の値が異なるシェル内で設定されていると、その変数を使用するステップは正しく機能しません。[AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html) を使用して次の手順を実行する際、約 20～30 分の間キーボードまたはポインタによる操作がないと、シェルセッションが終了することを銘記しておいてください。実行中のプロセスは、操作数としてカウントされません。
各命令は Bash シェル用に記述されているので、他のシェルでは修正が必要な場合があります。

この手順の各ステップにおいて、すべての example values は、ご自分が使用する値に置き換える必要があります。

1. 以下のコマンドを実行して、後のステップで使用するいくつかの変数を設定します。*region-code* は、リソースをデプロイする AWS リージョンに置き換えます。この値には、Amazon EKS でサポートされている任意の AWS リージョンが設定できます。AWS リージョンの一覧については、AWS の全般的なリファレンスガイドの [Amazon EKS エンドポイントとクォータ](https://docs.aws.amazon.com/general/latest/gr/eks.html)を参照してください。*my-cluster* の部分は、自分のクラスター名に置き換えます。この名前には英数字 (大文字と小文字が区別されます) とハイフンのみを使用できます。先頭の文字は英数字である必要があります。また、100 文字より長くすることはできません。名前は、クラスターを作成する AWS リージョンおよび AWS アカウント内で一意である必要があります。*my-nodegroup* を、ノードグループの名前に置き換えます。ノードグループ名は 63 文字以下である必要があります。先頭は文字または数字でなければなりませんが、残りの文字にはハイフンおよびアンダースコアを含めることもできます。*111122223333* は、ご自分のアカウント ID に置き換えます。

   ```
   export region_code=region-code
   export cluster_name=my-cluster
   export nodegroup_name=my-nodegroup
   export account_id=111122223333
   ```

1. パブリックサブネットとプライベートサブネットを持ち、Amazon EKS と `IPv6` の要件を満たす Amazon VPC を作成します。

   1. 次のコマンドを実行して、AWS CloudFormation スタック名のための変数を設定します。*my-eks-ipv6-vpc* は、任意の名前に置き換えることができます。

      ```
      export vpc_stack_name=my-eks-ipv6-vpc
      ```

   1. AWS CloudFormation のテンプレートを使用して `IPv6` VPC を作成します。

      ```
      aws cloudformation create-stack --region $region_code --stack-name $vpc_stack_name \
        --template-url https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-ipv6-vpc-public-private-subnets.yaml
      ```

      スタックが作成されるまで数分かかります。以下のコマンドを実行してください。コマンドの出力が「`CREATE_COMPLETE`」になるまで、次のステップに進まないでください。

      ```
      aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name --query Stacks[].StackStatus --output text
      ```

   1. 作成されたパブリックサブネットの ID を取得します。

      ```
      aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \
          --query='Stacks[].Outputs[?OutputKey==`SubnetsPublic`].OutputValue' --output text
      ```

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

      ```
      subnet-0a1a56c486EXAMPLE,subnet-099e6ca77aEXAMPLE
      ```

   1. 作成されたパブリックサブネットで、`IPv6` アドレスの自動割り当てオプションを有効にします。

      ```
      aws ec2 modify-subnet-attribute --region $region_code --subnet-id subnet-0a1a56c486EXAMPLE --assign-ipv6-address-on-creation
      aws ec2 modify-subnet-attribute --region $region_code --subnet-id subnet-099e6ca77aEXAMPLE --assign-ipv6-address-on-creation
      ```

   1. テンプレートによって作成されたサブネットおよびセキュリティグループの名前を、デプロイされた AWS CloudFormation スタックから取得します。これらの名前は、後のステップで使用するために変数に格納しておきます。

      ```
      security_groups=$(aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \
          --query='Stacks[].Outputs[?OutputKey==`SecurityGroups`].OutputValue' --output text)
      
      public_subnets=$(aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \
          --query='Stacks[].Outputs[?OutputKey==`SubnetsPublic`].OutputValue' --output text)
      
      private_subnets=$(aws cloudformation describe-stacks --region $region_code --stack-name $vpc_stack_name \
          --query='Stacks[].Outputs[?OutputKey==`SubnetsPrivate`].OutputValue' --output text)
      
      subnets=${public_subnets},${private_subnets}
      ```

1. クラスターの IAM ロールを作成して、そのロールに必要な Amazon EKS IAM 管理ポリシーをアタッチします。Amazon EKS によって管理される Kubernetes クラスターは、そのサービスで使用するリソースを管理するために、ユーザーに代わって他の AWS のサービスを呼び出します。

   1. 次のコマンドを実行して、`eks-cluster-role-trust-policy.json` ファイルを作成します。

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Service": "eks.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
          }
        ]
      }
      ```

   1. 次のコマンドを実行して、ロール名の変数を設定します。*myAmazonEKSClusterRole* は、任意の名前に置き換えることができます。

      ```
      export cluster_role_name=myAmazonEKSClusterRole
      ```

   1. ロールを作成します。

      ```
      aws iam create-role --role-name $cluster_role_name --assume-role-policy-document file://"eks-cluster-role-trust-policy.json"
      ```

   1. IAM ロールの ARN を取得し、後のステップで使用するために変数に格納します。

      ```
      CLUSTER_IAM_ROLE=$(aws iam get-role --role-name $cluster_role_name --query="Role.Arn" --output text)
      ```

   1. このロールに、必要な Amazon EKS 管理の IAM ポリシーをアタッチします。

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy --role-name $cluster_role_name
      ```

1. クラスターを作成する

   ```
   aws eks create-cluster --region $region_code --name $cluster_name --kubernetes-version 1.XX \
      --role-arn $CLUSTER_IAM_ROLE --resources-vpc-config subnetIds=$subnets,securityGroupIds=$security_groups \
      --kubernetes-network-config ipFamily=ipv6
   ```

   1. 注意: リクエストで指定したアベイラビリティーゾーンのいずれかに、Amazon EKS クラスターの作成に十分な容量がない場合には、エラーが表示されることがあります。このエラー出力には新しいクラスターをサポートできるアベイラビリティーゾーンが表示されます。アカウント向けにサポートされているアベイラビリティーゾーンにある 2 つ以上のサブネットを使用して、クラスターを作成します。詳細については「[容量不足](troubleshooting.md#ice)」を参照してください。

      クラスターが作成されるまでに数分かかります。以下のコマンドを実行してください。コマンドの出力が「`ACTIVE`」になるまで、次のステップに進まないでください。

      ```
      aws eks describe-cluster --region $region_code --name $cluster_name --query cluster.status
      ```

1. クラスターの `kubeconfig` ファイルを作成または更新し、そのクラスターと通信できるようにします。

   ```
   aws eks update-kubeconfig --region $region_code --name $cluster_name
   ```

   デフォルトでは、`config` ファイルが `~/.kube` に作成されるか、`config` ファイルが既に `~/.kube` に存在する場合には、その中に新しいクラスター設定が追加されます。

1. ノードの IAM ロールを作成します。

   1. 次のコマンドを実行して、`vpc-cni-ipv6-policy.json` ファイルを作成します。

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "ec2:AssignIpv6Addresses",
                      "ec2:DescribeInstances",
                      "ec2:DescribeTags",
                      "ec2:DescribeNetworkInterfaces",
                      "ec2:DescribeInstanceTypes"
                  ],
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "ec2:CreateTags"
                  ],
                  "Resource": [
                      "arn:aws:ec2:*:*:network-interface/*"
                  ]
              }
          ]
      }
      ```

   1. IAM ポリシーを作成します。

      ```
      aws iam create-policy --policy-name AmazonEKS_CNI_IPv6_Policy --policy-document file://vpc-cni-ipv6-policy.json
      ```

   1. 次のコマンドを実行して、`node-role-trust-relationship.json` ファイルを作成します。

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
          }
        ]
      }
      ```

   1. 次のコマンドを実行して、ロール名の変数を設定します。*AmazonEKSNodeRole* は、任意の名前に置き換えることができます。

      ```
      export node_role_name=AmazonEKSNodeRole
      ```

   1. IAM ロールの作成

      ```
      aws iam create-role --role-name $node_role_name --assume-role-policy-document file://"node-role-trust-relationship.json"
      ```

   1. IAM ロールに IAM ポリシーをアタッチします。

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::$account_id:policy/AmazonEKS_CNI_IPv6_Policy \
          --role-name $node_role_name
      ```
**重要**  
簡単にするため、このチュートリアルでは、ポリシーが以下の IAM ロールにアタッチされています。ただし、本番向けクラスターの場合は、異なる IAM ロールにポリシーをアタッチすることをお勧めします。詳細については、「[IRSA を使用するように Amazon VPC CNI プラグインを設定する](cni-iam-role.md)」を参照してください。

   1. IAM ロールに、2 つの必須なマネージド IAM ポリシーをアタッチします。

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \
        --role-name $node_role_name
      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \
        --role-name $node_role_name
      ```

   1. IAM ロールの ARN を取得し、後のステップで使用するために変数に格納します。

      ```
      node_iam_role=$(aws iam get-role --role-name $node_role_name --query="Role.Arn" --output text)
      ```

1. マネージド型ノードグループを作成する

   1. 前のステップで作成したサブネットの ID を表示します。

      ```
      echo $subnets
      ```

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

      ```
      subnet-0a1a56c486EXAMPLE,subnet-099e6ca77aEXAMPLE,subnet-0377963d69EXAMPLE,subnet-0c05f819d5EXAMPLE
      ```

   1. ノードグループを作成します。*0a1a56c486EXAMPLE*、*099e6ca77aEXAMPLE*、*0377963d69EXAMPLE*、および *0c05f819d5EXAMPLE* は、前のステップの出力で返された値に置き換えます。次のコマンドでは、前の出力の中でサブネット ID の間にあるカンマを必ず削除して使用します。*t3.medium* の部分は、任意の [AWS Nitro System インスタンスタイプ](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances)に置き換えることができます。

      ```
      aws eks create-nodegroup --region $region_code --cluster-name $cluster_name --nodegroup-name $nodegroup_name \
          --subnets subnet-0a1a56c486EXAMPLE subnet-099e6ca77aEXAMPLE subnet-0377963d69EXAMPLE subnet-0c05f819d5EXAMPLE \
          --instance-types t3.medium --node-role $node_iam_role
      ```

      ノードグループの作成には数分かかります。以下のコマンドを実行してください。出力が「`ACTIVE`」を返すまで、次のステップに進まないでください。

      ```
      aws eks describe-nodegroup --region $region_code --cluster-name $cluster_name --nodegroup-name $nodegroup_name \
          --query nodegroup.status --output text
      ```

1. デフォルトの Pod に `IPv6` アドレスが割り当てられていることを、`IP` 列で確認します。

   ```
   kubectl get pods -n kube-system -o wide
   ```

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

   ```
   NAME                       READY   STATUS    RESTARTS   AGE     IP                                       NODE                                            NOMINATED NODE   READINESS GATES
   aws-node-rslts             1/1     Running   1          5m36s   2600:1f13:b66:8200:11a5:ade0:c590:6ac8   ip-192-168-34-75.region-code.compute.internal   <none>           <none>
   aws-node-t74jh             1/1     Running   0          5m32s   2600:1f13:b66:8203:4516:2080:8ced:1ca9   ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   coredns-85d5b4454c-cw7w2   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::                ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   coredns-85d5b4454c-tx6n8   1/1     Running   0          56m     2600:1f13:b66:8203:34e5::1               ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   kube-proxy-btpbk           1/1     Running   0          5m36s   2600:1f13:b66:8200:11a5:ade0:c590:6ac8   ip-192-168-34-75.region-code.compute.internal   <none>           <none>
   kube-proxy-jjk2g           1/1     Running   0          5m33s   2600:1f13:b66:8203:4516:2080:8ced:1ca9   ip-192-168-253-70.region-code.compute.internal  <none>           <none>
   ```

1. デフォルトのサービスに `IPv6` アドレスが割り当てられていることを、`IP` 列で確認します。

   ```
   kubectl get services -n kube-system -o wide
   ```

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

   ```
   NAME       TYPE        CLUSTER-IP          EXTERNAL-IP   PORT(S)         AGE   SELECTOR
   kube-dns   ClusterIP   fd30:3087:b6c2::a   <none>        53/UDP,53/TCP   57m   k8s-app=kube-dns
   ```

1. (オプション) [サンプルアプリケーションをデプロイする](sample-deployment.md)か、[AWS Load Balancer コントローラーとサンプルアプリケーションをデプロイ](aws-load-balancer-controller.md)して、「[Application Load Balancer を使用してアプリケーションと HTTP トラフィックをルーティングする](alb-ingress.md)」に従い HTTP アプリケーションをロードバランシングするか、「[Network Load Balancer を使用して TCP および UDP トラフィックをルーティングする](network-load-balancing.md)」 に従いネットワークトラフィックを `IPv6` Pod にロードバランシングします。

1. このチュートリアルのために作成したクラスターとノードの使用が終了したら、以下のコマンドにより、作成したリソースのクリーンアップを行う必要があります。削除を行う前に、これらのリソースが、このチュートリアルの外部で使用されていないことを確認します。

   1. ここまでの手順を実行したのとは異なるシェルで、このステップを完了する場合は、サンプル値を前の手順を実行した際に指定した値に置き換えながら、すべての変数を前の手順で使用した値に設定します。前の手順を実行したのと同じシェルでこのステップを完了する場合は、このまま次のステップに進みます。

      ```
      export region_code=region-code
      export vpc_stack_name=my-eks-ipv6-vpc
      export cluster_name=my-cluster
      export nodegroup_name=my-nodegroup
      export account_id=111122223333
      export node_role_name=AmazonEKSNodeRole
      export cluster_role_name=myAmazonEKSClusterRole
      ```

   1. ノードグループを削除します。

      ```
      aws eks delete-nodegroup --region $region_code --cluster-name $cluster_name --nodegroup-name $nodegroup_name
      ```

      削除には数分かかります。以下のコマンドを実行してください。何らかの出力が返された場合は、次のステップに進まないでください。

      ```
      aws eks list-nodegroups --region $region_code --cluster-name $cluster_name --query nodegroups --output text
      ```

   1. クラスターを削除します。

      ```
      aws eks delete-cluster --region $region_code --name $cluster_name
      ```

      クラスターの削除には数分かかります。次に進む前に、下記のコマンドを使用してクラスターが削除されていることを確認します。

      ```
      aws eks describe-cluster --region $region_code --name $cluster_name
      ```

      下記のような出力が返されるまで、次のステップに進まないでください。

      ```
      An error occurred (ResourceNotFoundException) when calling the DescribeCluster operation: No cluster found for name: my-cluster.
      ```

   1. 作成した IAM リソースを削除します。前の手順で使用した名前とは異なる名前を選択した場合は、その名で *AmazonEKS\$1CNI\$1IPv6\$1Policy* を置き換えます。

      ```
      aws iam detach-role-policy --role-name $cluster_role_name --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
      aws iam detach-role-policy --role-name $node_role_name --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
      aws iam detach-role-policy --role-name $node_role_name --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
      aws iam detach-role-policy --role-name $node_role_name --policy-arn arn:aws:iam::$account_id:policy/AmazonEKS_CNI_IPv6_Policy
      aws iam delete-policy --policy-arn arn:aws:iam::$account_id:policy/AmazonEKS_CNI_IPv6_Policy
      aws iam delete-role --role-name $cluster_role_name
      aws iam delete-role --role-name $node_role_name
      ```

   1. VPC を作成した AWS CloudFormation スタックを削除します。

      ```
      aws cloudformation delete-stack --region $region_code --stack-name $vpc_stack_name
      ```

# Pod のアウトバウンドインターネットアクセスを有効にする
<a name="external-snat"></a>

 **適用対象**: Linux `IPv4` Fargate ノード、Amazon EC2 インスタンスを持つ Linux ノード

`IPv6` ファミリーを使用してクラスターをデプロイした場合、このトピックの情報はクラスターに適用されません。`IPv6` アドレスがネットワーク変換されないからです。クラスターでの `IPv6` 使用の詳細については「[クラスター、Pod、サービスに対する IPv6 アドレスの説明](cni-ipv6.md)」を参照してください。

デフォルトでは、クラスター内の各 Pod に、Pod がデプロイされた VPC に関連付けられた Classless Inter-Domain Routing (CIDR) ブロックから、[プライベート](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-private-addresses) `IPv4` アドレスが割り当てられます。同じ VPC 内の Pod は、これらのプライベート IP アドレスをエンドポイントとして使用して相互に通信します。VPC に関連付けられている CIDR ブロック外の `IPv4` アドレスと Pod が通信する場合、([Linux](https://github.com/aws/amazon-vpc-cni-k8s#amazon-vpc-cni-k8s) と [Windows](https://github.com/aws/amazon-vpc-cni-plugins/tree/master/plugins/vpc-bridge) 両用の) Amazon VPC CNI プラグインが Pod の `IPv4` アドレスを、Pod が実行されているノードのプライマリ [Elastic Network Interface](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#eni-basics) のプライマリプライベート `IPv4` アドレスに変換します (デフォルトでは [\$1](#snat-exception))。

**注記**  
Windows ノードについては、他にも考慮すべき事項があります。デフォルトでは、[Windows の VPC CNI プラグイン](https://github.com/aws/amazon-vpc-cni-plugins/tree/master/plugins/vpc-bridge)は、同じ VPC 内の宛先へのトラフィックを SNAT から除外するネットワーク設定で定義されます。つまり、内部 VPC 通信では SNAT が無効になっており、Pod に割り当てられた IP アドレスは VPC 内でルーティング可能です。ただし、VPC 外の宛先へのトラフィックでは、送信元 Pod IP がインスタンスの ENI のプライマリ IP アドレスに SNAT されます。Windows のこのデフォルト設定により、Pod はホストインスタンスと同じ方法で VPC 外部のネットワークにアクセスできます。

この動作によって、次の現象が起こります。
+ Pod は、それらが実行されているノードに[パブリック](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-public-addresses) IP アドレスまたは [Elastic](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-eips.html) IP アドレスが割り当てられており、[パブリックサブネット](https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html#subnet-basics)内にある場合にのみ、インターネットリソースと通信できます。パブリックサブネットに関連付けられている[ルートテーブル](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html)には、インターネットゲートウェイへのルートが含まれています。可能であれば、プライベートサブネットにノードをデプロイすることをお勧めします。
+ `1.8.0` よりも古いバージョンのプラグインの場合、[VPC ピアリング](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html)、[トランジット VPC](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/transit-vpc-option.html)、または [AWS Direct Connect](https://docs.aws.amazon.com/directconnect/latest/UserGuide/Welcome.html) を使用してクラスター VPC に接続されているネットワークまたは VPC 内にあるリソースは、セカンダリ Elastic Network Interface の背後にある Pod との通信を開始できません。ただし、Pod はこれらのリソースとの通信を開始し、リソースから応答を受け取ることができます。

ご使用の環境で次のいずれかが当てはまる場合は、次のコマンドを使用してデフォルト設定を変更してください。
+ [VPC ピアリング](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html)、[トランジット VPC](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/transit-vpc-option.html)、または [AWS Direct Connect](https://docs.aws.amazon.com/directconnect/latest/UserGuide/Welcome.html) を使用してクラスター VPC に接続されているネットワークまたは VPC 内に、`IPv4` アドレスを使用して Pod との通信を開始する必要があるリソースがあり、プラグインのバージョンが `1.8.0` よりも前である。
+ Pod が[プライベートサブネット](https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html#subnet-basics)にあり、インターネットへのアウトバウンド通信を行う必要がある。サブネットには、[NAT ゲートウェイ](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html)へのルートがある。

```
kubectl set env daemonset -n kube-system aws-node AWS_VPC_K8S_CNI_EXTERNALSNAT=true
```

**注記**  
`AWS_VPC_K8S_CNI_EXTERNALSNAT` および `AWS_VPC_K8S_CNI_EXCLUDE_SNAT_CIDRS` CNI の設定変数は Windows ノードに適用されません。SNAT の無効化は Windows でサポートされていません。`IPv4` CIDR のリストを SNAT から除外する場合は、Windows ブートストラップスクリプトで `ExcludedSnatCIDRs` パラメータを指定して定義できます。このパラメータの使用に関する詳細については、「[ブートストラップスクリプトの設定パラメータ](eks-optimized-windows-ami.md#bootstrap-script-configuration-parameters)」を参照してください。

## ホストネットワーキング
<a name="snat-exception"></a>

\$1 Pod の仕様に `hostNetwork=true` が含まれている場合 (デフォルトは `false`)、その IP アドレスは別のアドレスに変換されません。これは、デフォルトでクラスターで実行される `kube-proxy` および Amazon VPC CNI plugin for Kubernetes Pod の場合に当てはまります。これらの Pod の場合、IP アドレスはノードのプライマリ IP アドレスと同じであるため、Pod の IP アドレスは変換されません。Pod の `hostNetwork` 設定の詳細については、Kubernetes API リファレンスの「[PodSpec v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#podspec-v1-core)」を参照してください。

# Kubernetes ネットワークポリシーにより Pod トラフィックを制限する
<a name="cni-network-policy"></a>

## 概要
<a name="_overview"></a>

デフォルトでは、Kubernetes の IP アドレス、ポート、クラスター内の Pod 間の接続、またはポッドと他のネットワークのリソースの接続に制限はありません。Kubernetes *ネットワークポリシー*を使用して、自分の Pod 間で送受信されるネットワークトラフィックを制限できます。詳細については、Kubernetes ドキュメントの「[ネットワークポリシー](https://kubernetes.io/docs/concepts/services-networking/network-policies/)」を参照してください。

## 標準のネットワークポリシー
<a name="_standard_network_policy"></a>

標準の `NetworkPolicy` を使用すると、クラスター内のポッド間トラフィックをセグメント化できます。OSI ネットワークモデルのレイヤー 3 と 4 で動作するネットワークポリシーであり、Amazon EKS クラスター内の IP アドレスまたはポートレベルでトラフィックフローを制御できます。標準のネットワークポリシーは、範囲が名前空間レベルに限定されます。

### ユースケース
<a name="_use_cases"></a>
+ ワークロード間でネットワークトラフィックをセグメント化すると、関連するアプリケーションのみが相互に通信できるようになります。
+ ポリシーを使用して名前空間レベルでテナントを分離すると、ネットワークを分離できます。

### 例
<a name="_example"></a>

以下のポリシーでは、*sun* 名前空間の *webapp* ポッドからのエグレストラフィックが制限されています。

```
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: webapp-egress-policy
  namespace: sun
spec:
  podSelector:
    matchLabels:
      role: webapp
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: moon
      podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 8080
  - to:
    - namespaceSelector:
        matchLabels:
          name: stars
      podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 8080
```

ポリシーは、`sun` 名前空間で `role: webapp` というラベルが付いたポッドに適用されます。
+ 許可されるトラフィック: TCP ポート `8080` の `moon` 名前空間で `role: frontend` というラベルが付いたポッド。
+ 許可されるトラフィック: TCP ポート `8080` の `stars` 名前空間で role: frontend というラベルが付いたポッド。
+ ブロックされるトラフィック: `webapp` ポッドからの他のすべてのアウトバウンドトラフィックは暗黙的に拒否されます。

## 管理者 (あるいはクラスター) ネットワークポリシー
<a name="_admin_or_cluster_network_policy"></a>

![\[EKS でネットワークポリシーが評価される順序を示した図\]](http://docs.aws.amazon.com/ja_jp/eks/latest/userguide/images/evaluation-order.png)


`ClusterNetworkPolicy` を使用すると、ネットワークセキュリティ標準をクラスター全体に適用できます。名前空間ごとにポリシーを繰り返し定義して維持するのではなく、単一のポリシーを使用して、名前空間に関係なく、クラスター内のさまざまなワークロードに対するネットワークアクセスコントロールを一元管理できます。

### ユースケース
<a name="_use_cases_2"></a>
+ EKS クラスター内のすべての (または一部の) ワークロードに対するネットワークアクセスコントロールを一元管理します。
+ クラスター全体にわたるデフォルトのネットワークセキュリティ体制を定義します。
+ 組織のセキュリティ標準を運用効率の高い方法でクラスターの範囲へと拡張します。

### 例
<a name="_example_2"></a>

以下のポリシーでは、他の名前空間からのクラスタートラフィックを明示的にブロックして、機密性の高いワークロード名前空間へのネットワークアクセスを防ぐことができます。

```
apiVersion: networking.k8s.aws/v1alpha1
kind: ClusterNetworkPolicy
metadata:
  name: protect-sensitive-workload
spec:
  tier: Admin
  priority: 10
  subject:
    namespaces:
      matchLabels:
        kubernetes.io/metadata.name: earth
  ingress:
    - action: Deny
      from:
      - namespaces:
          matchLabels: {} # Match all namespaces.
      name: select-all-deny-all
```

## 重要な注意事項
<a name="_important_notes"></a>

Amazon VPC CNI plugin for Kubernetes のネットワークポリシーは、以下に示した構成でサポートされています。
+ 標準と管理者のどちらのネットワークポリシーでも、Amazon VPC CNI プラグインのバージョンが 1.21.0 (またはそれ以降) です。
+ `IPv4` または `IPv6` アドレス用に設定されたクラスター。
+ [ポッド用のセキュリティグループ](security-groups-for-pods.md)でネットワークポリシーを使用できます。ネットワークポリシーを使用すると、クラスター内の通信をすべて制御できます。Pod 用のセキュリティグループを使用すると、Pod 内のアプリケーションから AWS サービスへのアクセスを制御できます。
+ *カスタムネットワーク*および*プレフィックス委任*でネットワークポリシーを使用できます。

## 考慮事項
<a name="cni-network-policy-considerations"></a>

 **アーキテクチャ** () 
+ Amazon VPC CNI plugin for Kubernetes を含むクラスターに Amazon VPC CNI plugin for Kubernetes ネットワークポリシーを適用する場合、Amazon EC2 Linux ノードにのみポリシーを適用できます。Fargate または Windows ノードにはポリシーを適用できません。
+ ネットワークポリシーは`IPv4` または `IPv6` アドレスのいずれかのみを適用しますが、両方は適用しません。`IPv4` クラスターではVPC CNI は `IPv4` アドレスをポッドに割り当て、`IPv4` ポリシーを適用します。`IPv6` クラスターではVPC CNI は `IPv6` アドレスをポッドに割り当て、`IPv6` ポリシーを適用します。`IPv6` クラスターに適用された `IPv4` ネットワークポリシールールは無視されます。`IPv4` クラスターに適用された `IPv6` ネットワークポリシールールは無視されます。

 **ネットワークポリシー** 
+ ネットワークポリシーはデプロイの一部である Pod にのみ適用されます。`metadata.ownerReferences` セットを持たないスタンドアロンの Pod ではネットワークポリシーを適用できません。
+ 同じ Pod に複数のネットワークポリシーを適用できます。同じ Pod を選択するポリシーが 2 つ以上設定されている場合、すべてのポリシーが Pod に適用されます。
+ ある IP アドレス範囲 (CIDR) に許可されるポートとプロトコルの組み合わせの最大数は、ネットワークポリシー全体で 24 です。`namespaceSelector` などのセレクターは、1 つ以上の CIDR に解決されます。複数のセレクターが 1 つの CIDR に解決される場合や、同一または異なるネットワークポリシーに同じ直接 CIDR を複数回指定した場合に、この制限が考慮されます。
+ どの Kubernetes サービスでも、サービスポートはコンテナポートと同じでなければなりません。名前付きポートを使用している場合はサービス仕様でも同じ名前を使用してください。

 **管理者ネットワークポリシー** 

1.  **管理者層ポリシー (最初に評価)**: 管理者階層のすべての ClusterNetworkPolicy が他のポリシーよりも先に評価されます。管理者階層内では、優先順位に従って (優先順位番号の最も小さいものから) ポリシーが処理されます。次にどうなるかは、アクションタイプによって決まります。
   +  **拒否アクション (最も高い優先順位)**: 拒否アクションを定義した管理者ポリシーがトラフィックと一致すると、そのトラフィックは他のポリシーとは関係なくすぐにブロックされます。ClusterNetworkPolicy や NetworkPolicy ルールはそれ以上処理されません。これにより、組織全体のセキュリティコントロールを名前空間レベルのポリシーで上書きできないようにしています。
   +  **許可アクション**: 拒否ルールが評価されると、許可アクションを定義した管理者ポリシーが優先順位に従って (優先順位番号の最も小さいものから) 処理されます。許可アクションに一致すると、トラフィックは受け入れられ、ポリシーはそれ以上評価されません。これらのポリシーは、ラベルセレクターに基づいて複数の名前空間に対するアクセスを許可して、特定のリソースにどのワークロードがアクセスできるかを一元的に制御できます。
   +  **パスアクション**: 管理階層ポリシーにパスアクションを定義すると、意思決定が下位の階層に委任されます。トラフィックがパスルールに一致すると、そのトラフィックの残りの管理者階層ルールの評価がスキップされ、NetworkPolicy 階層に直接進みます。これにより、管理者は特定のトラフィックパターンに対する制御をアプリケーションチームに明示的に委任できます。例えば、パスルールを使用すると、外部アクセスを厳密に制御しつつ、名前空間内のトラフィック管理を名前空間管理者に委任できます。

1.  **ネットワークポリシー階層**: 拒否または許可に一致する管理者階層ポリシーがない場合や、パスアクションが一致した場合、次は名前空間範囲の NetworkPolicy リソースが評価されます。これらは個々の名前空間内できめ細かく制御できるポリシーで、アプリケーションチームによって管理されます。名前空間範囲のポリシーでは、管理者ポリシーよりも厳しく制限を課すことができます。管理者ポリシーによる拒否の判断を上書きすることはできませんが、管理者ポリシーによって許可またはパスされたトラフィックをさらに制限できます。

1.  **ベースライン階層管理ポリシー**: トラフィックに一致する管理者ポリシーや名前空間範囲のポリシーがない場合、ベースライン階層の ClusterNetworkPolicy が評価されます。これにより、デフォルトのセキュリティ体制を名前空間範囲のポリシーで上書きできるため、管理者が組織全体のデフォルトを設定する一方で、チームが必要に応じて柔軟にカスタマイズできます。ベースラインポリシーは、優先順位に従って (優先順位番号の最も小さいものから) 評価されます。

1.  **デフォルト拒否 (一致するポリシーがない場合)**: この deny-by-default 動作により、明示的に認められた接続のみが許可されるため、強力なセキュリティ体制を維持できます。

 **移行** 
+ クラスターが現在サードパーティーソリューションを使用して Kubernetes ネットワークポリシーを管理している場合、同じポリシーを Amazon VPC CNI plugin for Kubernetes で使用できます。ただし、同じポリシーを管理しないように、既存のソリューションを削除する必要があります。

**警告**  
ネットワークポリシーソリューションを削除したら、そのソリューションが適用されていたすべてのノードを置き換えることをお勧めします。ソリューションのポッドが突然終了した場合に、トラフィックルールが残ってしまう可能性があるためです。

 **インストール**。
+ ネットワークポリシー機能では`policyendpoints.networking.k8s.aws` と呼ばれる `PolicyEndpoint` カスタムリソース定義  (CRD が作成され、必要になります。カスタムリソースの `PolicyEndpoint` オブジェクトは Amazon EKS によって管理されます。これらのリソースを変更または削除しないでください。
+ インスタンスロールの IAM 認証情報を使用するポッドを実行するか、EC2 IMDS に接続するポッドを実行する場合はEC2 IMDS へのアクセスをブロックするネットワークポリシーがないか慎重に確認してください。EC2 IMDS へのアクセスを許可するネットワークポリシーを追加する必要がある場合があります。詳細については「Amazon EC2 ユーザーガイド」の「[インスタンスメタデータとユーザーデータ](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)」を参照してください。

  *サービスアカウントの IAM ロール*または *EKS Pod Identity* を使用するポッドはEC2 IMDS にアクセスしません。
+ Amazon VPC CNI plugin for Kubernetes は、各ポッドの追加のネットワークインターフェイスにはネットワークポリシーを適用せず、各ポッドのプライマリインターフェイス (`eth0`) のみにネットワークポリシーを適用します。これは以下のアーキテクチャに影響します：
  +  `ENABLE_V4_EGRESS` 変数が `true` に設定された `IPv6` ポッド。この変数により、`IPv4` エグレス機能が IPv6 ポッドをクラスター外のエンドポイントなどの `IPv4` エンドポイントに接続できるようになります。`IPv4` エグレス機能は、ローカルループバック IPv4 アドレスを持つ追加のネットワークインターフェースを作成することで機能します。
  + Multus などのチェーンネットワークプラグインを使用する場合。これらのプラグインは各ポッドにネットワークインターフェースを追加するため、ネットワークポリシーはチェーンネットワークプラグインには適用されません。

# Kubernetes ネットワークポリシーを使用して Pod ネットワークトラフィックを制限する
<a name="cni-network-policy-configure"></a>

Kubernetes ネットワークポリシーを使用して、自分の Pod 間で送受信されるネットワークトラフィックを制限できます。詳細については、Kubernetes ドキュメントの「[ネットワークポリシー](https://kubernetes.io/docs/concepts/services-networking/network-policies/)」を参照してください。

この機能を使用するには以下を設定する必要があります：

1. Pod 起動時のポリシーの適用を設定します。これは VPC CNI `DaemonSet` の `aws-node` コンテナでできます。

1. アドオンのネットワークポリシーパラメータを有効にします。

1. Kubernetes ネットワークポリシーを使用するようにクラスターを設定します。

開始する前に、考慮事項を確認してください。詳細については「[考慮事項](cni-network-policy.md#cni-network-policy-considerations)」を参照してください。

## 前提条件
<a name="cni-network-policy-prereqs"></a>

この機能の前提条件は次のとおりです。

### 最小クラスターバージョン
<a name="cni-network-policy-minimum"></a>

既存の Amazon EKS クラスター。デプロイするには「[Amazon EKS の使用を開始する](getting-started.md)」を参照してください。クラスターは、次の表に示す Kubernetes バージョンとプラットフォームバージョンのいずれかを実行している必要があります。一覧にあるバージョンより後の Kubernetes とプラットフォームのバージョンもサポートされることにご注意ください。現在の Kubernetes バージョンを確認するには、次のコマンドの *my-cluster* をクラスターの名前に置き換えて、変更したコマンドを実行します。

```
aws eks describe-cluster --name my-cluster --query cluster.version --output text
```


| Kubernetes バージョン | プラットフォームバージョン | 
| --- | --- | 
|   `1.27.4`   |   `eks.5`   | 
|   `1.26.7`   |   `eks.6`   | 

### 最小 VPC CNI バージョン
<a name="cni-network-policy-minimum-vpc"></a>

標準 Kubernetes ネットワークポリシーと管理者ネットワークポリシーの両方を作成するには、VPC CNI プラグインのバージョン `1.21` を実行する必要があります。現在のバージョンは、次のコマンドで確認できます。

```
kubectl describe daemonset aws-node --namespace kube-system | grep amazon-k8s-cni: | cut -d : -f 3
```

バージョンが `1.21` より前の場合は、[Amazon VPC CNI を更新する (Amazon EKS アドオン)](vpc-add-on-update.md) を確認してバージョン `1.21` 以降にアップグレードしてください。

### 最小 Linux カーネルバージョン
<a name="cni-network-policy-minimum-linux"></a>

ノードにはバージョン `5.10` 以降の Linux カーネルが必要です。カーネルのバージョンは、`uname -r` で確認できます。Amazon EKS 最適化 Amazon Linux、Amazon EKS 最適化高速 Amazon Linux AMI、と Bottlerocket AMI の最新バージョンを使用している場合、既に必要なカーネルバージョンがインストールされています。

Amazon EKS 最適化高速 Amazon Linux AMI `v20231116` バージョン以降には、カーネルバージョン `5.10` があります。

## ステップ 1: Pod 起動時のポリシーの適用を設定する
<a name="cni-network-policy-configure-policy"></a>

Amazon VPC CNI plugin for Kubernetes はポッドのプロビジョニングと並行して、ポッドのネットワークポリシーを設定します。新しいポッドにすべてのポリシーが設定されるまで、新しいポッドのコンテナは*デフォルトの許可ポリシー*で起動します。これは*標準モード*と呼ばれます。デフォルトの許可ポリシーはすべての ingress トラフィックと egress トラフィックが新しいポッドとの間で許可されることを意味します。例えば、新しいポッドがアクティブなポリシーで更新されるまで、ポッドにはファイアウォールルールが適用されません (すべてのトラフィックが許可されます)。

変数 `NETWORK_POLICY_ENFORCING_MODE` を `strict` に設定すると、VPC CNI を使用するポッドは*デフォルトの拒否ポリシー*で起動し、その後ポリシーが設定されます。これは *Strict モード*と呼ばれます。Strict モードではポッドがクラスター内でアクセスする必要があるすべてのエンドポイントにネットワークポリシーが必要です。この要件は CoreDNS ポッドに適用されることに注意してください。デフォルトの拒否ポリシーはホストネットワークを使用するポッドには設定されていません。

このデフォルトのネットワークポリシーはVPC CNI `DaemonSet` の `aws-node` コンテナで環境変数 `NETWORK_POLICY_ENFORCING_MODE` を `strict` に設定することで変更できます。

```
env:
  - name: NETWORK_POLICY_ENFORCING_MODE
    value: "strict"
```

## ステップ 2: アドオンのネットワークポリシーパラメータを有効にする
<a name="enable-network-policy-parameter"></a>

ネットワークポリシー機能はデフォルトでノード上のポート `8162` をメトリクスに使用します。また、この機能はヘルスプローブにポート `8163` を使用します。そのノード上、またはこれらのポートを使用する必要があるポッド内で他のアプリケーションを実行すると、そのアプリは実行できません。VPC CNI バージョン `v1.14.1` 以降で、これらのポートを変更できます。

アドオンのネットワークポリシーパラメータを有効にするには次の手順に従います。

### AWS マネジメントコンソール
<a name="cni-network-policy-console"></a>

1. [Amazon EKS コンソール](https://console.aws.amazon.com/eks/home#/clusters)を開きます。

1. 左のナビゲーションペインで、**[クラスター]** を選択し、 Amazon VPC CNI アドオンを設定するクラスターの名前を選択してください。

1. **[アドオン]** タブを選択してください。

1. アドオンボックスの右上にあるボックスを選択し、次に **[編集]** を選択してください。

1. **[`Amazon VPC CNI` を設定]** ページで、次の操作を行います：

   1. **[バージョン]** リストで `v1.14.0-eksbuild.3` 以降のバージョンを選択してください。

   1. **[オプションの構成設定]** を展開します。

   1. **[設定値]** に JSON キー `"enableNetworkPolicy":` と値 `"true"` を入力します。結果のテキストは有効な JSON オブジェクトでなければなりません。このキーと値だけがテキストボックス内のデータである場合はキーと値を中括弧 `{ }` で囲みます。

      次の例ではネットワークポリシー機能が有効になっており、メトリクスとヘルスプローブがデフォルトのポート番号に設定されています：

      ```
      {
          "enableNetworkPolicy": "true",
          "nodeAgent": {
              "healthProbeBindAddr": "8163",
              "metricsBindAddr": "8162"
          }
      }
      ```

### Helm
<a name="cni-network-helm"></a>

`helm` を通して Amazon VPC CNI plugin for Kubernetes をインストールしている場合、設定を更新してポートを変更できます。

1. 次に、以下のコマンドを実行して、ポートを変更します。キー `nodeAgent.metricsBindAddr` または キー `nodeAgent.healthProbeBindAddr` の値にそれぞれポート番号を設定します。

   ```
   helm upgrade --set nodeAgent.metricsBindAddr=8162 --set nodeAgent.healthProbeBindAddr=8163 aws-vpc-cni --namespace kube-system eks/aws-vpc-cni
   ```

### kubectl
<a name="cni-network-policy-kubectl"></a>

1. エディターで `aws-node``DaemonSet` を開きます。

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

1. VPC CNI `aws-node` デーモンセットマニフェストの `aws-network-policy-agent` コンテナで、以下の `args:` のコマンド引数でポート番号を置き換えます。

   ```
       - args:
               - --metrics-bind-addr=:8162
               - --health-probe-bind-addr=:8163
   ```

## ステップ 3: Kubernetes ネットワークポリシーを使用するようにクラスターを設定する
<a name="cni-network-policy-setup"></a>

これはAmazon EKS アドオンまたはセルフマネージドアドオンに対して設定できます。

### Amazon EKS アドオン
<a name="cni-network-policy-setup-procedure-add-on"></a>

AWS CLI を使用すると、次のコマンドを実行して、Kubernetes ネットワークポリシーを使用するようにクラスターを設定できます。`my-cluster` をクラスターの名前に置き換え、IAM ロール ARN を使用するロールに置き換えます。

```
aws eks update-addon --cluster-name my-cluster --addon-name vpc-cni --addon-version v1.14.0-eksbuild.3 \
    --service-account-role-arn arn:aws:iam::123456789012:role/AmazonEKSVPCCNIRole \
    --resolve-conflicts PRESERVE --configuration-values '{"enableNetworkPolicy": "true"}'
```

AWS マネジメントコンソールを使用してこれを設定するには、以下の手順に従います。

1. [Amazon EKS コンソール](https://console.aws.amazon.com/eks/home#/clusters)を開きます。

1. 左のナビゲーションペインで、**[クラスター]** を選択し、 Amazon VPC CNI アドオンを設定するクラスターの名前を選択してください。

1. **[アドオン]** タブを選択してください。

1. アドオンボックスの右上にあるボックスを選択し、次に **[編集]** を選択してください。

1. **[`Amazon VPC CNI` を設定]** ページで、次の操作を行います：

   1. **[バージョン]** リストで `v1.14.0-eksbuild.3` 以降のバージョンを選択してください。

   1. **[オプションの構成設定]** を展開します。

   1. **[設定値]** に JSON キー `"enableNetworkPolicy":` と値 `"true"` を入力します。結果のテキストは有効な JSON オブジェクトでなければなりません。このキーと値だけがテキストボックス内のデータである場合はキーと値を中括弧 `{ }` で囲みます。次の例はネットワークポリシーが有効になっていることを示しています：

      ```
      { "enableNetworkPolicy": "true" }
      ```

      次のスクリーンショットはこのシナリオの例を示しています。  
![\[オプション設定でネットワークポリシーが設定されている VPC CNI アドオンを示す <shared id="consolelong"/>。\]](http://docs.aws.amazon.com/ja_jp/eks/latest/userguide/images/console-cni-config-network-policy.png)

### セルフマネージド型アドオン
<a name="cni-network-policy-setup-procedure-self-managed-add-on"></a>

`helm` を通して Amazon VPC CNI plugin for Kubernetes をインストールしている場合、設定を更新してネットワークポリシーを有効にできます。

1. 次のコマンドを実行してネットワークポリシーを有効にします。

   ```
   helm upgrade --set enableNetworkPolicy=true aws-vpc-cni --namespace kube-system eks/aws-vpc-cni
   ```

1. エディターで `amazon-vpc-cni``ConfigMap` を開きます。

   ```
   kubectl edit configmap -n kube-system amazon-vpc-cni -o yaml
   ```

1. 次の行を `ConfigMap` の`data`に追加します。

   ```
   enable-network-policy-controller: "true"
   ```

   行を追加すると、`ConfigMap` は次の例のようになるはずです。

   ```
   apiVersion: v1
    kind: ConfigMap
    metadata:
     name: amazon-vpc-cni
     namespace: kube-system
    data:
     enable-network-policy-controller: "true"
   ```

1. エディターで `aws-node``DaemonSet` を開きます。

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

   1. VPC CNI `aws-node` デーモンセットマニフェストの `aws-network-policy-agent` コンテナで、`args:` のコマンド引数 `--enable-network-policy=false` の `false` を `true` に置き換えます。

      ```
           - args:
              - --enable-network-policy=true
      ```

## ステップ 4. 次のステップ
<a name="cni-network-policy-setup-procedure-confirm"></a>

設定が完了したら、`aws-node` ポッドがクラスターで実行されていることを確認します。

```
kubectl get pods -n kube-system | grep 'aws-node\|amazon'
```

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

```
aws-node-gmqp7                                          2/2     Running   1 (24h ago)   24h
aws-node-prnsh                                          2/2     Running   1 (24h ago)   24h
```

バージョン `1.14` 以降の `aws-node` ポッドには 2 つのコンテナがあります。以前のバージョンではネットワークポリシーが無効になっている場合、`aws-node` ポッドにコンテナは 1 つしか存在しません。

これで、Kubernetes ネットワークポリシーをクラスターにデプロイできます。

Kubernetes ネットワークポリシーを実装するために、Kubernetes の `NetworkPolicy` オブジェクトまたは `ClusterNetworkPolicy` オブジェクトを作成してクラスターにデプロイできます。`NetworkPolicy` オブジェクトの範囲は名前空間に限定されますが、`ClusterNetworkPolicy` オブジェクトの範囲はクラスター全体または複数の名前空間に限定できます。ラベルセレクター、名前空間、および IP アドレス範囲に基づいて、Pod 間のトラフィックを許可または拒否するポリシーを実装します。`NetworkPolicy` オブジェクトの作成の詳細については Kubernetes ドキュメントの「[ネットワークポリシー](https://kubernetes.io/docs/concepts/services-networking/network-policies/#networkpolicy-resource)」を参照してください。

Kubernetes `NetworkPolicy` オブジェクトの適用は、Extended Berkeley Packet Filter (eBPF) を使用して実装されます。`iptables` をベースにした実装に関連して、CPU 使用率の低下やシーケンシャルルックアップの回避など、低レイテンシーを実現し、パフォーマンス特性を発揮します。さらに、eBPF プローブは、複雑なカーネルレベルの問題のデバッグやオブザーバビリティの向上に役立つ、コンテキスト豊富なデータへのアクセスを提供します。Amazon EKS は、プローブを利用して各ノードのポリシー結果をログに記録し、そのデータを外部のログコレクターにエクスポートしてデバッグに役立てる eBPF ベースのエクスポーターをサポートしています。詳細については「[eBPFドキュメント](https://ebpf.io/what-is-ebpf/#what-is-ebpf)」を参照してください。

# Amazon EKS Pod ネットワークトラフィックの Kubernetes ネットワークポリシーを無効にする
<a name="network-policy-disable"></a>

Kubernetes ネットワークポリシーを無効にして Amazon EKS Pod ネットワークトラフィックの制限を停止する

1. すべての Kubernetes ネットワークポリシーを一覧表示します。

   ```
   kubectl get netpol -A
   ```

1. 各 Kubernetes ネットワークポリシーを削除します。ネットワークポリシーを無効にする前に、すべてのネットワークポリシーを削除する必要があります。

   ```
   kubectl delete netpol <policy-name>
   ```

1. エディタで aws-node DaemonSet を開きます。

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

1. VPC CNI `aws-node` デーモンセットマニフェストの `aws-network-policy-agent` コンテナで、`args:` のコマンド引数 `--enable-network-policy=true` の `true` を `false` に置き換えます。

   ```
        - args:
           - --enable-network-policy=true
   ```

# Amazon EKS の Kubernetes ネットワークポリシーのトラブルシューティング
<a name="network-policies-troubleshooting"></a>

これは、Amazon VPC CNI のネットワークポリシー機能のトラブルシューティングガイドです。

このガイドでは、以下について説明します。
+ インストール情報、CRD、RBAC アクセス許可 [新しい `policyendpoints` CRD とアクセス許可](#network-policies-troubleshooting-permissions) 
+ ネットワークポリシーの問題の診断時に調べるログ [ネットワークポリシーのログ](#network-policies-troubleshooting-flowlogs) 
+ トラブルシューティング用の eBPF SDK ツール群の実行
+ 既知の問題と解決策 [既知の問題と解決策](#network-policies-troubleshooting-known-issues) 

**注記**  
ネットワークポリシーは、Kubernetes *デプロイメント*によって作成されたポッドにのみ適用されることに注意してください。VPC CNI のネットワークポリシーにおける他の制限事項については、「[考慮事項](cni-network-policy.md#cni-network-policy-considerations)」を参照してください。

[ネットワークポリシーのログ](#network-policies-troubleshooting-flowlogs)を読み、[eBPF SDK](#network-policies-ebpf-sdk) のツールを実行することにより、ネットワークポリシーを使用するネットワーク接続をトラブルシューティングおよび調査できます。

## 新しい `policyendpoints` CRD とアクセス許可
<a name="network-policies-troubleshooting-permissions"></a>
+ CRD: `policyendpoints.networking.k8s.aws` 
+ Kubernetes API: `v1.networking.k8s.io` と呼ばれる `apiservice` 
+ Kubernetes リソース: `Kind: NetworkPolicy` 
+ RBAC: `aws-node` と呼ばれる `ClusterRole` (VPC CNI)、`eks:network-policy-controller` と呼ばれる `ClusterRole` (EKS クラスターコントロールプレーンのネットワークポリシーコントローラー)

ネットワークポリシーの場合、VPC CNI は `policyendpoints.networking.k8s.aws` と呼ばれる新しい `CustomResourceDefinition` (CRD) を作成します。VPC CNI には CRD を作成し、この CRD および VPC CNI (`eniconfigs.crd.k8s.amazonaws.com`) によってインストールされたその他の CRD の CustomResources (CR) を作成するアクセス許可が必要です。両方の CRD は GitHub の [`crds.yaml` ファイル](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/charts/aws-vpc-cni/crds/customresourcedefinition.yaml)で利用できます。具体的には、VPC CNI には `policyendpoints` の「get」、「list」、「watch」動詞のアクセス許可が必要です。

Kubernetes *ネットワークポリシー*は、`v1.networking.k8s.io` と呼ばれる `apiservice` の一部であり、これはポリシー YAML ファイル内では `apiversion: networking.k8s.io/v1` となります。VPC CNI `DaemonSet` には、Kubernetes API のこの部分を使用するアクセス許可が必要です。

VPC CNI アクセス許可は、`aws-node` と呼ばれる `ClusterRole` にあります。`ClusterRole` オブジェクトは、名前空間にグループ化されないことに注意してください。次の内容では、クラスターの `aws-node` が示されます。

```
kubectl get clusterrole aws-node -o yaml
```

```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/instance: aws-vpc-cni
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: aws-node
    app.kubernetes.io/version: v1.19.4
    helm.sh/chart: aws-vpc-cni-1.19.4
    k8s-app: aws-node
  name: aws-node
rules:
- apiGroups:
  - crd.k8s.amazonaws.com
  resources:
  - eniconfigs
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  - events.k8s.io
  resources:
  - events
  verbs:
  - create
  - patch
  - list
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/status
  verbs:
  - get
- apiGroups:
  - vpcresources.k8s.aws
  resources:
  - cninodes
  verbs:
  - get
  - list
  - watch
  - patch
```

また、新しいコントローラーは各 EKS クラスターのコントロールプレーンで実行されます。コントローラーは、`eks:network-policy-controller` と呼ばれる `ClusterRole` のアクセス許可を使用します。次の内容では、クラスターの `eks:network-policy-controller` が示されます。

```
kubectl get clusterrole eks:network-policy-controller -o yaml
```

```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/name: amazon-network-policy-controller-k8s
  name: eks:network-policy-controller
rules:
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints
  verbs:
  - create
  - delete
  - get
  - list
  - patch
  - update
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/finalizers
  verbs:
  - update
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/status
  verbs:
  - get
  - patch
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - networkpolicies
  verbs:
  - get
  - list
  - patch
  - update
  - watch
```

## ネットワークポリシーのログ
<a name="network-policies-troubleshooting-flowlogs"></a>

ネットワークポリシーによって接続が許可されるか拒否されるかについての VPC CNI による各判定は、*フローログ*に記録されます。各ノードのネットワークポリシーログにはネットワークポリシーが設定されているすべてのポッドのフローログが含まれます。ネットワークポリシーログは `/var/log/aws-routed-eni/network-policy-agent.log` に保存されます。次の例は `network-policy-agent.log` ファイルからのものです。

```
{"level":"info","timestamp":"2023-05-30T16:05:32.573Z","logger":"ebpf-client","msg":"Flow Info: ","Src
IP":"192.168.87.155","Src Port":38971,"Dest IP":"64.6.160","Dest
Port":53,"Proto":"UDP","Verdict":"ACCEPT"}
```

ネットワークポリシーログはデフォルトで無効になっています。ネットワークポリシーログを有効にするには次の手順に従います。

**注記**  
ネットワークポリシーログには、VPC CNI `aws-node` `DaemonSet` マニフェストの `aws-network-policy-agent` コンテナ用に vCPU をさらに 1 つ追加する必要があります。

### Amazon EKS アドオン
<a name="cni-network-policy-flowlogs-addon"></a>

 ** AWS マネジメントコンソール **   

1. [Amazon EKS コンソール](https://console.aws.amazon.com/eks/home#/clusters)を開きます。

1. 左のナビゲーションペインで、**[クラスター]** を選択し、 Amazon VPC CNI アドオンを設定するクラスターの名前を選択してください。

1. **[アドオン]** タブを選択してください。

1. アドオンボックスの右上にあるボックスを選択し、次に **[編集]** を選択してください。

1. ***Amazon VPC CNI *の設定**ページで、次の手順に従います。

   1. **[バージョン]** ドロップダウンリストで `v1.14.0-eksbuild.3` 以降のバージョンを選択してください。

   1. **[オプションの構成設定]** を展開します。

   1. 最上位の JSON キー `"nodeAgent":` を入力してください。値は **[設定値]** にキー `"enablePolicyEventLogs":` と `"true"` の値を持つオブジェクトです。結果のテキストは有効な JSON オブジェクトでなければなりません。次の例はネットワークポリシーとネットワークポリシーログが有効になっており、ネットワークポリシーログが CloudWatch Logs に送信されていることを示しています。

      ```
      {
          "enableNetworkPolicy": "true",
          "nodeAgent": {
              "enablePolicyEventLogs": "true"
          }
      }
      ```

次のスクリーンショットはこのシナリオの例を示しています。

![\[オプション設定でネットワークポリシーおよび CloudWatch ログが設定されている VPC CNI アドオンを示す <shared id="consolelong"/>。\]](http://docs.aws.amazon.com/ja_jp/eks/latest/userguide/images/console-cni-config-network-policy-logs.png)


 AWS CLI  

1. 次の AWS CLI コマンドを実行してください。`my-cluster` をクラスターの名前に置き換え、IAM 役割 ARN を使用する役割に置き換えます。

   ```
   aws eks update-addon --cluster-name my-cluster --addon-name vpc-cni --addon-version v1.14.0-eksbuild.3 \
       --service-account-role-arn arn:aws:iam::123456789012:role/AmazonEKSVPCCNIRole \
       --resolve-conflicts PRESERVE --configuration-values '{"nodeAgent": {"enablePolicyEventLogs": "true"}}'
   ```

### セルフマネージド型アドオン
<a name="cni-network-policy-flowlogs-selfmanaged"></a>

Helm  
`helm` を通して Amazon VPC CNI plugin for Kubernetes をインストールしている場合、設定を更新してネットワークポリシーログを記述できます。  

1. 次のコマンドを実行してネットワークポリシーを有効にします。

   ```
   helm upgrade --set nodeAgent.enablePolicyEventLogs=true aws-vpc-cni --namespace kube-system eks/aws-vpc-cni
   ```

kubectl  
`kubectl` を通して Amazon VPC CNI plugin for Kubernetes をインストールしている場合、設定を更新してネットワークポリシーログを記述できます。  

1. エディターで `aws-node``DaemonSet` を開きます。

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

1. VPC CNI `aws-node` `DaemonSet` マニフェストの `aws-network-policy-agent` コンテナで、`args:` のコマンド引数 `--enable-policy-event-logs=false` で `false` を `true` に置き換えます。

   ```
        - args:
           - --enable-policy-event-logs=true
   ```

### ネットワークポリシーログを Amazon CloudWatch Logs に送信する
<a name="network-policies-cloudwatchlogs"></a>

Amazon CloudWatch Logs などのサービスを使用して、ネットワークポリシーログをモニタリングできます。次の方法を使用して、ネットワークポリシーログを CloudWatch Logs に送信できます。

EKS クラスターの場合、ポリシー ログは `/aws/eks/cluster-name/cluster/` の下に配置され、セルフマネージド K8S クラスターの場合、ログは `/aws/k8s-cluster/cluster/` の下に配置されます。

#### Amazon VPC CNI plugin for Kubernetes によるネットワークポリシーログの送信
<a name="network-policies-cwl-agent"></a>

ネットワークポリシーを有効にすると、2 つ目のコンテナが*ノードエージェント*の `aws-node` ポッドに追加されます。このノードエージェントはネットワークポリシーログを CloudWatch Logs に送信できます。

**注記**  
ノードエージェントはネットワークポリシーログのみを送信します。VPC CNI によって作成された他のログは含まれません。

##### 前提条件
<a name="cni-network-policy-cwl-agent-prereqs"></a>
+ VPC CNI に使用している IAM 役割に、次の権限をスタンザまたは個別のポリシーとして追加します。

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": [
                  "logs:DescribeLogGroups",
                  "logs:CreateLogGroup",
                  "logs:CreateLogStream",
                  "logs:PutLogEvents"
              ],
              "Resource": "*"
          }
      ]
  }
  ```

##### Amazon EKS アドオン
<a name="cni-network-policy-cwl-agent-addon"></a>

 ** AWS マネジメントコンソール **   

1. [Amazon EKS コンソール](https://console.aws.amazon.com/eks/home#/clusters)を開きます。

1. 左のナビゲーションペインで、**[クラスター]** を選択し、 Amazon VPC CNI アドオンを設定するクラスターの名前を選択してください。

1. **[アドオン]** タブを選択してください。

1. アドオンボックスの右上にあるボックスを選択し、次に **[編集]** を選択してください。

1. ***Amazon VPC CNI *の設定**ページで、次の手順に従います。

   1. **[バージョン]** ドロップダウンリストで `v1.14.0-eksbuild.3` 以降のバージョンを選択してください。

   1. **[オプションの構成設定]** を展開します。

   1. 最上位の JSON キー `"nodeAgent":` を入力してください。値は **[設定値]** にキー `"enableCloudWatchLogs":` と `"true"` の値を持つオブジェクトです。結果のテキストは有効な JSON オブジェクトでなければなりません。次の例はネットワークポリシーとネットワークポリシーログが有効になっており、ログが CloudWatch Logs に送信されていることを示しています。

      ```
      {
          "enableNetworkPolicy": "true",
          "nodeAgent": {
              "enablePolicyEventLogs": "true",
              "enableCloudWatchLogs": "true",
          }
      }
      ```
次のスクリーンショットはこのシナリオの例を示しています。

![\[オプション設定でネットワークポリシーおよび CloudWatch ログが設定されている VPC CNI アドオンを示す <shared id="consolelong"/>。\]](http://docs.aws.amazon.com/ja_jp/eks/latest/userguide/images/console-cni-config-network-policy-logs-cwl.png)


 ** AWSCLI**   

1. 次の AWS CLI コマンドを実行してください。`my-cluster` をクラスターの名前に置き換え、IAM 役割 ARN を使用する役割に置き換えます。

   ```
   aws eks update-addon --cluster-name my-cluster --addon-name vpc-cni --addon-version v1.14.0-eksbuild.3 \
       --service-account-role-arn arn:aws:iam::123456789012:role/AmazonEKSVPCCNIRole \
       --resolve-conflicts PRESERVE --configuration-values '{"nodeAgent": {"enablePolicyEventLogs": "true", "enableCloudWatchLogs": "true"}}'
   ```

##### セルフマネージド型アドオン
<a name="cni-network-policy-cwl-agent-selfmanaged"></a>

 **Helm**   
`helm` を通して Amazon VPC CNI plugin for Kubernetes をインストールしている場合、設定を更新してネットワークポリシーログを CloudWatch Logs に送信できます。  

1. 次のコマンドを実行してネットワークポリシーログを有効にし、CloudWatch Logs に送信します。

   ```
   helm upgrade --set nodeAgent.enablePolicyEventLogs=true --set nodeAgent.enableCloudWatchLogs=true aws-vpc-cni --namespace kube-system eks/aws-vpc-cni
   ```

 **kubectl**   

1. エディターで `aws-node``DaemonSet` を開きます。

   ```
   kubectl edit daemonset -n kube-system aws-node
   ```

1. VPC CNI `aws-node` `DaemonSet` マニフェストの `aws-network-policy-agent` コンテナで、`args:` の 2 つのコマンド引数 `--enable-policy-event-logs=false` および `--enable-cloudwatch-logs=false` の `false` を `true` に置き換えます。

   ```
        - args:
           - --enable-policy-event-logs=true
           - --enable-cloudwatch-logs=true
   ```

#### Fluent Bit `DaemonSet`と一緒にネットワークポリシーログの送信
<a name="network-policies-cwl-fluentbit"></a>

`DaemonSet` で Fluent Bit を使用してノードからログを送信する場合、ネットワークポリシーのネットワークポリシーログを含めるように設定を追加できます。次の設定例を使用できます。

```
    [INPUT]
        Name              tail
        Tag               eksnp.*
        Path              /var/log/aws-routed-eni/network-policy-agent*.log
        Parser            json
        DB                /var/log/aws-routed-eni/flb_npagent.db
        Mem_Buf_Limit     5MB
        Skip_Long_Lines   On
        Refresh_Interval  10
```

## eBPF SDK の内容
<a name="network-policies-ebpf-sdk"></a>

Amazon VPC CNI plugin for Kubernetes は、複数のツールをまとめた eBPF SDK コレクションをノードにインストールします。eBPF SDK ツールを使用して、ネットワークポリシーの問題を特定できます。例えば、次のコマンドはノードで実行されているプログラムを一覧表示します。

```
sudo /opt/cni/bin/aws-eks-na-cli ebpf progs
```

このコマンドを実行するために、任意の方法を使用してノードに接続できます。

## 既知の問題と解決策
<a name="network-policies-troubleshooting-known-issues"></a>

次のセクションでは、Amazon VPC CNI ネットワークポリシーの機能に関する既知の問題とその解決策について説明します。

### enable-policy-event-logs が「false」に設定されているにも関わらず、ネットワークポリシーログが生成される
<a name="network-policies-troubleshooting-policy-event-logs"></a>

 **問題**: `enable-policy-event-logs` 設定が `false` に設定されている場合でも、EKS VPC CNI によってネットワークポリシーログが生成される。

 **解決策**: `enable-policy-event-logs` 設定はポリシー「決定」ログのみを無効にしますが、すべてのネットワークポリシーエージェントのログ記録が無効になるわけではありません。この動作については、GitHub の「[aws-network-policy-agent README](https://github.com/aws/aws-network-policy-agent/)」に記載されています。ログ記録を完全に無効にするには、他のログ記録設定の調整が必要な場合があります。

### ネットワークポリシーマップのクリーンアップ問題
<a name="network-policies-troubleshooting-map-cleanup"></a>

 **問題**: ポッドが削除された後も、ネットワーク `policyendpoint` が残り続けてクリーンアップされない問題。

 **解決策**: この問題は、VPC CNI アドオンバージョン 1.19.3-eksbuild.1 による問題で発生しました。この問題を解決するには、VPC CNI アドオンの新しいバージョンに更新してください。

### ネットワークポリシーが適用されない
<a name="network-policies-troubleshooting-policyendpoint"></a>

 **問題**: Amazon VPC CNI プラグインでネットワークポリシー機能が有効になっているが、ネットワークポリシーが正しく適用されない。

ネットワークポリシー `kind: NetworkPolicy` を作成してもポッドに影響を与えない場合、ポリシーエンドポイントオブジェクトがポッドと同じ名前空間で作成されていることを確認します。名前空間に `policyendpoint` オブジェクトがない場合、ネットワークポリシーコントローラー (EKS クラスターの一部) が、ネットワークポリシーエージェント (VPC CNI の一部) が適用するためのネットワークポリシールールを作成できなかったということです。

 **解決策**: この解決策は、VPC CNI (`ClusterRole`: `aws-node`) およびネットワークポリシーコントローラー (`ClusterRole`: `eks:network-policy-controller`) のアクセス許可を修正し、Kyverno などのポリシー実施ツールでこれらのアクションを許可することです。Kyverno ポリシーが `policyendpoint` オブジェクトの作成をブロックしていないことを確認してください。必要なアクセス許可については、「[新しい `policyendpoints` CRD とアクセス許可](#network-policies-troubleshooting-permissions)」で前のセクションを参照してください。

### strict モードでポリシーを削除してもポッドがデフォルトの拒否状態に戻らない
<a name="network-policies-troubleshooting-strict-mode-fallback"></a>

 **問題**: ネットワークポリシーが strict モードで有効になっている場合、ポッドはデフォルト拒否ポリシーで開始されます。ポリシーが適用されると、指定されたエンドポイントへのトラフィックが許可されます。しかし、ポリシーが削除されても、ポッドがデフォルト拒否状態に戻らず、代わりにデフォルト許可状態になってしまいます。

 **解決策**: この問題は、ネットワークポリシーエージェント 1.2.0 のリリースを含む VPC CNI リリース 1.19.3 で修正されました。修正後は、strict モードを有効にすると、ポリシーが削除されるとポッドは期待どおりにデフォルト拒否状態に戻ります。

### ポッドの起動レイテンシーのセキュリティグループ
<a name="network-policies-troubleshooting-sgfp-latency"></a>

 **問題**: EKS でポッド機能のセキュリティグループを使用すると、ポッドの起動レイテンシーが増加する。

 **解決策**: レイテンシーは、VPC リソースコントローラーがポッドのブランチ ENI を作成するために使用する `CreateNetworkInterface` API の API スロットリングによるリソースコントローラーのレート制限によるものです。このオペレーションのアカウントの API 制限を確認し、必要に応じて上限の引き上げをリクエストすることを検討してください。

### vpc.amazonaws.com/pod-eni の不足による FailedScheduling
<a name="network-policies-troubleshooting-insufficient-pod-eni"></a>

 **問題**: 以下のエラーにより、ポッドのスケジューリングが失敗する: `FailedScheduling 2m53s (x28 over 137m) default-scheduler 0/5 nodes are available: 5 Insufficient vpc.amazonaws.com/pod-eni. preemption: 0/5 nodes are available: 5 No preemption victims found for incoming pod.` 

 **解決策**: 前の問題と同様に、ポッドにセキュリティグループを割り当てると、ポッドスケジューリングのレイテンシーが増加し、各 ENI を追加する時間の CNI しきい値を超えて増加するため、ポッド起動が失敗する原因になります。これは、Podのセキュリティグループを使用するときに予期される動作です。ワークロードアーキテクチャを設計する際、スケジューリングの影響を考慮してください。

### IPAM の接続問題とセグメンテーション障害
<a name="network-policies-troubleshooting-systemd-udev"></a>

 **問題**: IPAM の接続問題、スロットリングのリクエスト、セグメンテーションの障害など、複数のエラーが発生する。
+  `Checking for IPAM connectivity …​` 
+  `Throttling request took 1.047064274s` 
+  `Retrying waiting for IPAM-D` 
+  `panic: runtime error: invalid memory address or nil pointer dereference` 

 **解決策**: AL2023 で `systemd-udev` をインストールすると、破損を引き起こすポリシーでファイルが書き換えられるため、この問題が発生します。パッケージが更新された別の `releasever` に更新する場合、またはパッケージ自体を手動で更新する場合に発生する可能性があります。AL2023 ノードでは、`systemd-udev` をインストールまたは更新しないでください。

### デバイス名による検索失敗エラー
<a name="network-policies-troubleshooting-device-not-found"></a>

 **問題**: エラーメッセージ: `{"level":"error","ts":"2025-02-05T20:27:18.669Z","caller":"ebpf/bpf_client.go:578","msg":"failed to find device by name eni9ea69618bf0: %!w(netlink.LinkNotFoundError={0xc000115310})"}` 

 **解決策**: この問題は、Amazon VPC CNI ネットワークポリシーエージェント (v1.2.0) の最新バージョンで特定されて修正されています。この問題を解決するには、VPC CNI の最新バージョンに更新してください。

### Multus CNI イメージの CVE 脆弱性
<a name="network-policies-troubleshooting-cve-multus"></a>

 **問題**: 拡張された EKS ImageScan CVE レポートで、Multus CNI イメージバージョン v4.1.4-eksbuild.2\$1thick の脆弱性が特定されている。

 **解決策**: 脆弱性のない Multus CNI イメージの新しいバージョンおよび新しい Network Policy Controller イメージに更新します。スキャナーを更新することで、以前のバージョンで見つかった脆弱性に対処できます。

### ログのフロー情報の「DENY」判定
<a name="network-policies-troubleshooting-flow-info-deny"></a>

 **問題**: ネットワークポリシーログに次の DENY 判定が表示される: `{"level":"info","ts":"2024-11-25T13:34:24.808Z","logger":"ebpf-client","caller":"events/events.go:193","msg":"Flow Info: ","Src IP":"","Src Port":9096,"Dest IP":"","Dest Port":56830,"Proto":"TCP","Verdict":"DENY"}` 

 **解決策**: この問題は、ネットワークポリシーコントローラーの新しいバージョンで解決されています。ログ記録の問題を解決するには、最新の EKS プラットフォームバージョンに更新してください。

### Calico から移行後のポッド間の通信問題
<a name="network-policies-troubleshooting-calico-migration"></a>

 **問題**: EKS クラスターをバージョン 1.30 にアップグレードし、ネットワークポリシーを Calico から Amazon VPC CNI に切り替えた後、ネットワークポリシーが適用されるとポッド間の通信が失敗する。ネットワークポリシーを削除すると通信は回復する。

 **解決策**: VPC CNI のネットワークポリシーエージェントには、Calico ほど多くのポートを指定することができません。代わりに、ネットワークポリシーでポート範囲を使用します。ネットワークポリシーの各 `ingress:` または `egress:` セレクターの各プロトコルにおけるポートの一意の組み合わせの最大数は 24 です。ポート範囲を使用して一意のポート数を減らし、この制限を回避します。

### ネットワークポリシーエージェントがスタンドアロンポッドをサポートしない
<a name="network-policies-troubleshooting-standalone-pods"></a>

 **問題**: スタンドアロンポッドに適用されるネットワークポリシーは、一貫性のない動作を示す可能性がある。

 **解決策**: 現在、ネットワークポリシーエージェントは、デプロイメント/レプリカセットの一部としてデプロイされたポッドのみをサポートしています。ネットワークポリシーがスタンドアロンポッドに適用された場合、一貫性のない動作を示す可能性があります。これは、このページの上部の「[考慮事項](cni-network-policy.md#cni-network-policy-considerations)」および GitHub の「[aws-network-policy-agent の GitHub 問題 \$1327](https://github.com/aws/aws-network-policy-agent/issues/327)」に記載されています。整合性のあるネットワークポリシーの動作のため、デプロイまたはレプリカセットの一部としてポッドをデプロイします。

# Amazon EKS のネットワークポリシーの星型デモ
<a name="network-policy-stars-demo"></a>

このデモでは、Amazon EKS クラスターにフロントエンド、バックエンド、およびクライアントサービスを作成します。また、このデモでは、各サービス間で利用可能な入力および出力のパスを示す管理グラフィカルユーザーインターフェースが作成されます。実稼働ワークロードを実行しないクラスターでデモを完了することをお勧めします。

ネットワークポリシーを作成する前に、サービスはすべて、双方向に通信できます。ネットワークポリシーを適用すると、クライアントはフロントエンドサービスとのみ通信でき、バックエンドはフロントエンドからのみトラフィックを受け付けます。

1. フロントエンド、バックエンド、クライアント、および管理ユーザーインターフェイスサービスを適用します。

   ```
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/namespace.yaml
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/management-ui.yaml
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/backend.yaml
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/frontend.yaml
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/client.yaml
   ```

1. クラスター上の Pod をすべて表示します。

   ```
   kubectl get pods -A
   ```

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

   出力では、次の出力に示す名前空間にポッドが表示されます。`READY` 列内のポッドの *NAMES* とポッド数は、次の出力とは異なります。似たような名前のポッドが見えて、それらがすべて `STATUS` 列内に `Running` を持つまで続けないでください。

   ```
   NAMESPACE         NAME                                       READY   STATUS    RESTARTS   AGE
   [...]
   client            client-xlffc                               1/1     Running   0          5m19s
   [...]
   management-ui     management-ui-qrb2g                        1/1     Running   0          5m24s
   stars             backend-sz87q                              1/1     Running   0          5m23s
   stars             frontend-cscnf                             1/1     Running   0          5m21s
   [...]
   ```

1. 管理ユーザーインターフェイスに接続するには、クラスターで実行されているサービスの `EXTERNAL-IP` に接続します。

   ```
   kubectl get service/management-ui -n management-ui
   ```

1. ブラウザーを開いて、前のステップの場所に移動します。管理ユーザーインターフェイスが表示されます。**[C]** ノードはクライアントサービス、**[F]** ノードはフロントエンドサービス、**[B]** ノードはバックエンドサービスを表します。各ノードには、太字の色付きの行で示されるように、他のすべてのノードへの完全な通信アクセスが含まれます。  
![\[オープンネットワークポリシー\]](http://docs.aws.amazon.com/ja_jp/eks/latest/userguide/images/stars-default.png)

1. 相互にサービスを分離するには、次のネットワークポリシーを `stars` および `client` の名前空間の両方に適用します。

   ```
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     name: default-deny
   spec:
     podSelector:
       matchLabels: {}
   ```

   次のコマンドを使用して、ポリシーを両方の名前空間に適用できます。

   ```
   kubectl apply -n stars -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/apply_network_policies.files/default-deny.yaml
   kubectl apply -n client -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/apply_network_policies.files/default-deny.yaml
   ```

1. ブラウザを更新します。管理ユーザーインターフェイスはノードに到達できなくなるため、ユーザーインターフェイスに表示されないことがわかります。

1. 管理ユーザーインターフェイスがサービスにアクセスできるように、次の別のネットワークポリシーを適用します。このポリシーを適用して UI を許可します。

   ```
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     namespace: stars
     name: allow-ui
   spec:
     podSelector:
       matchLabels: {}
     ingress:
       - from:
           - namespaceSelector:
               matchLabels:
                 role: management-ui
   ```

   このポリシーを適用してクライアントを許可します。

   ```
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     namespace: client
     name: allow-ui
   spec:
     podSelector:
       matchLabels: {}
     ingress:
       - from:
           - namespaceSelector:
               matchLabels:
                 role: management-ui
   ```

   次のコマンドを使用して両方のポリシーを適用できます。

   ```
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/apply_network_policies.files/allow-ui.yaml
   kubectl apply -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/apply_network_policies.files/allow-ui-client.yaml
   ```

1. ブラウザを更新します。管理ユーザーインターフェイスは再びノードにアクセスできますが、ノードは相互に通信できないことがわかります。  
![\[UI アクセスネットワークポリシー\]](http://docs.aws.amazon.com/ja_jp/eks/latest/userguide/images/stars-no-traffic.png)

1. フロントエンドサービスからバックエンドサービスへのトラフィックを許可するには、次のネットワークポリシーを適用します。

   ```
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     namespace: stars
     name: backend-policy
   spec:
     podSelector:
       matchLabels:
         role: backend
     ingress:
       - from:
           - podSelector:
               matchLabels:
                 role: frontend
         ports:
           - protocol: TCP
             port: 6379
   ```

1. ブラウザを更新します。フロントエンドがバックエンドと通信できることがわかります。  
![\[フロントエンドからバックエンドまでのポリシー\]](http://docs.aws.amazon.com/ja_jp/eks/latest/userguide/images/stars-front-end-back-end.png)

1. クライアントからフロントエンドサービスへのトラフィックを許可するには、次のネットワークポリシーを適用します。

   ```
   kind: NetworkPolicy
   apiVersion: networking.k8s.io/v1
   metadata:
     namespace: stars
     name: frontend-policy
   spec:
     podSelector:
       matchLabels:
         role: frontend
     ingress:
       - from:
           - namespaceSelector:
               matchLabels:
                 role: client
         ports:
           - protocol: TCP
             port: 80
   ```

1. ブラウザを更新します。クライアントがフロントエンドサービスと通信できることがわかります。フロントエンドサービスは、バックエンドサービスと引き続き通信できます。  
![\[最終ネットワークポリシー\]](http://docs.aws.amazon.com/ja_jp/eks/latest/userguide/images/stars-final.png)

1. (オプション) デモが完了したら、そのリソースを削除することができます。

   ```
   kubectl delete -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/client.yaml
   kubectl delete -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/frontend.yaml
   kubectl delete -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/backend.yaml
   kubectl delete -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/management-ui.yaml
   kubectl delete -f https://raw.githubusercontent.com/aws-samples/eks-workshop/2f9d29ed3f82ed6b083649e975a0e574fb8a4058/content/beginner/120_network-policies/calico/stars_policy_demo/create_resources.files/namespace.yaml
   ```

   リソースを削除した後でも、ノード上にネットワークポリシーエンドポイントが残っている場合があり、それがクラスター内のネットワークを予期しない方法で妨げることがあります。これらのルールを削除する唯一の確実な方法は、ノードを再起動するか、すべてのノードを終了して、リサイクルすることです。すべてのノードを終了するには、Auto Scaling グループの必要数を 0 に設定してから目的数にバックアップするか、単にノードを終了します。

# カスタムネットワーキングを使用して代替サブネットに Pod をデプロイする
<a name="cni-custom-network"></a>

 **適用対象**: Linux `IPv4` Fargate ノード、Amazon EC2 インスタンスを持つ Linux ノード

![\[ネットワークインターフェイスが複数あるノードの図\]](http://docs.aws.amazon.com/ja_jp/eks/latest/userguide/images/cn-image.png)


Amazon VPC CNI plugin for Kubernetes が、Amazon EC2 ノード用にセカンダリ [Elastic Network Interface](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) (ネットワークインターフェイス) を作成する際には、デフォルトで、ノードのプライマリネットワークインターフェイスと同じサブネットがその格納先になります。また、プライマリネットワークインターフェイスに関連付けられているものと同じセキュリティグループが、セカンダリネットワークインターフェイスにも関連付けられます。以下の 1 つ以上の理由により、プラグインを使用して異なるサブネットにセカンダリネットワークインターフェイスを作成させたり、セカンダリネットワークインターフェイスに異なるセキュリティグループを関連付けたり、また、その両方を行ったりする必要性が生じることがあります。
+ プライマリネットワークインターフェイスが存在するサブネットで使用可能な `IPv4` アドレスには、数の上で制限があります。これにより、サブネット内に作成できる Pod の数に制限が生じる可能性があります。セカンダリネットワークインターフェイス用に別のサブネットを指定すると、Pod のために使用可能な `IPv4` アドレスの数を増やすことができます。
+ セキュリティ上の理由からも、ノードのプライマリネットワークインターフェイスで使用するものとは異なるセキュリティグループまたはサブネットが、Pod に必要となる場合があります。
+ ノードをパブリックサブネット内に構成した場合、Pod はプライベートサブネット内に配置します。パブリックサブネットに関連付けられているルートテーブルには、インターネットゲートウェイへのルートが含まれています。プライベートサブネットに関連付けられているルートテーブルには、インターネットゲートウェイへのルートは含まれません。

**ヒント**  
また、カスタムネットワーキングを使用することなく Amazon EKS クラスターに直接新規または既存のサブネットを追加することもできます。詳細については、「[管理コンソールから既存の VPC サブネットを Amazon EKS クラスターに追加する](eks-networking.md#add-existing-subnet)」を参照してください。

## 考慮事項
<a name="cni-custom-network-considerations"></a>

この機能を使用する際の考慮事項を次に示します。
+ カスタムネットワーキングを有効にすると、プライマリネットワークインターフェイスに割り当てられた IP アドレスが、Pod に割り当てられることはなくなります。Pod には、セカンダリネットワークインターフェイスからの IP アドレスのみが割り当てられます。
+ クラスターで `IPv6` ファミリーを使用している場合は、カスタムネットワーキングを使用することはできません。
+ `IPv4` アドレスの枯渇を軽減するために、カスタムネットワーキングを使用する予定の場合は、`IPv6` ファミリーを使用してクラスターを作成することもできます。詳細については、「[クラスター、Pod、サービスに対する IPv6 アドレスの説明](cni-ipv6.md)」を参照してください。
+ サブネットにデプロイされたセカンダリネットワークインターフェイス用の Pod が、ノードのプライマリネットワークインターフェイスとは異なるサブネットおよびセキュリティグループを使用できるように設定されていても、そのサブネットとセキュリティグループは、ノードと同じ VPC 内に配置される必要があります。
+ Fargate の場合、サブネットは Fargate プロファイルを介して制御されます。詳細については、「[起動時にどの Pod が AWS Fargate を使用するのかを定義する](fargate-profile.md)」を参照してください。

# Amazon EKS ノードのセカンダリネットワークインターフェイスをカスタマイズする
<a name="cni-custom-network-tutorial"></a>

このチュートリアルを開始する前に以下を完了してください：
+ 考慮事項を確認する
+ Amazon VPC CNI plugin for Kubernetes によるセカンダリネットワークインターフェイスの作成と、Pod への IP アドレス割り当て方法に関する知識。詳細については、GitHub の「[ENI Allocation](https://github.com/aws/amazon-vpc-cni-k8s#eni-allocation)」(ENI 割り当て) を参照してください。
+ ご使用のデバイスまたは AWS クラウドシェル で、バージョン `2.12.3` 以降、または AWS コマンドラインインターフェイス (AWS CLI のバージョン `1.27.160` 以降がインストールおよび設定されていること。現在のバージョンを確認するには「`aws --version | cut -d / -f2 | cut -d ' ' -f1`」を参照してください。`yum`、`apt-get`、macOS 用の Homebrew などのパッケージマネージャーは、多くの場合 AWS CLI の最新バージョンより数バージョン古くなっています。最新バージョンをインストールするには「*AWS コマンドラインインターフェイスユーザーガイド*」の「[インストール](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)」および「[aws configure を使用したクイック設定](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)」を参照してください。AWS クラウドシェル にインストールされている AWS CLI バージョンも最新バージョンより数バージョン遅れることがあります。更新するには、「*AWS CloudShell ユーザーガイド*」の「[ホームディレクトリへの AWS CLI のインストール](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software)」を参照してください。
+ デバイスまたは AWS クラウドシェル に、`kubectl` コマンドラインツールがインストールされていること。`kubectl` をインストールまたはアップグレードする方法については「[`kubectl` および `eksctl` のセットアップ](install-kubectl.md)」を参照してください。
+ このトピック内のステップはBash シェル内で実行することが推奨されます。Bash シェルを使用していない場合、行継続文字や、変数の設定と使用に関する方法など、一部のスクリプトコマンドのためにシェルの調整が必要となります。さらに、シェルの引用規則とエスケープ規則は異なる場合があります。詳細については「AWS コマンドラインインターフェイスのユーザーガイド」の「[AWS CLI での文字列への引用符の使用](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-quoting-strings.html)」を参照してください。

このチュートリアルでは置き換えが必要だと明記されている場合を除き、サンプル値をそのまま使用することをお勧めします。本番向けクラスター向けにステップを完了する際には例値 を任意の値に置き換えることができます。すべてのステップは同一のターミナルで実行することをお勧めします。設定された変数はステップ全体で使用され、また、これらは異なるターミナルには存在しないためです。

このトピックのコマンドは「[AWS CLI 使用例を使用する](https://docs.aws.amazon.com/cli/latest/userguide/welcome-examples.html)」に記載されている規則に従ってフォーマットされています。使用している AWS CLI [プロファイル](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-profiles)で定義されているデフォルトの AWS リージョンとは異なる AWS リージョンにあるリソースに対してコマンドラインからコマンドを実行する場合はコマンドに `--region us-west-2` を追加する必要があります。`us-west-2` は自分の AWS リージョンに置き換えます。

カスタムネットワーキングを本番用クラスターにデプロイする場合は、[ステップ 2: VPC を設定する](#custom-networking-configure-vpc) にスキップします。

## ステップ 1: テスト VPC およびクラスターを作成する
<a name="custom-networking-create-cluster"></a>

次の手順により、テスト VPC とクラスターを作成し、そのたクラスターのためにカスタムネットワークを構成できます。本番向けのクラスターで必要になるいくつかの機能で、このトピックに関連のないものについては説明していません。そのため、本番ワークロード向けに、このテストクラスターを使用することはお勧めしません。詳細については、「[Amazon EKS クラスターを作成します。](create-cluster.md)」を参照してください。

1. 以下のコマンドを実行して、`account_id` 変数を定義します。

   ```
   account_id=$(aws sts get-caller-identity --query Account --output text)
   ```

1. VPC を作成します。

   1. テストシステムにデプロイする場合は Amazon EKS AWS クラウドフォーメーション テンプレートを使用して VPC を作成します。

      ```
      aws cloudformation create-stack --stack-name my-eks-custom-networking-vpc \
        --template-url https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-vpc-private-subnets.yaml \
        --parameters ParameterKey=VpcBlock,ParameterValue=192.168.0.0/24 \
        ParameterKey=PrivateSubnet01Block,ParameterValue=192.168.0.64/27 \
        ParameterKey=PrivateSubnet02Block,ParameterValue=192.168.0.96/27 \
        ParameterKey=PublicSubnet01Block,ParameterValue=192.168.0.0/27 \
        ParameterKey=PublicSubnet02Block,ParameterValue=192.168.0.32/27
      ```

   1. AWS クラウドFormation スタックが作成されるまで数分かかります。次のコマンドを実行して、スタックのデプロイステータスを確認します。

      ```
      aws cloudformation describe-stacks --stack-name my-eks-custom-networking-vpc --query Stacks\[\].StackStatus  --output text
      ```

      コマンドの出力が「`CREATE_COMPLETE`」になるまで、次のステップに進まないでください。

   1. テンプレートによって作成された、プライベートサブネット ID の値により変数を定義します。

      ```
      subnet_id_1=$(aws cloudformation describe-stack-resources --stack-name my-eks-custom-networking-vpc \
          --query "StackResources[?LogicalResourceId=='PrivateSubnet01'].PhysicalResourceId" --output text)
      subnet_id_2=$(aws cloudformation describe-stack-resources --stack-name my-eks-custom-networking-vpc \
          --query "StackResources[?LogicalResourceId=='PrivateSubnet02'].PhysicalResourceId" --output text)
      ```

   1. 前のステップで取得した、サブネットのアベイラビリティーゾーンを使用して変数を定義します。

      ```
      az_1=$(aws ec2 describe-subnets --subnet-ids $subnet_id_1 --query 'Subnets[*].AvailabilityZone' --output text)
      az_2=$(aws ec2 describe-subnets --subnet-ids $subnet_id_2 --query 'Subnets[*].AvailabilityZone' --output text)
      ```

1. クラスターの IAM ロールを作成します。

   1. IAM 信頼ポリシー用の JSON ファイルを作成するには次のコマンドを実行してください。

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Service": "eks.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
          }
        ]
      }
      ```

   1. Amazon EKS クラスター の IAM ロールを作成します。必要に応じて、`eks-cluster-role-trust-policy.json` の前に、ステップでファイルの書き込み先となったコンピュータ上のパスを追加します。このコマンドは前のステップで作成した信頼ポリシーをロールに関連付けます。IAM ロールを作成するにはロールを作成する [IAM プリンシパル](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#iam-term-principal)に `iam:CreateRole` アクション (許可) を割り当てる必要があります。

      ```
      aws iam create-role --role-name myCustomNetworkingAmazonEKSClusterRole --assume-role-policy-document file://"eks-cluster-role-trust-policy.json"
      ```

   1. [AmazonEKSClusterPolicy](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEKSClusterPolicy.html#AmazonEKSClusterPolicy-json) という名前の Amazon EKS マネージド型ポリシーをロールにアタッチします。IAM ポリシーを [IAM プリンシパル](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#iam-term-principal)にアタッチするにはポリシーのアタッチを行っているプリンシパルに、次のいずれかの IAM アクション (許可) を割り当てる必要があります: `iam:AttachUserPolicy` または `iam:AttachRolePolicy`

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy --role-name myCustomNetworkingAmazonEKSClusterRole
      ```

1. Amazon EKS クラスターを作成し、このクラスターとデバイスの間の通信を設定します。

   1. クラスターを作成する。

      ```
      aws eks create-cluster --name my-custom-networking-cluster \
         --role-arn arn:aws:iam::$account_id:role/myCustomNetworkingAmazonEKSClusterRole \
         --resources-vpc-config subnetIds="$subnet_id_1","$subnet_id_2"
      ```
**注記**  
リクエストで指定したアベイラビリティーゾーンのいずれかに、Amazon EKS クラスターの作成に十分な容量がない場合にはエラーが表示されることがあります。このエラー出力には新しいクラスターをサポートできるアベイラビリティーゾーンが表示されます。アカウント向けにサポートされているアベイラビリティーゾーンにある 2 つ以上のサブネットを使用して、クラスターを作成します。詳細については「[容量不足](troubleshooting.md#ice)」を参照してください。

   1. クラスターが作成されるまでに数分かかります。次のコマンドを実行して、クラスターのデプロイステータスを確認します。

      ```
      aws eks describe-cluster --name my-custom-networking-cluster --query cluster.status
      ```

      コマンドの出力が「`"ACTIVE"`」になるまで、次のステップに進まないでください。

   1. クラスターと通信するために `kubectl` を設定します。

      ```
      aws eks update-kubeconfig --name my-custom-networking-cluster
      ```

## ステップ 2: VPC を設定する
<a name="custom-networking-configure-vpc"></a>

このチュートリアルでは、[ステップ 1: テスト VPC およびクラスターを作成する](#custom-networking-create-cluster) で作成した VPC が必要です。本番向けクラスターの場合は、example values をすべて実際の値に置き換えて、VPC に合うように各ステップを調整します。

1. 現在インストールされている Amazon VPC CNI plugin for Kubernetes が最新バージョンであることを確認します。Amazon EKS アドオンタイプの最新バージョンを確認し、そのバージョンに更新するには「[Amazon EKS アドオンを更新する](updating-an-add-on.md)」を参照してください。セルフマネージドアドオンタイプの最新バージョンを確認し、そのバージョンに更新するには「[Amazon VPC CNI を使用して Pod に IP を割り当てる](managing-vpc-cni.md)」を参照してください。

1. クラスター VPC の ID を取得し、後のステップで使用するために変数に格納します。

   ```
   vpc_id=$(aws eks describe-cluster --name my-custom-networking-cluster --query "cluster.resourcesVpcConfig.vpcId" --output text)
   ```

1. 追加の Classless Inter-Domain Routing (CIDR ブロックを、クラスターの VPC に関連付けます。CIDR ブロックは既存の関連付けられた CIDR ブロックと重複することはできません。

   1. 現在 VPC に関連付けられている CIDR ブロックを表示します。

      ```
      aws ec2 describe-vpcs --vpc-ids $vpc_id \
          --query 'Vpcs[*].CidrBlockAssociationSet[*].{CIDRBlock: CidrBlock, State: CidrBlockState.State}' --out table
      ```

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

      ```
      ----------------------------------
      |          DescribeVpcs          |
      +-----------------+--------------+
      |    CIDRBlock    |    State     |
      +-----------------+--------------+
      |  192.168.0.0/24 |  associated  |
      +-----------------+--------------+
      ```

   1. 追加の CIDR ブロックを VPC に関連付けます。次のコマンドで CIDR ブロック値を置き換えます。詳細については「Amazon VPC ユーザーガイド」の「[追加の IPv4 CIDR ブロックと VPC の関連付け](https://docs.aws.amazon.com/vpc/latest/userguide/modify-vpcs.html#add-ipv4-cidr)」を参照してください。

      ```
      aws ec2 associate-vpc-cidr-block --vpc-id $vpc_id --cidr-block 192.168.1.0/24
      ```

   1. 新しいブロックが関連付けられていることを確認します。

      ```
      aws ec2 describe-vpcs --vpc-ids $vpc_id --query 'Vpcs[*].CidrBlockAssociationSet[*].{CIDRBlock: CidrBlock, State: CidrBlockState.State}' --out table
      ```

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

      ```
      ----------------------------------
      |          DescribeVpcs          |
      +-----------------+--------------+
      |    CIDRBlock    |    State     |
      +-----------------+--------------+
      |  192.168.0.0/24 |  associated  |
      |  192.168.1.0/24 |  associated  |
      +-----------------+--------------+
      ```

   新しい CIDR ブロックの `State` が `associated` に遷移するまで、次のステップには進まないでください。

1. 既存のサブネットが存在する各アベイラビリティーゾーン内で、使用するサブネットを必要な数だけ作成します。前のステップで VPC に関連付けた、CIDR ブロック内にある CIDR ブロックを指定します。

   1. 新しいサブネットを作成します。次のコマンドで CIDR ブロック値を置き換えます。サブネットは既存のサブネットが置かれているものとは異なる VPC CIDR ブロックの中に作成する必要があり、作成するアベイラビリティーゾーンは既存のサブネットと同じにする必要があります。この例では現在のプライベートサブネットが存在する各アベイラビリティーゾーンにある新しい CIDR ブロックの中に、1 つのサブネットが作成されます。作成されたサブネットの ID は後のステップで使用するために変数に格納されます。`Name` の値は前のステップで Amazon EKS VPC テンプレートを使用して作成されたサブネットに、割り当てられている値と一致します。名前は必須ではありません。名前には異なる値を使用できます。

      ```
      new_subnet_id_1=$(aws ec2 create-subnet --vpc-id $vpc_id --availability-zone $az_1 --cidr-block 192.168.1.0/27 \
          --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=my-eks-custom-networking-vpc-PrivateSubnet01},{Key=kubernetes.io/role/internal-elb,Value=1}]' \
          --query Subnet.SubnetId --output text)
      new_subnet_id_2=$(aws ec2 create-subnet --vpc-id $vpc_id --availability-zone $az_2 --cidr-block 192.168.1.32/27 \
          --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=my-eks-custom-networking-vpc-PrivateSubnet02},{Key=kubernetes.io/role/internal-elb,Value=1}]' \
          --query Subnet.SubnetId --output text)
      ```
**重要**  
デフォルトで新しいサブネットはVPC の[メインルートテーブル](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html#RouteTables)に暗黙的に関連付けられます。このルートテーブルにより、その VPC にデプロイされているすべてのリソース間の通信が可能になります。ただし、VPC に関連付けられた CIDR ブロックの外部にある IP アドレスが割り当てられたリソースとの通信は許可されません。この動作を変更するには独自のルートテーブルをサブネットに関連付けます。詳細については「Amazon VPC ユーザーガイド」の「[サブネットルートテーブル](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html#subnet-route-tables)」を参照してください。

   1. 使用している VPC の現在のサブネットを表示します。

      ```
      aws ec2 describe-subnets --filters "Name=vpc-id,Values=$vpc_id" \
          --query 'Subnets[*].{SubnetId: SubnetId,AvailabilityZone: AvailabilityZone,CidrBlock: CidrBlock}' \
          --output table
      ```

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

      ```
      ----------------------------------------------------------------------
      |                           DescribeSubnets                          |
      +------------------+--------------------+----------------------------+
      | AvailabilityZone |     CidrBlock      |         SubnetId           |
      +------------------+--------------------+----------------------------+
      |  us-west-2d      |  192.168.0.0/27    |     subnet-example1        |
      |  us-west-2a      |  192.168.0.32/27   |     subnet-example2        |
      |  us-west-2a      |  192.168.0.64/27   |     subnet-example3        |
      |  us-west-2d      |  192.168.0.96/27   |     subnet-example4        |
      |  us-west-2a      |  192.168.1.0/27    |     subnet-example5        |
      |  us-west-2d      |  192.168.1.32/27   |     subnet-example6        |
      +------------------+--------------------+----------------------------+
      ```

      作成した `192.168.1.0` CIDR ブロック内のサブネットが、`192.168.0.0` CIDR ブロック内のサブネットと同じアベイラビリティーゾーンに置かれていることが確認できます。

## ステップ 3: Kubernetes リソースを設定する
<a name="custom-networking-configure-kubernetes"></a>

1. `aws-node` DaemonSet で `AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG` 環境変数を `true` に設定します。

   ```
   kubectl set env daemonset aws-node -n kube-system AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true
   ```

1. [クラスターのセキュリティグループ](sec-group-reqs.md)の ID を取得し、次のステップで使用するために変数に格納します。このセキュリティグループはクラスターの作成時に Amazon EKS により自動的に作成されます。

   ```
   cluster_security_group_id=$(aws eks describe-cluster --name my-custom-networking-cluster --query cluster.resourcesVpcConfig.clusterSecurityGroupId --output text)
   ```

1.   Pod をデプロイするサブネットごとに `ENIConfig` カスタムリソースを作成します。

   1. 各ネットワークインターフェイス設定に固有のファイルを作成します。

      次のコマンドでは、前のステップで作成した 2 つのサブネットのそれぞれに、個別の `ENIConfig` ファイルが作成されます。`name` の値は一意である必要があります。これらの名前はサブネットが存在するアベイラビリティーゾーンと同じものが付けられます。クラスターセキュリティグループは、`ENIConfig` に割り当てられます。

      ```
      cat >$az_1.yaml <<EOF
      apiVersion: crd.k8s.amazonaws.com/v1alpha1
      kind: ENIConfig
      metadata:
        name: $az_1
      spec:
        securityGroups:
          - $cluster_security_group_id
        subnet: $new_subnet_id_1
      EOF
      ```

      ```
      cat >$az_2.yaml <<EOF
      apiVersion: crd.k8s.amazonaws.com/v1alpha1
      kind: ENIConfig
      metadata:
        name: $az_2
      spec:
        securityGroups:
          - $cluster_security_group_id
        subnet: $new_subnet_id_2
      EOF
      ```

      本番向けのクラスターでは、前のコマンドに次の変更を行います。
      + \$1cluster\$1security\$1group\$1id は各 `ENIConfig` で使用する既存の[セキュリティグループ](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)の ID に置き換えます。
      + 可能な限り、`ENIConfig` が使用されるアベイラビリティーゾーンと同じ名前を、`ENIConfigs` に付けることをお勧めします。いくつかの理由から、`ENIConfigs` に対して、アベイラビリティーゾーンとは異なる名前を使用する必要が生じることがあります。例えば、同じアベイラビリティーゾーンに 3 つ以上のサブネットがあり、そのすべてでカスタムネットワーキングを使用したい場合は同一のアベイラビリティーゾーンに複数の `ENIConfigs` が必要になります。各 `ENIConfig` には一意の名前が必要であるため、複数の `ENIConfigs` に対しアベイラビリティーゾーンの名前を使用することはできません。

        `ENIConfig` の中で、アベイラビリティーゾーンと異なる名前を持つものについては前のコマンドで \$1az\$11 と \$1az\$12 を独自の名前に置き換えます。さらに、この後のチュートリアルで [ENIConfig でノードをアノテーション](#custom-networking-annotate-eniconfig)します。
**注記**  
本番向けクラスターで使用するために有効なセキュリティグループを指定しておらず、かつ:
      + Amazon VPC CNI plugin for Kubernetes のバージョン `1.8.0` 以降を使用する場合は、ノードのプライマリ Elastic Network Interface に関連付けられたセキュリティグループが使用されます。
      + `1.8.0` より前のバージョンの Amazon VPC CNI plugin for Kubernetes を使用している場合は、VPC のデフォルトのセキュリティグループが、セカンダリネットワークインターフェイスに割り当てられます。
**重要**  
 `AWS_VPC_K8S_CNI_EXTERNALSNAT=false` は、Kubernetes 用 Amazon VPC CNI プラグインのデフォルトの設定です。デフォルト設定を使用している場合、VPC に関連付けられた CIDR ブロックのいずれにもない IP アドレスに向けて送信されたトラフィックにはノードのプライマリネットワークインターフェイスでの、セキュリティグループとサブネットが使用されます。セカンダリネットワークインターフェイスを作成するために使用された、`ENIConfigs` で定義されているサブネットとセキュリティグループはこのトラフィックでは使用されません。この設定の詳細については「[Pod のアウトバウンドインターネットアクセスを有効にする](external-snat.md)」を参照してください。
また、Pod でもセキュリティグループを使用する場合、そのセキュリティグループは `SecurityGroupPolicy` で指定されたものとなり、`ENIConfigs` で指定されたものは使用されません。詳細については、「[セキュリティグループを個別の Pod に割り当てる](security-groups-for-pods.md)」を参照してください。

   1. 以下のコマンドを使用して、作成したカスタムリソースファイルをそれぞれクラスターに適用します。

      ```
      kubectl apply -f $az_1.yaml
      kubectl apply -f $az_2.yaml
      ```

1. `ENIConfigs` が作成されたことを確認します。

   ```
   kubectl get ENIConfigs
   ```

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

   ```
   NAME         AGE
   us-west-2a   117s
   us-west-2d   105s
   ```

1. 本番向けのクラスターで、カスタムネットワーキングを有効にしており、`ENIConfigs` の名前を使用されているアベイラビリティーゾーンとは異なるものにした場合は[次のステップ](#custom-networking-deploy-nodes)に移り、Amazon EC2 ノードをデプロイします。

   クラスターで作成された任意の新しい Amazon EC2 ノードに対し、Kubernetes がアベイラビリティーゾーン用の `ENIConfig` を自動的に適用することを許可します。

   1. このチュートリアルでのテスト用クラスターの場合は、このまま[次のステップ](#custom-networking-automatically-apply-eniconfig)に移動します。

      実稼働クラスターの場合は、` [ENI\$1CONFIG\$1ANNOTATION\$1DEF](https://github.com/aws/amazon-vpc-cni-k8s#eni_config_annotation_def) ` 環境変数用のキー `aws-node` を使用するアノテーションが、`k8s.amazonaws.com/eniConfig` DaemonSet のためのコンテナ仕様内に存在することを確認します。

      ```
      kubectl describe daemonset aws-node -n kube-system | grep ENI_CONFIG_ANNOTATION_DEF
      ```

      出力が返される場合はアノテーションが存在します。出力が返されない場合、その変数は設定されていません。本番向けクラスターの場合にはここでの設定と、以降のステップで示す設定のどちらも使用可能です。ここでの設定を使用すると、以降のステップの設定は上書きされます。このチュートリアルではこの後のステップでの設定を使用します。

   1.  クラスター内に作成された任意の新しい Amazon EC2 ノードに対し、自動的にアベイラビリティーゾーンの `ENIConfig` を適用するように、`aws-node` DaemonSet を更新します。

      ```
      kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=topology.kubernetes.io/zone
      ```

## ステップ 4: Amazon EC2 ノードをデプロイする
<a name="custom-networking-deploy-nodes"></a>

1. ノードの IAM ロールを作成します。

   1. IAM 信頼ポリシー用の JSON ファイルを作成するには次のコマンドを実行してください。

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
          }
        ]
      }
      ```

   1. IAM ロールを作成し、返された Amazon リソースネーム (ARN) を、後のステップで使用するために変数に格納します。

      ```
      node_role_arn=$(aws iam create-role --role-name myCustomNetworkingNodeRole --assume-role-policy-document file://"node-role-trust-relationship.json" \
          --query Role.Arn --output text)
      ```

   1. IAM ロールに、3 つの必須な IAM マネージドポリシーをアタッチします。

      ```
      aws iam attach-role-policy \
        --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \
        --role-name myCustomNetworkingNodeRole
      aws iam attach-role-policy \
        --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \
        --role-name myCustomNetworkingNodeRole
      aws iam attach-role-policy \
          --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \
          --role-name myCustomNetworkingNodeRole
      ```
**重要**  
分かりやすくするため、このチュートリアルでは[AmazonEKS\$1CNI\$1Policy](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEKS_CNI_Policy.html) ポリシーはノードの IAM ロールにアタッチされています。ただし、本番向けクラスターの場合は、Amazon VPC CNI plugin for Kubernetes のみで使用される IAM ロールに、個別にポリシーをアタッチすることをお勧めします。詳細については、「[IRSA を使用するように Amazon VPC CNI プラグインを設定する](cni-iam-role.md)」を参照してください。

1. 次のいずれかのタイプのノードグループを作成します。デプロイするインスタンスタイプを確認するには「[最適な Amazon EC2 ノードインスタンスタイプを選択する](choosing-instance-type.md)」を参照してください。このチュートリアルのために、**マネージド型**、および**起動テンプレートを使用しない、または AMI ID が指定されていない起動テンプレートを使用する**オプションを完了します。本番ワークロードでノードグループを使用する場合はそのグループをデプロイする前に、[マネージドノードグループ](create-managed-node-group.md)および[セルフマネージドノードグループ](worker.md)のすべてのオプションについて理解しておくことをお勧めします。
   +  **マネージド型** — 次のいずれかのオプションを使用して、ノードグループをデプロイします：
     +  **起動テンプレートを使用しない、または AMI ID が指定されていない起動テンプレートを使用する** — 次のコマンドを実行してください。このチュートリアルではサンプルの値を使用します。本番向けのノードグループの場合はすべてのサンプルの値を、実際の値に置き換えてください。ノードグループ名は 63 文字以下である必要があります。先頭は文字または数字でなければなりませんが、残りの文字にはハイフンおよびアンダースコアを含めることもできます。

       ```
       aws eks create-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup \
           --subnets $subnet_id_1 $subnet_id_2 --instance-types t3.medium --node-role $node_role_arn
       ```
     +  **指定された AMI ID を持つ起動テンプレートを使用** 

       1. ノードでの Pod について、Amazon EKS で推奨される最大数を決定します。「」の指示に従い、そのトピックのステップ 3 で `--cni-custom-networking-enabled` を追加します。後のステップで使用するために、この出力を書き留めます。

       1. 起動テンプレートで、Amazon EKS 最適化 AMI ID を指定するか、Amazon EKS 最適化 AMI から構築されたカスタム AMI を指定します。その後、[起動テンプレートを使用してノードグループをデプロイ](launch-templates.md)し、さらに、起動テンプレートにある次のユーザーデータを指定します。このユーザーデータは、引数を `NodeConfig` 仕様に渡します。NodeConfig の詳細については、「[NodeConfig API リファレンス](https://awslabs.github.io/amazon-eks-ami/nodeadm/doc/api/#nodeconfig)」を参照してください。`20` は、前のステップで使用した値 (推奨) か、または独自の値に置き換えることができます。

          ```
          ---
          MIME-Version: 1.0
          Content-Type: multipart/mixed; boundary="BOUNDARY"
          --BOUNDARY
          Content-Type: application/node.eks.aws
          
          ---
          apiVersion: node.eks.aws/v1alpha1
          kind: NodeConfig
          spec:
            cluster:
              name: my-cluster
              ...
              kubelet:
                config:
                  maxPods: 20
          ```

          Amazon EKS 最適化 AMI から構築されていないカスタム AMI を作成した場合は自分で設定をカスタム作成する必要があります。
   +  **セルフマネージド型** 

     1. ノードでの Pod について、Amazon EKS で推奨される最大数を決定します。 の手順に従います (`--cni-custom-networking-enabled` をステップ 3 に追加してください)。後のステップで使用するために、この出力を書き留めます。

     1. [セルフマネージド Amazon Linux ノードを作成する](launch-workers.md) の手順に従ってノードグループをデプロイします。
**注記**  
本番クラスター内のノードで、非常に大量の Pod をサポートさせる場合には、「」のスクリプトを再度実行します。また、このコマンドには `--cni-prefix-delegation-enabled` オプションを追加します。例えば、`m5.large` インスタンスタイプの場合は `110` が返されます。この機能を有効化する方法については「[プレフィックスを使用して Amazon EKS ノードに割り当てる IP アドレスを増やす](cni-increase-ip-addresses.md)」を参照してください。この機能はカスタムネットワーキングで使用できます。

1. ノードグループの作成には数分かかります。次のコマンドを使用すると、マネージド型のノードグループ作成のステータスを確認できます。

   ```
   aws eks describe-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup --query nodegroup.status --output text
   ```

   出力が「`ACTIVE`」を返すまで、次のステップに進まないでください。

1.  このチュートリアルではこのステップをスキップできます。

   本番向けのクラスターにおいて、`ENIConfigs` の名前を、それが使用されているアベイラビリティーゾーンと同じにしなかった場合にはノードに対し、そのノードで使用すべき `ENIConfig` の名前をアノテーションします。各アベイラビリティーゾーンにサブネットが 1 つしかなく、`ENIConfigs` にアベイラビリティーゾーンと同じ名前を付けている場合にはこのステップは必要ありません。[前のステップ](#custom-networking-automatically-apply-eniconfig)でその設定を有効にしている場合、Amazon VPC CNI plugin for Kubernetes が適切な `ENIConfig` をノードに対し自動的に関連付けるためです。

   1. クラスター内のノードのリストを取得します。

      ```
      kubectl get nodes
      ```

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

      ```
      NAME                                          STATUS   ROLES    AGE     VERSION
      ip-192-168-0-126.us-west-2.compute.internal   Ready    <none>   8m49s   v1.22.9-eks-810597c
      ip-192-168-0-92.us-west-2.compute.internal    Ready    <none>   8m34s   v1.22.9-eks-810597c
      ```

   1. 各ノードが属するアベイラビリティーゾーンを決定します。前の出力に基づいて IP アドレスを置き換えて、前のステップで返されたノードごとに次のコマンドを実行します。

      ```
      aws ec2 describe-instances --filters Name=network-interface.private-dns-name,Values=ip-192-168-0-126.us-west-2.compute.internal \
      --query 'Reservations[].Instances[].{AvailabilityZone: Placement.AvailabilityZone, SubnetId: SubnetId}'
      ```

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

      ```
      [
          {
              "AvailabilityZone": "us-west-2d",
              "SubnetId": "subnet-Example5"
          }
      ]
      ```

   1. 各ノードを、サブネット ID とアベイラビリティーゾーンのために作成した `ENIConfig` でアノテーションします。各ノードのアノテーションに使用できる `ENIConfig` は 1 つだけです。ただし、複数のノードに対し同じ `ENIConfig` でアノテーションすることは可能です。値の例 は実際に使用する値に置き換えます。

      ```
      kubectl annotate node ip-192-168-0-126.us-west-2.compute.internal k8s.amazonaws.com/eniConfig=EniConfigName1
      kubectl annotate node ip-192-168-0-92.us-west-2.compute.internal k8s.amazonaws.com/eniConfig=EniConfigName2
      ```

1.  カスタムネットワーキング機能の使用に切り替える前に、Pod を実行している本稼働クラスターにノードがあった場合は、以下のタスクを完了してください。

   1. カスタムネットワーク機能を使用しているノードが、使用可能であることを確認します。

   1. ノードを遮断およびドレインして、Pod をスムーズにシャットダウンします。詳細については、Kubernetes ドキュメントの「[Safely Drain a Node](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/)」(ノードを安全にドレインする) を参照してください。

   1. ノードを終了します。ノードが既存のマネージド型ノードグループ内にある場合はそのノードグループを削除できます。以下のコマンドを実行してください。

      ```
      aws eks delete-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup
      ```

   カスタムネットワーク機能は`k8s.amazonaws.com/eniConfig` ラベルで登録されている新しいノードでのみ使用されます。

1. Pod に、前の手順で作成したサブネットの 1 つに関連付けられた CIDR ブロックから、IP アドレスが割り当てられていることを確認します。

   ```
   kubectl get pods -A -o wide
   ```

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

   ```
   NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE     IP              NODE                                          NOMINATED NODE   READINESS GATES
   kube-system   aws-node-2rkn4             1/1     Running   0          7m19s   192.168.0.92    ip-192-168-0-92.us-west-2.compute.internal    <none>           <none>
   kube-system   aws-node-k96wp             1/1     Running   0          7m15s   192.168.0.126   ip-192-168-0-126.us-west-2.compute.internal   <none>           <none>
   kube-system   coredns-657694c6f4-smcgr   1/1     Running   0          56m     192.168.1.23    ip-192-168-0-92.us-west-2.compute.internal    <none>           <none>
   kube-system   coredns-657694c6f4-stwv9   1/1     Running   0          56m     192.168.1.28    ip-192-168-0-92.us-west-2.compute.internal    <none>           <none>
   kube-system   kube-proxy-jgshq           1/1     Running   0          7m19s   192.168.0.92    ip-192-168-0-92.us-west-2.compute.internal    <none>           <none>
   kube-system   kube-proxy-wx9vk           1/1     Running   0          7m15s   192.168.0.126   ip-192-168-0-126.us-west-2.compute.internal   <none>           <none>
   ```

   VPC に追加した `192.168.1.0` CIDR ブロックからの IP アドレスが、coredns Pod に割り当てられていることが確認できます。カスタムネットワーキングを使用していない場合はここに `192.168.0.0` CIDR ブロックからのアドレスが割り当てられています。この CIDR ブロックが、元々 VPC に関連付けられている唯一のブロックであるためです。

   Pod の `spec` が `hostNetwork=true` を含む場合には、ノードのプライマリ IP アドレスが割り当てられます。追加したサブネットのアドレスは割り当てられません。デフォルトではこの値は `false` に設定されます。クラスターで実行される `kube-proxy` および Amazon VPC CNI plugin for Kubernetes (`aws-node`) の Pod に対して、この値は `true` に設定されます。これが、`kube-proxy` とプラグインの `aws-node` の Pod に、前の出力にある 192.168.1.x アドレスが割り当てられない理由です。Pod の `hostNetwork` 設定の詳細については、Kubernetes API リファレンスの「[PodSpec v1 core](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#podspec-v1-core)」を参照してください。

## ステップ 5: チュートリアルでのリソースを削除する
<a name="custom-network-delete-resources"></a>

このチュートリアル完了後は作成したリソースを削除することをお勧めします。その後、ここでのステップを調整して、本番向けクラスターのカスタムネットワーキングを有効化することができます。

1. 作成したノードグループが完全にテスト向けである場合はそれを削除してください。

   ```
   aws eks delete-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup
   ```

1. AWS CLI から、クラスターが削除済みだと出力された場合でも、実際にはその削除プロセスが完了していない場合があります。削除のプロセスには数分かかります。次のコマンドを実行して、処理の完了を確認します。

   ```
   aws eks describe-nodegroup --cluster-name my-custom-networking-cluster --nodegroup-name my-nodegroup --query nodegroup.status --output text
   ```

   次のように出力されるまで、次に進まないでください。

   ```
   An error occurred (ResourceNotFoundException) when calling the DescribeNodegroup operation: No node group found for name: my-nodegroup.
   ```

1. 作成したノードグループが完全にテスト向けである場合はノードの IAM ロールを削除します。

   1. ロールからポリシーをデタッチします。

      ```
      aws iam detach-role-policy --role-name myCustomNetworkingNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
      aws iam detach-role-policy --role-name myCustomNetworkingNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
      aws iam detach-role-policy --role-name myCustomNetworkingNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
      ```

   1. ロールを削除します。

      ```
      aws iam delete-role --role-name myCustomNetworkingNodeRole
      ```

1. クラスターを削除します。

   ```
   aws eks delete-cluster --name my-custom-networking-cluster
   ```

   以下のコマンドを使用して、クラスターが削除されたことを確認します。

   ```
   aws eks describe-cluster --name my-custom-networking-cluster --query cluster.status --output text
   ```

   次のような出力が返された場合はクラスターが正常に削除されています。

   ```
   An error occurred (ResourceNotFoundException) when calling the DescribeCluster operation: No cluster found for name: my-custom-networking-cluster.
   ```

1. クラスターの IAM ロールを削除します。

   1. ロールからポリシーをデタッチします。

      ```
      aws iam detach-role-policy --role-name myCustomNetworkingAmazonEKSClusterRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
      ```

   1. ロールを削除します。

      ```
      aws iam delete-role --role-name myCustomNetworkingAmazonEKSClusterRole
      ```

1. 前のステップで作成したサブネットを削除します。

   ```
   aws ec2 delete-subnet --subnet-id $new_subnet_id_1
   aws ec2 delete-subnet --subnet-id $new_subnet_id_2
   ```

1. 作成した VPC を削除します。

   ```
   aws cloudformation delete-stack --stack-name my-eks-custom-networking-vpc
   ```

# プレフィックスを使用して Amazon EKS ノードに割り当てる IP アドレスを増やす
<a name="cni-increase-ip-addresses"></a>

 **適用対象**: Amazon EC2 インスタンスを持つ Linux および Windows ノード

 **適用対象**: パブリックサブネットおよびプライベートサブネット

各 Amazon EC2 インスタンスではエラスティックネットワークインターフェイス の最大数と、各ネットワークインターフェイスに割り当て可能な IP アドレスの最大数がサポートされています。各ノードにはネットワークインターフェースごとに 1 つの IP アドレスが必要です。その他の使用可能な IP アドレスはすべて `Pods` に割り当てることができます。`Pod` それぞれに固有の IP アドレスが必要です。その結果、使用可能なコンピューティングリソースとメモリリソースはあるが、`Pods` に割り当てる IP アドレスが不足しているために追加の `Pods` に対応できないノードが存在する可能性があります。

個別のセカンダリ IP アドレスではなく、IP プレフィックスをノードに割り当てて、ノードで`Pods`に割り当て可能な IP アドレスの数を増やす方法について説明します。各プレフィックスには複数の IP アドレスが含まれます。IP プレフィックスが割り当てられるようにクラスターを設定しない場合、クラスターは Pod 接続に必要なネットワークインターフェイスと IP アドレスを設定するために Amazon EC2 アプリケーションプログラミングインターフェイス (API) の呼び出しをさらに実行する必要があります。クラスターのサイズが大きくなるにつれて、これらの API コールの頻度が高くなるため、Pod とインスタンスの起動時間が長くなる場合があります。これにより、大規模でスパイク的なワークロードの需要を満たすためにスケーリングの遅延が発生します。また、スケーリング要件を満たすためには追加のクラスターと VPC をプロビジョニングする必要があるため、コストと管理オーバーヘッドも増加します。詳細については「GitHub」の「[Kubernetes スケーラビリティ閾値](https://github.com/kubernetes/community/blob/master/sig-scalability/configs-and-limits/thresholds.md)」を参照してください。

## Amazon VPC CNI plugin for Kubernetes 機能との互換性
<a name="cni-increase-ip-addresses-compatability"></a>

次の機能で IP プレフィックスを使用できます：
+ IPv4 ソースネットワークアドレス変換 - 詳細については「[Pod のアウトバウンドインターネットアクセスを有効にする](external-snat.md)」を参照してください。
+ クラスター、ポッド、サービスへの IPv6 アドレス - 詳細については「[クラスター、Pod、サービスに対する IPv6 アドレスの説明](cni-ipv6.md)」を参照してください。
+ Kubernetes ネットワークポリシーを使用したトラフィックの制限 - 詳細については、「[Kubernetes ネットワークポリシーにより Pod トラフィックを制限する](cni-network-policy.md)」を参照してください。

次のリストは適用される Amazon VPC CNI プラグイン設定に関する情報を示しています。各設定の詳細については、GitHub の「[amazon-vpc-cni-k8s](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/README.md)」を参照してください。
+  `WARM_IP_TARGET` 
+  `MINIMUM_IP_TARGET` 
+  `WARM_PREFIX_TARGET` 

## 考慮事項
<a name="cni-increase-ip-addresses-considerations"></a>

この機能を使用する場合は以下を考慮してください：
+ 各 Amazon EC2 インスタンスタイプでは、Pod の最大数がサポートされています。マネージドノードグループが複数のインスタンスタイプで構成されている場合、クラスターのインスタンスで指定する Pod の最大数の内、最小の値がクラスター内のすべてのノードに適用されます。
+ デフォルトでは1 つのノードで実行できる `Pods` の最大数は 110 ですが、この値は変更できます。数値を変更し、既存のマネージド型ノードグループがある場合、ノードグループの AMI または起動テンプレートを次に更新するときに、新しいノードで変更済みの値が適用されるようになります。
+ IP アドレスの割り当てから IP プレフィックスの割り当てに移行する場合は既存のノードにローリング置換を実行するのではなく、新しいノードグループを作成して使用可能な IP アドレスの数を増やすことをお勧めします。IP アドレスと IP プレフィックスの両方が割り当てられているノードで Pod を実行すると、アドバタイズされた IP アドレスの容量に不一致が生じ、ノード上の将来のワークロードに影響する可能性があります。推奨される移行方法については、「*Amazon EKS Best Practices Guide*」の「[Prefix Delegation mode for Linux](https://docs.aws.amazon.com/eks/latest/best-practices/prefix-mode-linux.html)」を参照してください。
+ セキュリティグループのスコープはノードレベル - 詳細については「[セキュリティグループ](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)」を参照してください。
+ ネットワークインターフェイスに割り当てられた IP プレフィックスはノードあたりの高い Pod 密度をサポートし、最適な起動時間になっています。
+ IP プレフィックスと IP アドレスは標準の Amazon EC2 Elastic ネットワークインターフェイスに関連付けられています。特定のセキュリティグループを必要とする Pod には、ブランチネットワークインターフェイスのプライマリ IP アドレスが割り当てられます。IP アドレスを取得するポッド、または IP プレフィックスからの IP アドレスを、同じノード上のブランチネットワークインターフェイスを取得する Pod と混在させることができます。
+ Linux ノードのみを含むクラスターの場合。
  + ネットワークインターフェイスにプレフィックスを割り当てるようにアドオンを設定すると、クラスター内のすべてのノードグループにあるすべてのノードを削除しない限り、Amazon VPC CNI plugin for Kubernetes アドオンを `1.9.0` (または `1.10.1`) より前のバージョンにダウングレードすることはできません。
  + Pod のセキュリティグループ (`POD_SECURITY_GROUP_ENFORCING_MODE`=`standard` および `AWS_VPC_K8S_CNI_EXTERNALSNAT`=`false` に設定) も使用している場合、Pod が VPC の外部のエンドポイントと通信するときに、Pod に割り当てた任意のセキュリティグループではなく、ノードのセキュリティグループが使用されます。

    [セキュリティグループ](security-groups-for-pods.md) (`POD_SECURITY_GROUP_ENFORCING_MODE`=`strict` に設定) も使用している場合、`Pods` が VPC の外部のエンドポイントと通信するときに、`Pod’s` セキュリティグループが使用されます。

# Amazon EKS ノードで使用可能な IP アドレスを増やす
<a name="cni-increase-ip-addresses-procedure"></a>

個別のセカンダリ IP アドレスではなく、IP プレフィックスをノードに割り当てて、ノードで Pod に割り当て可能な IP アドレスの数を増やす方法について説明します。

## 前提条件
<a name="_prerequisites"></a>
+ 既存のクラスターが必要です。デプロイするには「[Amazon EKS クラスターを作成します。](create-cluster.md)」を参照してください。
+ Amazon EKS ノードが配置されているサブネットでは、`/28` 個の連続ブロック (`IPv4` クラスターの場合)、または `/80` 個の Classless Inter-Domain Routing (CIDR) ブロック (`IPv6` クラスターの場合) が十分な数として必要になります。`IPv6` クラスターに含めることができるのは Linux ノードだけです。IP アドレスがサブネット CIDR 全体に分散している場合、IP プレフィックスを使用すると失敗する可能性があります。次の構成を推奨します。
  + サブネット CIDR 予約を使用すると、予約された範囲内の IP アドレスがまだ使用されている場合でも、解放時に IP アドレスが再割り当てされません。これにより、セグメンテーションなしでプレフィックスを割り当てることができます。
  + IP プレフィックスが割り当てられているワークロードの実行に特に使用される新しいサブネットを使用してください。IP プレフィックスを割り当てると、Windows と Linux 両方のワークロードを同じサブネットで実行できます。
+ ノードに IP プレフィックスを割り当てるには、ノードが AWS Nitro ベースである必要があります。Nitro ベースではないインスタンスでは、引き続き個別のセカンダリ IP アドレスが割り当てられますが、Pod に割り当てることのできる IP アドレスの数は Nitro ベースのインスタンスよりも大幅に少なくなります。
+  **Linux ノードのみのクラスターの場合** – クラスターが `IPv4` ファミリーで設定されている場合は、バージョン `1.9.0` 以降の Amazon VPC CNI plugin for Kubernetes アドオンがインストールされている必要があります。現在のバージョンは、次のコマンドで確認できます。

  ```
  kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
  ```

  クラスターが `IPv6` ファミリーで設定されている場合は、バージョン `1.10.1` のアドオンがインストールされている必要があります。プラグインバージョンが必要なバージョンよりも古い場合は、更新する必要があります。詳細については、「[Amazon VPC CNI を使用してポッドに IP を割り当てる](managing-vpc-cni.md)」の更新セクションを参照してください。
+  **Windows ノードのみのクラスターの場合** 
  + クラスターで Windows サポートを有効にする必要があります。詳細については、「[EKS クラスターに WiWindows ノードをデプロイする](windows-support.md)」を参照してください。

## ノードに IP アドレスプレフィックスを割り当てる
<a name="cni-increase-ip-procedure"></a>

ノードに IP アドレスプレフィックスを割り当てるようにクラスターを設定します。ノードのオペレーティングシステムに対応する手順を完了します。

### Linux
<a name="_linux"></a>

1. パラメータを有効にして、Amazon VPC CNI DaemonSet のネットワークインターフェイスにプレフィックスを割り当てます。クラスターをデプロイすると、バージョン `1.10.1` 以降の Amazon VPC CNI plugin for Kubernetes アドオンも同時にデプロイされます。`IPv6` ファミリーを使用してクラスターを作成している場合、この設定はデフォルトで `true` に設定されています。`IPv4` ファミリーを使用してクラスターを作成している場合、この設定はデフォルトで `false` に設定されています。

   ```
   kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true
   ```
**重要**  
サブネットに使用可能な IP アドレスがある場合でも、サブネットに使用可能な `/28` 個の連続したブロックがない場合には、Amazon VPC CNI plugin for Kubernetes ログに次のエラーが記述されます。  

   ```
   InsufficientCidrBlocks: The specified subnet does not have enough free cidr blocks to satisfy the request
   ```
これは、サブネット全体に広がる既存のセカンダリ IP アドレスの断片化が原因で発生する可能性があります。このエラーを解決するには、新しいサブネットを作成してそこに Pod を起動するか、Amazon EC2 サブネットの CIDR 予約を使用して、プレフィックス割り当てで使用するサブネット内の領域を予約します。詳細については、Amazon VPC ユーザーガイドの「[サブネット CIDR の予約](https://docs.aws.amazon.com/vpc/latest/userguide/subnet-cidr-reservation.html)」を参照してください。

1. 前提条件のリストに記載されたバージョン以降の Amazon VPC CNI plugin for Kubernetes を使用しながら、起動テンプレートなしでマネージドノードグループをデプロイする場合、または AMI ID を指定していない起動テンプレートを使用してデプロイする場合には、このまま次のステップに進みます。マネージド型ノードグループは、Pod の最大数を自動的に計算します。

   AMI ID を指定した起動テンプレートを使用して、セルフマネージド型ノードグループまたはマネージド型ノードグループをデプロイする場合は、Amazon EKS でノードの推奨最大 Pod 数を決定する必要があります。「」の指示に従い、ステップ 3 に `--cni-prefix-delegation-enabled` を追加します。後のステップで使用するために、出力に注意してください。
**重要**  
マネージド型ノードグループは、`maxPods` の値に最大数を適用します。vCPUs が 30 未満のインスタンスの場合、最大数は 110 で、その他すべてのインスタンスの最大数は 250 です。この最大数は、プレフィックス委任が有効かどうかにかかわらず適用されます。

1. `IPv6` 用に設定されたクラスターを使用している場合は、このまま次のステップに進みます。

   以下のオプションの内の 1 つでパラメータを指定します。どのオプションが適切で、どの値を提供するかを決定するには、GitHub の「[WARM\$1PREFIX\$1TARGET, WARM\$1IP\$1TARGET, and MINIMUM\$1IP\$1TARGET](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/prefix-and-ip-target.md)」を参照してください。

   example values は、ゼロより大きい値で置き換えます。
   +  `WARM_PREFIX_TARGET` 

     ```
     kubectl set env ds aws-node -n kube-system WARM_PREFIX_TARGET=1
     ```
   +  `WARM_IP_TARGET` または `MINIMUM_IP_TARGET` – この値を設定した場合、`WARM_PREFIX_TARGET` に対し設定されている値はすべて上書きされます。

     ```
     kubectl set env ds aws-node -n kube-system WARM_IP_TARGET=5
     ```

     ```
     kubectl set env ds aws-node -n kube-system MINIMUM_IP_TARGET=2
     ```

1. 少なくとも 1 つの Amazon EC2 Nitro Amazon Linux 2023 インスタンスタイプを使用して、次のいずれかのタイプのノードグループを作成します。Nitro インスタンスタイプのリストについては、「Amazon EC2 ユーザーガイド」の「[Instances built on the Nitro System](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances)」を参照してください。この機能は Windows ではサポートされていません。*110* が含まれているオプションの場合は、ステップ 3 の値 (推奨) または独自の値に置き換えてください。
   +  **セルフマネージド** –「[セルフマネージド Amazon Linux ノードを作成する](launch-workers.md)」の手順に従い、ノードグループをデプロイします。CloudFormation スタックを作成する前に、テンプレートファイルを開き、次のように `UserData` の `NodeLaunchTemplate` を調整します。

     ```
     ...
                 apiVersion: node.eks.aws/v1alpha1
                 kind: NodeConfig
                 spec:
                   cluster:
                     name: ${ClusterName}
                     apiServerEndpoint: ${ApiServerEndpoint}
                     certificateAuthority: ${CertificateAuthorityData}
                     cidr: ${ServiceCidr}
                   kubelet:
                     config:
                       maxPods: 110
     ...
     ```

     `eksctl` を使用してノードグループを作成する場合は、次のコマンドを使用できます。

     ```
     eksctl create nodegroup --cluster my-cluster --managed=false --max-pods-per-node 110
     ```
   +  **マネージド型** — 次のいずれかのオプションを使用して、ノードグループをデプロイします：
     +  **起動テンプレートがない場合、または AMI ID が指定されていない起動テンプレートを使用する場合** –「[クラスターのマネージドノードグループを作成する](create-managed-node-group.md)」の手順を完了します。マネージド型ノードグループは、Amazon EKS で推奨される `max-pods` の値を自動的に計算します。
     +  **指定した AMI ID を持つ起動テンプレート** — 起動テンプレートで Amazon EKS 最適化 AMI ID を指定するか、Amazon EKS 最適化 AMI から構築されたカスタム AMI を指定してから、[起動テンプレートを使用してノードグループをデプロイ](launch-templates.md)起動テンプレートでは、次のユーザーデータを指定します。このユーザーデータが `NodeConfig` オブジェクトを渡してノードの `nodeadm` ツールによって読み取られます。`nodeadm` の詳細については、[nodeadm のドキュメント](https://awslabs.github.io/amazon-eks-ami/nodeadm)を参照してください。

       ```
       MIME-Version: 1.0
       Content-Type: multipart/mixed; boundary="//"
       
       --//
       Content-Type: application/node.eks.aws
       
       ---
       apiVersion: node.eks.aws/v1alpha1
       kind: NodeConfig
       spec:
        cluster:
          apiServerEndpoint: [.replaceable]`my-cluster`
          certificateAuthority: [.replaceable]`LS0t...`
          cidr: [.replaceable]`10.100.0.0/16`
          name: [.replaceable]`my-cluster
        kubelet:
          config:
            maxPods: [.replaceable]`110`
       --//--
       ```

       `eksctl` を使用してノードグループを作成する場合は、次のコマンドを使用できます。

       ```
       eksctl create nodegroup --cluster my-cluster --max-pods-per-node 110
       ```

       Amazon EKS 最適化 AMI から構築されていないカスタム AMI を作成した場合は、自分で設定をカスタム作成する必要があります。
**注記**  
また、インスタンスとは異なるサブネットの Pod に IP アドレスを割り当てる場合は、このステップで機能を有効化する必要があります。詳細については、「[カスタムネットワーキングを使用して代替サブネットに Pod をデプロイする](cni-custom-network.md)」を参照してください。

### Server
<a name="_windows"></a>

1. IP プレフィックスの割り当てを有効にします。

   1. 編集する `amazon-vpc-cni` `ConfigMap` を開きます。

      ```
      kubectl edit configmap -n kube-system amazon-vpc-cni -o yaml
      ```

   1. `data` セクションに次の行を追加します。

      ```
        enable-windows-prefix-delegation: "true"
      ```

   1. ファイルを保存し、エディタを閉じます。

   1. `ConfigMap` に行が追加されたことを確認します。

      ```
      kubectl get configmap -n kube-system amazon-vpc-cni -o "jsonpath={.data.enable-windows-prefix-delegation}"
      ```

      返された出力が `true` でない場合は、エラーが発生した可能性があります。ステップをもう一度実行してみてください。
**重要**  
サブネットに使用可能な IP アドレスがある場合でも、サブネットに使用可能な `/28` 個の連続したブロックがない場合には、Amazon VPC CNI plugin for Kubernetes ログに次のエラーが記述されます。  

      ```
      InsufficientCidrBlocks: The specified subnet does not have enough free cidr blocks to satisfy the request
      ```
これは、サブネット全体に広がる既存のセカンダリ IP アドレスの断片化が原因で発生する可能性があります。このエラーを解決するには、新しいサブネットを作成してそこに Pod を起動するか、Amazon EC2 サブネットの CIDR 予約を使用して、プレフィックス割り当てで使用するサブネット内の領域を予約します。詳細については、Amazon VPC ユーザーガイドの「[サブネット CIDR の予約](https://docs.aws.amazon.com/vpc/latest/userguide/subnet-cidr-reservation.html)」を参照してください。

1. (オプション) クラスターの事前スケーリング動作と動的スケーリング動作を制御するための追加設定を指定します。詳細については、「GitHub」の「[ Windows でのプレフィックス委任モードの設定オプション](https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/master/docs/windows/prefix_delegation_config_options.md)」を参照してください。

   1. 編集する `amazon-vpc-cni` `ConfigMap` を開きます。

      ```
      kubectl edit configmap -n kube-system amazon-vpc-cni -o yaml
      ```

   1. サンプル値を 0 より大きい値に置き換え、必要なエントリを `ConfigMap` の `data` セクションに追加します。`warm-ip-target` または `minimum-ip-target` のいずれかに値を設定した場合、その値は `warm-prefix-target` に設定された値をオーバーライドします。

      ```
        warm-prefix-target: "1"
        warm-ip-target: "5"
        minimum-ip-target: "2"
      ```

   1. ファイルを保存し、エディタを閉じます。

1. 少なくとも 1 つの Amazon EC2 Nitro インスタンスタイプで Windows ノードグループを作成します。Nitro インスタンスタイプのリストについては、「Amazon EC2 ユーザーガイド」の「[Instances built on the Nitro System](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/instance-types.html#ec2-nitro-instances)」を参照してください。デフォルトでは、1 つのノードにデプロイできる Pod の最大数は 110 です。この数値を増減させる場合は、ブートストラップ設定のユーザーデータに以下を指定します。*max-pods-quantity* を最大ポッド値に置き換えます。

   ```
   -KubeletExtraArgs '--max-pods=max-pods-quantity'
   ```

   マネージド型ノードグループをデプロイする場合は、この設定を起動テンプレートに追加する必要があります。詳細については、「[起動テンプレートを使用してマネージドノードをカスタマイズする](launch-templates.md)」を参照してください。Windows ブートストラップスクリプトの設定パラメータの詳細については、「[ブートストラップスクリプトの設定パラメータ](eks-optimized-windows-ami.md#bootstrap-script-configuration-parameters)」を参照してください。

## 最大 Pod 数と使用可能な IP アドレスを決定する
<a name="cni-increase-ip-verify"></a>

1. ノードがデプロイされると、クラスター内のノードの表示が可能になります。

   ```
   kubectl get nodes
   ```

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

   ```
   NAME                                             STATUS     ROLES    AGE   VERSION
   ip-192-168-22-103.region-code.compute.internal   Ready      <none>   19m   v1.XX.X-eks-6b7464
   ip-192-168-97-94.region-code.compute.internal    Ready      <none>   19m   v1.XX.X-eks-6b7464
   ```

1. いずれかのノードを記述して、そのノードの `max-pods` 値と使用可能な IP アドレスの数を決定します。*192.168.30.193* を、前の出力で返されたいずれかのノードの名前の `IPv4` アドレスに置き換えます。

   ```
   kubectl describe node ip-192-168-30-193.region-code.compute.internal | grep 'pods\|PrivateIPv4Address'
   ```

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

   ```
   pods:                                  110
   vpc.amazonaws.com/PrivateIPv4Address:  144
   ```

   前の出力にある `110` は、*144* 個の IP アドレスが使用可能であるにもかかわらず、Kubernetes がノードにデプロイする Pod の最大数です。

# セキュリティグループを個別の Pod に割り当てる
<a name="security-groups-for-pods"></a>

 **適用対象**: Amazon EC2 インスタンスを持つ Linux ノード

 **適用対象**: プライベートサブネット

Pod のセキュリティグループは、Amazon EC2 セキュリティグループを Kubernetes Pod と統合します。Amazon EC2 セキュリティグループを使用して、多くの Amazon EC2 インスタンスタイプと Fargate で実行されているノードにデプロイする Pod との間で送受信されるインバウンドおよびアウトバウンドネットワークトラフィックを許可するルールを定義できます。この機能の詳細な説明については「[ポッドのセキュリティグループの紹介](https://aws.amazon.com/blogs/containers/introducing-security-groups-for-pods)」の投稿を参照してください。

## Amazon VPC CNI plugin for Kubernetes 機能との互換性
<a name="security-groups-for-pods-compatability"></a>

Pod のセキュリティグループは、以下の機能で使用できます。
+ IPv4 ソースネットワークアドレス変換 - 詳細については「[Pod のアウトバウンドインターネットアクセスを有効にする](external-snat.md)」を参照してください。
+ クラスター、ポッド、サービスへの IPv6 アドレス - 詳細については「[クラスター、Pod、サービスに対する IPv6 アドレスの説明](cni-ipv6.md)」を参照してください。
+ Kubernetes ネットワークポリシーを使用したトラフィックの制限 - 詳細については、「[Kubernetes ネットワークポリシーにより Pod トラフィックを制限する](cni-network-policy.md)」を参照してください。

## 考慮事項
<a name="sg-pods-considerations"></a>

Pod のセキュリティグループをデプロイする前に、次の制限事項と条件を考慮してください。
+ Pod のセキュリティグループは、Windows ノードまたは EKS Auto Mode では使用できません。
+ Pod のセキュリティグループは、バージョン 1.16.0 以降の Amazon VPC CNI プラグインを使用して、Amazon EC2 ノードを含む `IPv6` ファミリー用に設定されたクラスターで使用できます。バージョン 1.7.7 以降の Amazon VPC CNI プラグインを使用すると、Fargate ノードのみを含むクラスター設定の `IPv6` ファミリーで Pod のセキュリティグループを使用できます。詳細については、[クラスター、Pod、サービスに対する IPv6 アドレスの説明](cni-ipv6.md)を参照してください。
+ Pod のセキュリティグループはほとんどの [Nitro ベース](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances)の Amazon EC2 インスタンスファミリーでサポートされていますが、ファミリーの全世代がサポートしているわけではありません。例えば、`m5`、`c5`、`r5`、`m6g`、、`c6g`、`r6g` インスタンスファミリーと世代ではサポートされています。`t` ファミリーのインスタンスタイプは一切サポートされていません。サポートされているインスタンスタイプの詳細なリストについては、GitHub で [limits.go](https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/v1.5.0/pkg/aws/vpc/limits.go) ファイルを参照してください。ノードはそのファイルで一覧表示されているインスタンスタイプのうち、`IsTrunkingCompatible: true` を含むものである必要があります。
+ カスタムネットワークと Pod のセキュリティグループを組み合わせて使用している場合、`ENIConfig` で指定されたセキュリティグループではなく、Pod のセキュリティグループによって指定されたセキュリティグループが使用されます。
+ Amazon VPC CNI プラグインのバージョン `1.10.2` 以前を使用していて、Pod の仕様に `terminationGracePeriodSeconds` 設定を含める場合は、設定の値を「0」にすることはできません。
+ Amazon VPC CNI プラグインのバージョン `1.10` 以前、またはデフォルト設定が `POD_SECURITY_GROUP_ENFORCING_MODE`=`strict` のバージョン `1.11` を使用している場合、`externalTrafficPolicy` が `Local` に設定されたインスタンスターゲットを使用するタイプ `NodePort` および `LoadBalancer` の Kubernetes サービスは、セキュリティグループを割り当てる Pod ではサポートされていません。インスタンスターゲットでのロードバランサーの使用の詳細については「[Network Load Balancer を使用して TCP および UDP トラフィックをルーティングする](network-load-balancing.md)」を参照してください。
+ Amazon VPC CNI プラグインのバージョン `1.10` 以前、またはデフォルト設定が `POD_SECURITY_GROUP_ENFORCING_MODE`=`strict` のバージョン `1.11` を使用している場合、セキュリティグループが割り当てられた Pod からのアウトバウンドトラフィックに対してソース NAT が無効になり、その結果アウトバウンドセキュリティグループルールが適用されます。インターネットにアクセスするには、セキュリティグループが割り当てられた Pod を、NAT ゲートウェイまたはインスタンスで構成されたプライベートサブネットにデプロイされたノードで起動する必要があります。パブリックサブネットにデプロイされたセキュリティグループが割り当てられたポッドは、インターネットにアクセスできません。

  `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard` に設定されたプラグインのバージョン `1.11` 以降を使用している場合、VPC の外部を送信先とする Pod トラフィックはインスタンスのプライマリネットワークインターフェイスの IP アドレスに変換されます。このトラフィックには Pod のセキュリティグループ内のルールではなく、プライマリネットワークインターフェイスのセキュリティグループ内のルールが使用されます。
+ セキュリティグループが関連付けられている Pod で Calico ネットワークポリシーを使用するには、Amazon VPC CNI プラグインのバージョン `1.11.0` 以降を使用し、かつ `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard` に設定することが必要になります。それ以外の場合は、セキュリティグループが関連付けられている Pod との間のトラフィックフローに Calico ネットワークポリシーは適用されず、Amazon EC2 セキュリティグループの適用のみに限定されます。Amazon VPC CNI バージョンを更新するには「[Amazon VPC CNI を使用して Pod に IP を割り当てる](managing-vpc-cni.md)」を参照してください 
+ [NodeLocal DNSCache](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) を使用するクラスターのセキュリティグループを使用する Amazon EC2 ノードで実行されている Pod は、Amazon VPC CNI プラグインのバージョンが `1.11.0` 以降で `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard` に設定されている場合にのみサポートされます。Amazon VPC CNI プラグインのバージョンを更新するには「[Amazon VPC CNI を使用して Pod に IP を割り当てる](managing-vpc-cni.md)」を参照してください 
+ Pod のセキュリティグループは、解約率が高い Pod の場合、Pod の起動レイテンシーがより高くなる可能性があります。これはリソースコントローラーのレート制限によるものです。
+ EC2 セキュリティグループのスコープは Pod レベル - 詳細については「[セキュリティグループ](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html)」を参照してください。

  `POD_SECURITY_GROUP_ENFORCING_MODE=standard` および `AWS_VPC_K8S_CNI_EXTERNALSNAT=false` を設定した場合、VPC 外部のエンドポイント宛てのトラフィックは、Pod のセキュリティグループではなくノードのセキュリティグループを使用します。

# Amazon EKS Pod のセキュリティグループ用に Amazon VPC CNI Plugin for Kubernetes を設定する
<a name="security-groups-pods-deployment"></a>

Amazon EC2 インスタンスで Pod を使用する場合は、セキュリティグループ用に Amazon VPC CNI Plugin for Kubernetes を設定する必要があります。

Fargate Pod のみを使用し、クラスターに Amazon EC2 ノードがない場合は、「[Amazon EKS Pod のセキュリティグループポリシーを使用する](sg-pods-example-deployment.md)」を参照してください。

1. 次のコマンドを使用して、現在の Amazon VPC CNI Plugin for Kubernetes のバージョンをチェックします。

   ```
   kubectl describe daemonset aws-node --namespace kube-system | grep amazon-k8s-cni: | cut -d : -f 3
   ```

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

   ```
   v1.7.6
   ```

   Amazon VPC CNI Plugin for Kubernetes のバージョンが `1.7.7` より前の場合は、プラグインをバージョン `1.7.7` 以降に更新してください。詳細については、[Amazon VPC CNI を使用して Pod に IP を割り当てる](managing-vpc-cni.md)を参照してください。

1. [AmazonEKSVPCResourceController](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AmazonEKSVPCResourceController) マネージド IAM ポリシーを Amazon EKS クラスターに関連付けられている[クラスターロール](cluster-iam-role.md#create-service-role)に追加します。ポリシーにより、ロールはネットワークインターフェイス、プライベート IP アドレス、およびネットワークインスタンスへのアタッチとデタッチを管理できます。

   1. クラスター IAM ロールの名前を取得し、変数に格納します。*マイクラスター* の部分は自分のクラスター名に置き換えます。

      ```
      cluster_role=$(aws eks describe-cluster --name my-cluster --query cluster.roleArn --output text | cut -d / -f 2)
      ```

   1. ロールへのポリシーの付与

      ```
      aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSVPCResourceController --role-name $cluster_role
      ```

1. Amazon VPC CNI アドオンを有効にして Pod のネットワークインターフェイスを管理するには、`aws-node` DaemonSet で `ENABLE_POD_ENI` 変数を `true` に設定します。この設定が `true` になると、クラスター内の各ノードについて、アドオンにより `cninode` カスタムリソースが作成されます。VPC リソースコントローラーは、1 つの特別なネットワークインターフェイスを作成してアタッチします。これは、*トランクネットワークインターフェイス*と呼ばれ、説明は `aws-k8s-trunk-eni` です。

   ```
   kubectl set env daemonset aws-node -n kube-system ENABLE_POD_ENI=true
   ```
**注記**  
トランクネットワークインターフェイスは、インスタンスタイプでサポートされているネットワークインターフェイスの最大数に含まれます。各インスタンスタイプによりサポートされるネットワークインターフェイスの最大数のリストについては、「Amazon EC2 ユーザーガイド」の「[各インスタンスタイプのネットワークインターフェイスあたりの IP アドレス数](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI)」を参照してください。ノードにすでに最大数の標準ネットワークインターフェイスがアタッチされている場合、VPC リソースコントローラーはスペースを予約します。コントローラーが標準ネットワークインターフェイスをデタッチして削除し、トランクネットワークインターフェイスを作成し、インスタンスにアタッチできるように、実行中の Pod をスケールダウンする必要があります。

1. `CNINode` カスタムリソースがどのノードにあるか、次のコマンドで確認できます。[`No resources found`] が返された場合、数秒待ってから、もう一度試してください。前のステップで、Amazon VPC CNI Plugin for Kubernetes Pod を再起動する必要があります。再起動には数秒かかります。

   ```
   kubectl get cninode -A
        NAME FEATURES
        ip-192-168-64-141.us-west-2.compute.internal [{"name":"SecurityGroupsForPods"}]
        ip-192-168-7-203.us-west-2.compute.internal [{"name":"SecurityGroupsForPods"}]
   ```

   `1.15` より古いバージョンの VPC CNI バージョンを使用している場合は、`CNINode` カスタムリソースの代わりにノードラベルが使用されていました。`true` に設定されているノードラベル `aws-k8s-trunk-eni` がどのノードにあるか、次のコマンドで確認できます。[`No resources found`] が返された場合、数秒待ってから、もう一度試してください。前のステップで、Amazon VPC CNI Plugin for Kubernetes Pod を再起動する必要があります。再起動には数秒かかります。

   ```
   kubectl get nodes -o wide -l vpc.amazonaws.com/has-trunk-attached=true
   ```

   トランクネットワークインターフェイスが作成されると、Pod にはトランクネットワークインターフェイスまたは標準ネットワークインターフェイスのセカンダリ IP アドレスが割り当てられます。ノードが削除されると、トランクインターフェイスは自動的に削除されます。

   後のステップで Pod のセキュリティグループをデプロイすると、VPC リソースコントローラーは*ブランチネットワークインターフェイス*と呼ばれる特別なインターフェイスを `aws-k8s-branch-eni` の説明と共に作成し、セキュリティグループを関連付けます。ノードにアタッチされた標準ネットワークインターフェイスとトランクネットワークインターフェイスに加えて、ブランチネットワークインターフェイスが作成されます。

   Liveness プローブまたは Readiness プローブを使用している場合は、*TCP Early Demux* も無効にする必要があります。これにより、`kubelet` は TCP を使用してブランチネットワークインターフェイス上の Pod に接続できます。TCP Early Demux を無効にするには、次のコマンドを実行します。

   ```
   kubectl patch daemonset aws-node -n kube-system \
     -p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'
   ```
**注記**  
Amazon VPC CNI Plugin for Kubernetes アドオンのバージョン `1.11.0` 以降を使用し、かつ `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard` に設定している場合、次のステップで説明されているように、前のコマンドを実行する必要はありません。

1. クラスターで `NodeLocal DNSCache` が使用されている場合、独自のセキュリティグループを持つ Pod で Calico ネットワークポリシーを使用する場合、またはセキュリティグループを割り当てる Pod に対して `externalTrafficPolicy` を `Local` に設定したインスタンスターゲットを使用するタイプ `NodePort` および `LoadBalancer` の Kubernetes サービスがある場合、バージョン `1.11.0` 以降の Amazon VPC CNI Plugin for Kubernetes アドオンを使用して次の設定を有効にする必要があります。

   ```
   kubectl set env daemonset aws-node -n kube-system POD_SECURITY_GROUP_ENFORCING_MODE=standard
   ```

   重要: **Pod のセキュリティグループルールは、`kubelet` や `nodeLocalDNS` など、同じノードにある Pod とサービスの間のトラフィックまたは Pod 間のトラフィックには適用されません。同じノードで異なるセキュリティグループを使用するポッドは、異なるサブネットに設定されているため通信できません。また、これらのサブネット間のルーティングは無効になっています。**Pod から VPC の外部のアドレスへのアウトバウンドトラフィックは、インスタンスのプライマリネットワークインターフェイスの IP アドレスに変換されたネットワークアドレスです (`AWS_VPC_K8S_CNI_EXTERNALSNAT=true` に設定していない場合)。このトラフィックには Pod のセキュリティグループ内のルールではなく、プライマリネットワークインターフェイスのセキュリティグループ内のルールが使用されます。\$1\$1 この設定を既存のPod に適用するには、Pod または Pod が実行されているノードを再起動する必要があります。

1. Pod のセキュリティグループポリシーの使用方法については、「[Amazon EKS Pod のセキュリティグループポリシーを使用する](sg-pods-example-deployment.md)」を参照してください。

# Amazon EKS Pod のセキュリティグループポリシーを使用する
<a name="sg-pods-example-deployment"></a>

Pod のセキュリティグループを使用するには、既存のセキュリティグループが必要です。次のステップは、Pod に対してセキュリティグループポリシーを使用する方法を示しています。次のステップではターミナル間で保持されない変数が使用されるため、特に明記されていない限り、同じターミナルからすべてのステップを完了してください。

Amazon EC2 インスタンスを持つ Pod がある場合は、この手順を使用する前にプラグインを設定する必要があります。詳細については、「[Amazon EKS Pod のセキュリティグループ用に Amazon VPC CNI Plugin for Kubernetes を設定する](security-groups-pods-deployment.md)」を参照してください。

1.  リソースをデプロイする Kubernetes 名前空間を作成します。*my-namespace* は使用する名前空間の名前に置き換えることができます。

   ```
   kubectl create namespace my-namespace
   ```

1.  アマゾン EKS `SecurityGroupPolicy` をクラスターにデプロイします。

   1. 次のコンテンツをデバイスにコピーします。サービスアカウントラベルに基づいて Pod を選択したい場合は、*podSelector* を `serviceAccountSelector` で置き換えることができます。セレクターをどちらか 1 つ指定する必要があります。`podSelector` が空 (例: `podSelector: {}`) であると、名前空間内のすべての Pod が選択されます。*my-role* は自分の役割名に変更できます。`serviceAccountSelector` が空であると、名前空間内のすべてのサービスアカウントが選択されます。*my-security-group-policy* を自分の `SecurityGroupPolicy` の名前に置き換え、*my-namespace* は `SecurityGroupPolicy` を作成する名前空間に置き換えることができます。

      *my\$1pod\$1security\$1group\$1id* を既存のセキュリティグループの ID に置き換える必要があります。既存のセキュリティグループがない場合は作成する必要があります。詳細については「[アマゾン EC2 ユーザーガイド](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/)」の「[アマゾン EC2 security groups for リナックス instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)」(リナックス インスタンス用の アマゾン EC2 セキュリティグループ) を参照してください。1～5 個のセキュリティグループ ID を指定できます。複数の ID を指定した場合、すべてのセキュリティグループ内のすべてのルールの組み合わせが、選択した Pod に対して有効になります。

      ```
      cat >my-security-group-policy.yaml <<EOF
      apiVersion: vpcresources.k8s.aws/v1beta1
      kind: SecurityGroupPolicy
      metadata:
        name: my-security-group-policy
        namespace: my-namespace
      spec:
        podSelector:
          matchLabels:
            role: my-role
        securityGroups:
          groupIds:
            - my_pod_security_group_id
      EOF
      ```
**重要**  
Pod に対して指定した 1 つまたは複数のセキュリティグループは次の基準を満たす必要があります。  
存在している必要があります。存在しない場合、セレクターに一致する Pod をデプロイすると、Pod は作成プロセスでスタックしたままになります。Pod の説明を書き込むと、次のようなエラーメッセージが表示されます: `An error occurred (InvalidSecurityGroupID.NotFound) when calling the CreateNetworkInterface operation: The securityGroup ID 'sg-05b1d815d1EXAMPLE' does not exist`。
プローブを設定した任意のポートを介して、ノードに適用されたセキュリティ グループ (`kubelet` の場合) からのインバウンド通信を許可する必要があります。
`TCP` および `UDP` ポート 53 番経由のアウトバウンド通信を、CoreDNS を実行しているPod (または Pod が実行されるノード) に割り当てられたセキュリティグループへ許可する必要があります。CoreDNS Pod のセキュリティグループは、指定したセキュリティグループからのインバウンド `TCP` および `UDP` ポート 53 番トラフィックを許可する必要があります。
セキュリティグループには、通信を行う必要がある他の Pod との通信に必要なインバウンドルールとアウトバウンドルールを含める必要があります。
Fargate でセキュリティグループを使用している場合は、セキュリティグループに、Pod と Kubernetes コントロールプレーンとの通信を許可するルールを含める必要があります。最も簡単な方法はクラスターセキュリティグループをセキュリティグループの 1 つとして指定することです。
セキュリティグループポリシーは、新しくスケジュールされた Pod にのみ適用されます。実行中の Pod には影響しません。

   1. ポリシーをデプロイします。

      ```
      kubectl apply -f my-security-group-policy.yaml
      ```

1. 前のステップで指定した *podSelector* の *my-role* の値に一致するラベルを持つサンプルアプリケーションをデプロイします。

   1. 次のコンテンツをデバイスにコピーします。サンプル値を独自のものに置き換えて、変更したコマンドを実行してください。*my-role* を置き換える場合は前のステップでセレクターに指定した値と同じであることを確認してください。

      ```
      cat >sample-application.yaml <<EOF
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: my-deployment
        namespace: my-namespace
        labels:
          app: my-app
      spec:
        replicas: 4
        selector:
          matchLabels:
            app: my-app
        template:
          metadata:
            labels:
              app: my-app
              role: my-role
          spec:
            terminationGracePeriodSeconds: 120
            containers:
            - name: nginx
              image: public.ecr.aws/nginx/nginx:1.23
              ports:
              - containerPort: 80
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: my-app
        namespace: my-namespace
        labels:
          app: my-app
      spec:
        selector:
          app: my-app
        ports:
          - protocol: TCP
            port: 80
            targetPort: 80
      EOF
      ```

   1. 次のコマンドを使用して、アプリケーションをデプロイします。アプリケーションをデプロイすると、Amazon VPC CNI Plugin for Kubernetes が `role` ラベルと一致し、前のステップで指定したセキュリティグループが Pod に適用されます。

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

1. サンプルアプリケーションでデプロイされた Pod を表示します。このトピックの以降の説明ではこのターミナルを `TerminalA` と呼びます。

   ```
   kubectl get pods -n my-namespace -o wide
   ```

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

   ```
   NAME                             READY   STATUS    RESTARTS   AGE     IP               NODE                                            NOMINATED NODE   READINESS GATES
   my-deployment-5df6f7687b-4fbjm   1/1     Running   0          7m51s   192.168.53.48    ip-192-168-33-28.region-code.compute.internal   <none>           <none>
   my-deployment-5df6f7687b-j9fl4   1/1     Running   0          7m51s   192.168.70.145   ip-192-168-92-33.region-code.compute.internal   <none>           <none>
   my-deployment-5df6f7687b-rjxcz   1/1     Running   0          7m51s   192.168.73.207   ip-192-168-92-33.region-code.compute.internal   <none>           <none>
   my-deployment-5df6f7687b-zmb42   1/1     Running   0          7m51s   192.168.63.27    ip-192-168-33-28.region-code.compute.internal   <none>           <none>
   ```
**注記**  
Pod がスタックしている場合は次のヒントをお試しください。  
`Waiting` 状態でスタックした Pod があれば、`kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace ` を実行してください。`Insufficient permissions: Unable to create Elastic Network Interface.` が表示された場合、前のステップで IAM クラスター役割に IAM ポリシーを追加したことを確認します。
Pod が `Pending` 状態でスタックした場合、ノードのインスタンスタイプが [limits.go](https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/master/pkg/aws/vpc/limits.go) のリストに含まれていることを確認します。そのうえで、インスタンスタイプでサポートされるブランチネットワークインターフェイスの最大製品数とノードグループ内のノード数を乗算した数にまだ達していないことを確認します。例えば、`m5.large` インスタンスでは9 つのブランチネットワークインターフェイスがサポートされています。ノードグループに 5 つのノードがある場合、ノードグループに対して最大 45 のブランチネットワークインターフェイスを作成できます。46 番目の Pod をデプロイしようとすると、セキュリティグループに関連付けられた別の Pod が削除されるまで `Pending` 状態のままになります。

   `kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace ` を実行したときに次のようなメッセージが表示されている場合は、無視しても問題ありません。このメッセージは、Amazon VPC CNI Plugin for Kubernetes がホストネットワークの設定を試み、ネットワークインターフェイスの作成中に失敗したときに表示される場合があります。プラグインはネットワークインターフェイスが作成されるまで、このイベントをログに記録します。

   ```
   Failed to create Pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "e24268322e55c8185721f52df6493684f6c2c3bf4fd59c9c121fd4cdc894579f" network for Pod "my-deployment-5df6f7687b-4fbjm": networkPlugin
   cni failed to set up Pod "my-deployment-5df6f7687b-4fbjm-c89wx_my-namespace" network: add cmd: failed to assign an IP address to container
   ```

   インスタンスタイプで実行できる Pod の最大数を超えることはできません。各インスタンスタイプで実行できるポッドの最大数の一覧については、GitHub の「[eni-max-pods.txt](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/misc/eni-max-pods.txt)」を参照してください。セキュリティグループが関連付けられているポッドを削除するか、ポッドが実行されているノードを削除すると、VPC リソースコントローラーによってブランチネットワークインターフェイスが削除されます。セキュリティグループ用に Pod を含むクラスターを Pod で削除する場合、コントローラーではブランチネットワークインターフェイスを削除しないため、自分で削除する必要があります。ネットワークインターフェイスの削除方法の詳細については「Amazon EC2 ユーザーガイド」の「[ネットワークインターフェイスの削除](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#delete_eni)」を参照してください。

1. 別のターミナルで、Pod のいずれかをシェルで操作します。このトピックの以降の説明ではこのターミナルを `TerminalB` と呼びます。*5df6f7687b-4fbjm* を、前の手順の出力で返された Pod のいずれかの ID に置き換えます。

   ```
   kubectl exec -it -n my-namespace my-deployment-5df6f7687b-4fbjm -- /bin/bash
   ```

1. `TerminalB` のシェルから、サンプルアプリケーションが動作することを確認します。

   ```
   curl my-app
   ```

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

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

   アプリケーションを実行しているすべての Pod が作成したセキュリティグループに関連付けられているため、出力を受信できます。そのグループにはセキュリティグループが関連付けられているすべての Pod 間のすべてのトラフィックを許可するルールが含まれています。DNS トラフィックはそのセキュリティグループからノードに関連付けられているクラスターセキュリティグループへのアウトバウンドで許可されます。ノードは、Pod が名前のルックアップを実行した CoreDNS Pod を実行しています。

1. `TerminalA` で、クラスターセキュリティグループへの DNS 通信を許可するセキュリティグループルールを、セキュリティグループから削除します。前のステップで DNS ルールをクラスターセキュリティグループに追加しなかった場合は*\$1my\$1cluster\$1security\$1group\$1id* を、ルールを作成したセキュリティグループの ID で置き換えます。

   ```
   aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_tcp_rule_id
   aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_udp_rule_id
   ```

1. `TerminalB` で、アプリケーションにもう一度アクセスしてみます。

   ```
   curl my-app
   ```

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

   ```
   curl: (6) Could not resolve host: my-app
   ```

   クラスターセキュリティグループが関連付けられている CoreDNS Pod に Pod がアクセスできなくなったため、この試行は失敗します。クラスターセキュリティグループから、Pod に関連付けられたセキュリティグループからの DNS 通信を許可するセキュリティグループルールがなくなりました。

   前のステップで、いずれかの Pod に返された IP アドレスを使用してアプリケーションにアクセスしようとすると、セキュリティグループが関連付けられており、名前のルックアップが不要な Pod 間ですべてのポートが許可されているため、引き続き応答を受信します。

1. 試行し終えたら、作成したサンプルのセキュリティグループポリシー、アプリケーション、およびセキュリティグループを削除できます。`TerminalA` から、次のコマンドを実行してください。

   ```
   kubectl delete namespace my-namespace
   aws ec2 revoke-security-group-ingress --group-id $my_pod_security_group_id --security-group-rule-ids $my_inbound_self_rule_id
   wait
   sleep 45s
   aws ec2 delete-security-group --group-id $my_pod_security_group_id
   ```

# 複数のネットワークインターフェイスをポッドにアタッチする
<a name="pod-multiple-network-interfaces"></a>

デフォルトでは、Amazon VPC CNI プラグインは各ポッドに 1 つの IP アドレスを割り当てます。この IP アドレスは、ポッドのすべての送受信トラフィックを処理する *Elastic Network Interface* にアタッチされます。帯域幅とパケット/秒レートのパフォーマンスを向上させるには、VPC CNI の*マルチ NIC 機能*を使用してマルチホームポッドを設定できます。マルチホームポッドは、複数のネットワークインターフェイス (および複数の IP アドレス) を使用する単一の Kubernetes ポッドです。マルチホームポッドを実行すると、同時接続を使用してアプリケーショントラフィックを複数のネットワークインターフェイスに分散できます。これは、人工知能 (AI)、機械学習 (ML)、ハイパフォーマンスコンピューティング (HPC) のユースケースに特に役立ちます。

次の図は、複数のネットワークインターフェイスカード (NIC) が使用されているワーカーノードで実行されているマルチホームポッドを示しています。

![\[2 つのネットワークインターフェイスが接続されたマルチホームポッドで、一方のネットワークインターフェイスには ENA、もう一方のネットワークインターフェイスには ENA と EFA を備えているもの\]](http://docs.aws.amazon.com/ja_jp/eks/latest/userguide/images/multi-homed-pod.png)


## 背景
<a name="pod-multi-nic-background"></a>

Amazon EC2 では、*Elastic Network Interface* は仮想ネットワークカードを表す VPC 内の論理ネットワーキングコンポーネントです。多くの EC2 インスタンスタイプでは、ネットワークインターフェイスはハードウェア内で単一のネットワークインターフェイスカード (NIC) を共有します。この単一の NIC には、最大帯域幅とパケット毎秒レートがあります。

マルチ NIC 機能が有効になっている場合、VPC CNI は、デフォルトでは行われる IP アドレスの一括割り当てを行いません。代わりに、VPC CNI は、新しいポッドの起動時に、各ネットワークカードのネットワークインターフェイスに 1 つの IP アドレスをオンデマンドで割り当てます。この動作により、マルチホームポッドを使用することで増加する IP アドレスの枯渇率が低下します。VPC CNI はオンデマンドで IP アドレスを割り当てるため、マルチ NIC 機能が有効になっているインスタンスではポッドが起動するまでに時間がかかる場合があります。

## 考慮事項
<a name="pod-multi-nic-considerations"></a>
+ Kubernetes クラスターで VPC CNI バージョン `1.20.0` 以降が実行されていることを確認します。マルチ NIC 機能は、VPC CNI のバージョン `1.20.0` 以降でのみ使用できます。
+ VPC CNI プラグインで `ENABLE_MULTI_NIC` 環境変数を有効にします。次のコマンドを実行して変数を設定し、DaemonSet のデプロイを開始できます。
  +  `kubectl set env daemonset aws-node -n kube-system ENABLE_MULTI_NIC=true` 
+ 複数のネットワークインターフェイスカード (NIC) を持つワーカーノードを作成してください。複数のネットワークインターフェイスカードを持つ EC2 インスタンスのリストについては、「**Amazon EC2 ユーザーガイド**」の「[ネットワークカード](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#network-cards)」を参照してください。
+ マルチ NIC 機能が有効になっている場合、VPC CNI は、デフォルトでは行われる IP アドレスの一括割り当てを行いません。VPC CNI はオンデマンドで IP アドレスを割り当てるため、マルチ NIC 機能が有効になっているインスタンスではポッドが起動するまでに時間がかかる場合があります。詳細については、前の「[背景](#pod-multi-nic-background)」セクションを参照してください。
+ マルチ NIC 機能を有効にしても、デフォルトではポッドは複数のネットワークインターフェイスを持ちません。マルチ NIC を使用するように各ワークロードを設定する必要があります。複数のネットワークインターフェイスを持つ必要があるワークロードに `k8s.amazonaws.com/nicConfig: multi-nic-attachment` 注釈を追加します。

### `IPv6` に関する考慮事項
<a name="pod-multi-nic-considerations-ipv6"></a>
+  **カスタム IAM ポリシー** - `IPv6` クラスターの場合は、VPC CNI に次のカスタム IAM ポリシーを作成して使用します。このポリシーはマルチ NIC に固有です。`IPv6` クラスターでの VPC CNI の使用に関する一般的な情報については、「[クラスター、Pod、サービスに対する IPv6 アドレスの説明](cni-ipv6.md)」を参照してください。

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "AmazonEKSCNIPolicyIPv6MultiNIC",
              "Effect": "Allow",
              "Action": [
                  "ec2:CreateNetworkInterface",
                  "ec2:DescribeInstances",
                  "ec2:AssignIpv6Addresses",
                  "ec2:DetachNetworkInterface",
                  "ec2:DescribeNetworkInterfaces",
                  "ec2:DescribeTags",
                  "ec2:ModifyNetworkInterfaceAttribute",
                  "ec2:DeleteNetworkInterface",
                  "ec2:DescribeInstanceTypes",
                  "ec2:UnassignIpv6Addresses",
                  "ec2:AttachNetworkInterface",
                  "ec2:DescribeSubnets"
              ],
              "Resource": "*"
          },
          {
              "Sid": "AmazonEKSCNIPolicyENITagIPv6MultiNIC",
              "Effect": "Allow",
              "Action": "ec2:CreateTags",
              "Resource": "arn:aws:ec2:*:*:network-interface/*"
          }
      ]
  }
  ```
+  `IPv6` **移行メカニズムは使用できません** - マルチ NIC 機能を使用する場合、VPC CNI は`IPv6` クラスター上のポッドに `IPv4` アドレスを割り当てません。それ以外の場合、VPC CNI はホストローカル `IPv4` アドレスを各ポッドに割り当て、ポッドが別の Amazon VPC またはインターネットの外部 `IPv4` リソースと通信できるようにします。

## 使用方法
<a name="pod-multi-NIC-usage"></a>

VPC CNI でマルチ NIC 機能を有効にし、`aws-node` ポッドを再起動すると、各ワークロードをマルチホームに設定できます。次の YAML 設定の例では、必要な注釈が付けられています。

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: orders-deployment
  namespace: ecommerce
  labels:
    app: orders
spec:
  replicas: 3
  selector:
    matchLabels:
      app: orders
  template:
    metadata:
      annotations:
         k8s.amazonaws.com/nicConfig: multi-nic-attachment
      labels:
        app: orders
    spec:
...
```

## よくある質問
<a name="pod-muti-nic-faqs"></a>

### **1. ネットワークインターフェイスカード (NIC) とは**
<a name="pod-muti-nic-faqs-nic"></a>

ネットワークインターフェイスカード (NIC) は、単にネットワークカードとも呼ばれ、基盤となるクラウドコンピューティングハードウェアのネットワーク接続を可能にする物理デバイスです。最新の EC2 サーバーでは、これは Nitro ネットワークカードを指します。Elastic Network Interface (ENI) は、この基盤となるネットワークカードの仮想表現です。

一部の EC2 インスタンスタイプには、帯域幅とパケットレートのパフォーマンスを向上させるために複数の NIC があります。このようなインスタンスでは、追加のネットワークカードにセカンダリ ENI を割り当てることができます。例えば、ENI \$11 はネットワークカードインデックス 0 にアタッチされた NIC のインターフェイスとして機能しますが、ENI \$12 は別のネットワークカードインデックスにアタッチされた NIC のインターフェイスとして機能します。

### **2. マルチホームポッドとは**
<a name="pod-muti-nic-faqs-pod"></a>

マルチホームポッドは、複数のネットワークインターフェイス (および複数の IP アドレスを暗示) を持つ単一の Kubernetes ポッドです。各ポッドネットワークインターフェイスは [Elastic Network Interface (ENI)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) に関連付けられており、これらの ENI は基盤となるワーカーノード上の個別の NIC の論理表現です。複数のネットワークインターフェイスを使用すると、マルチホームポッドのデータ転送容量が増え、データ転送速度も上がります。

**重要**  
VPC CNI は、複数の NIC を持つインスタンスタイプでのみマルチホームポッドを設定できます。

### **3. この機能を使用する理由は何ですか?**
<a name="pod-muti-nic-faqs-why"></a>

Kubernetes ベースのワークロードでネットワークパフォーマンスをスケールする必要がある場合は、マルチ NIC 機能を使用して、ENA デバイスがアタッチされているすべての基盤となる NIC とインターフェイスで通信するマルチホームポッドを実行できます。追加のネットワークカードを使用すると、複数の同時接続にアプリケーショントラフィックを分散することで、アプリケーションの帯域幅容量とパケットレートのパフォーマンスが向上します。これは、人工知能 (AI)、機械学習 (ML)、ハイパフォーマンスコンピューティング (HPC) のユースケースに特に役立ちます。

### **4. この機能の使用方法を教えてください。**
<a name="pod-muti-nic-faqs-how-to-enable"></a>

1. まず、Kubernetes クラスターが VPC CNI バージョン 1.20 以降を使用していることを確認する必要があります。VPC CNI を EKS アドオンとして更新する手順については、「[Amazon VPC CNI を更新する (Amazon EKS アドオン)](vpc-add-on-update.md)」を参照してください。

1. 次に、`ENABLE_MULTI_NIC` 環境変数を使用して、VPC CNI でマルチ NIC サポートを有効にする必要があります。

1. 次に、複数のネットワークカードを持つノードを作成して結合する必要があります。複数のネットワークカードを持つ EC2 インスタンスタイプのリストについては、「*Amazon EC2 ユーザーガイド*」の「[ネットワークカード](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#network-cards)」を参照してください。

1. 最後に、複数のネットワークインターフェイス (マルチホームポッド) を使用するか、単一のネットワークインターフェイスを使用するかのいずれかに各ワークロードを設定します。

### **5. サポートされているワーカーノードで複数の NIC を使用するようにワークロードを設定するにはどうすればよいですか?**
<a name="pod-muti-nic-faqs-how-to-workloads"></a>

マルチホームポッドを使用するには、注釈 `k8s.amazonaws.com/nicConfig: multi-nic-attachment` を追加する必要があります。これにより、基盤となるインスタンス内のすべての NIC からポッドに ENI がアタッチされます (ポッドと NIC 間の 1 対多マッピング)。

この注釈がない場合、VPC CNI はポッドに必要なネットワークインターフェイスが 1 つだけであると見なし、使用可能な任意の NIC の ENI から IP を 1 つ割り当てます。

### **6. この機能ではどのネットワークインターフェイスアダプターがサポートされていますか?**
<a name="pod-muti-nic-faqs-adapters"></a>

IP トラフィックの基盤となるネットワークカードに少なくとも 1 つの ENA がアタッチされている場合は、任意のネットワークインターフェイスアダプターを使用できます。ENA に関する詳細については、「*Amazon EC2 ユーザーガイド*」の「[Elastic Network Adapter (ENA)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking-ena.html)」を参照してください。

サポートされているネットワークデバイス設定:
+  **ENA** インターフェイスはVPC の IP ネットワークをサポートするために必要なすべての従来の IP ネットワークとルーティング機能を提供します。詳細については、「[EC2 インスタンスで ENA による拡張ネットワーキングを有効にする](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/enhanced-networking-ena.html)」を参照してください。
+  **EFA** **(EFA** と **ENA の組み合わせ)** インターフェイスは、IP ネットワーク用の ENA デバイスと、低レイテンシーで高スループット通信用の EFA デバイスの両方を提供します。

**重要**  
ネットワークカードに **EFA 専用**アダプターのみがアタッチされている場合、VPC CNI はマルチホームポッドのネットワーク接続をプロビジョニングするときにそのネットワークカードをスキップします。ただし、**EFA 専用**アダプターをネットワークカード上の **ENA** アダプターと組み合わせると、VPC CNI はこのデバイス上の ENI も管理します。EKS クラスターで EFA 専用インターフェイスを使用するには、「[Elastic Fabric Adapter を使用して Amazon EKS で機械学習トレーニングを実行する](node-efa.md)」を参照してください。

### **7. クラスター内のノードが ENA をサポートしているかどうかを確認できますか?**
<a name="pod-muti-nic-faqs-node-ena"></a>

はい。AWS CLI または EC2 API を使用して、クラスター内の EC2 インスタンスに関するネットワーク情報を取得できます。これにより、インスタンスに ENA サポートがあるかどうかの詳細が表示されます。次の例で、`<your-instance-id>` をノードの EC2 インスタンス ID に置き換えます。

 AWS CLI の例:

```
aws ec2 describe-instances --instance-ids <your-instance-id> --query "Reservations[].Instances[].EnaSupport"
```

出力例:

```
[ true ]
```

### **8. ポッドに関連付けられているさまざまな IP アドレスを確認できますか?**
<a name="pod-muti-nic-faqs-list-ips"></a>

いいえ、簡単にはできません。ただし、ノードから `nsenter` を使用して、`ip route show` のような一般的なネットワークツールを実行すれば、追加の IP アドレスとインターフェイスを確認できます。

### **9. ポッドのネットワークインターフェイスの数を制御できますか?**
<a name="pod-muti-nic-faqs-number-of-enis"></a>

いいえ。ワークロードがサポートされているインスタンスで複数の NIC を使用するように設定されている場合、単一のポッドにはインスタンス上のすべてのネットワークカードから IP アドレスが自動的に割り当てられます。または、シングルホームポッドには、インスタンス上の 1 つの NIC に 1 つのネットワークインターフェイスがアタッチされます。

**重要**  
**EFA 専用**デバイス*のみ*がアタッチされているネットワークカードは、VPC CNI によってスキップされます。

### **10. 特定の NIC を使用するようにポッドを設定できますか?**
<a name="pod-muti-nic-faqs-specify-nic"></a>

いいえ、それはサポートされません。ポッドに関連する注釈がある場合、VPC CNI はワーカーノード上の ENA アダプターですべての NIC を使用するように自動的に設定します。

### **11. この機能は、他の VPC CNI ネットワーク機能と連携しますか?**
<a name="pod-muti-nic-faqs-modes"></a>

はい。VPC CNI のマルチ NIC 機能は、*カスタムネットワーク*と*拡張サブネット検出*の両方と連携します。ただし、マルチホームポッドではカスタムサブネットやセキュリティグループを使用しません。代わりに、VPC CNI はノードと同じサブネットとセキュリティグループ設定を使用して、マルチホームポッドに IP アドレスとネットワークインターフェイスを割り当てます。カスタムネットワークの詳細については、「[カスタムネットワーキングを使用して代替サブネットに Pod をデプロイする](cni-custom-network.md)」を参照してください。

VPC CNI のマルチ NIC 機能は*ポッドのセキュリティグループ*と組み合わせて動作することはできません。

### **12. この機能でネットワークポリシーを使用できますか?**
<a name="pod-muti-nic-faqs-netpol"></a>

はい。マルチ NIC で Kubernetes ネットワークポリシーを使用できます。Kubernetes ネットワークポリシーにより、Pod 間で送受信されるネットワークトラフィックが制限されます。VPC CNI でネットワークポリシーを適用する詳細については、「[Kubernetes ネットワークポリシーにより Pod トラフィックを制限する](cni-network-policy.md)」を参照してください。

### **13. マルチ NIC サポートは EKS オートモードで有効になっていますか?**
<a name="pod-muti-nic-faqs-auto-mode"></a>

マルチ NIC は EKS オートモードクラスターではサポートされていません。