pods のセキュリティグループ - Amazon EKS

pods のセキュリティグループ

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

考慮事項

pods のセキュリティグループをデプロイする前に、次の制限と条件を考慮してください。

  • Amazon EC2 ノードで実行する Pods は、任意の Amazon EKS がサポートする Kubernetes バージョンに配置できますが、Fargate で実行する pods は、1.18 以降のクラスターに配置する必要があります。

  • pods のセキュリティグループは、Windows ノードでは使用できません。

  • pods のセキュリティグループは、IPv6 ファミリー用に設定され、Amazon EC2 ノードを含むクラスターでは使用できません。ただし、IPv6 ファミリー用に設定され、Fargate ノードのみを含むクラスターでは、pods のセキュリティグループの使用が可能です。詳細については、「IPv6 アドレスの pods および services への割り当て」を参照してください。

  • pods のセキュリティグループは、m5c5r5p3m6gc6g、および r6g インスタンスファミリーを含む、ほとんどの Nitro ベースの Amazon EC2 インスタンスファミリーでサポートされています。t3 インスタンスファミリーはサポートされていません。サポートされているインスタンスの詳細なリストについては、GitHub で「limits.go」ファイルを参照してください。ノードは、そのファイルで一覧表示されているインスタンスタイプのうち、IsTrunkingCompatible: true を含むものである必要があります。

  • pod のセキュリティポリシーを使用して pod 変更へのアクセスを制限している場合は、eks-vpc-resource-controller および vpc-resource-controller Kubernetes サービスアカウントは、psp が割り当てられた role に対して Kubernetes ClusterRoleBinding で指定する必要があります。デフォルトの Amazon EKS の psp、role、および ClusterRoleBinding を使用している場合、これは eks:podsecuritypolicy:authenticated ClusterRoleBinding です。例えば、次の例に示すように、サービスアカウントをセクション subjects: に追加します。

    ... subjects: - kind: Group apiGroup: rbac.authorization.k8s.io name: system:authenticated - kind: ServiceAccount name: vpc-resource-controller - kind: ServiceAccount name: eks-vpc-resource-controller
  • カスタムネットワークと pods のセキュリティグループを組み合わせて使用している場合、ENIconfig で指定されたセキュリティグループではなく、pods のセキュリティグループによって指定されたセキュリティグループが使用されます。

  • Amazon VPC CNI プラグインのバージョン 1.10.2 以前を使用していて、pod 仕様に terminationGracePeriodSeconds 設定を含める場合は、設定の値を「0」にすることはできません。

  • Amazon VPC CNI プラグインのバージョン 1.10 以前、またはデフォルト設定が 1.11=POD_SECURITY_GROUP_ENFORCING_MODE のバージョン strict を使用している場合、externalTrafficPolicyLocal に設定されたインスタンスターゲットを使用するタイプ NodePort および LoadBalancer の Kubernetes サービスは、セキュリティグループを割り当てた pods ではサポートされていません。インスタンスターゲットでのロードバランサーの使用の詳細については、「Amazon EKS でのネットワーク負荷分散」を参照してください。POD_SECURITY_GROUP_ENFORCING_MODE=standard に設定されたプラグインのバージョン 1.11 以降を使用している場合、externalTrafficPolicyLocal に設定されたインスタンスターゲットがサポートされます。

  • Amazon VPC CNI プラグインのバージョン 1.10 以降、またはデフォルト設定が POD_SECURITY_GROUP_ENFORCING_MODE=strict のバージョン 1.11 を使用している場合、セキュリティグループが割り当てられた pods からのアウトバウンドトラフィックに対してソース NAT が無効になり、その結果アウトバウンドセキュリティグループルールが適用されます。インターネットにアクセスするには、セキュリティグループが割り当てられた pods を、NAT ゲートウェイまたはインスタンスで構成されたプライベートサブネットにデプロイされたノードで起動する必要があります。パブリックサブネットにデプロイされたセキュリティグループが割り当てられた Pods は、インターネットにアクセスできません。

    POD_SECURITY_GROUP_ENFORCING_MODE=standard に設定されたプラグインのバージョン 1.11 以降を使用している場合、VPC の外部を送信先とする pod トラフィックは、インスタンスのプライマリネットワークインターフェイスの IP アドレスに変換されます。このトラフィックには、pod's のセキュリティグループ内のルールではなく、プライマリネットワークインターフェイスのセキュリティグループ内のルールが適用されます。

  • セキュリティグループが関連付けられている pods で Calico ネットワークポリシーを使用するには、Amazon VPC CNI プラグインのバージョン 1.11.0 以降を使用し、かつ POD_SECURITY_GROUP_ENFORCING_MODE=standard に設定することが必要になります。それ以外の場合、関連付けられたセキュリティグループを持つ pods との間のトラフィックフローに、Calico ネットワークポリシー は適用されず、Amazon EC2 セキュリティグループの適用のみに限定されます。Amazon VPC CNI バージョンを更新するには、「Amazon VPC CNI plugin for Kubernetes の管理」を参照してください。

  • Nodelocal DNSCache を使用するクラスターのセキュリティグループを使用する Amazon EC2 ノードで実行されている Pods は、Amazon VPC CNI プラグインのバージョンが 1.11.0 以降で POD_SECURITY_GROUP_ENFORCING_MODE=standard に設定されている場合にのみサポートされます。Amazon VPC CNI プラグインのバージョンを更新するには、「Amazon VPC CNI plugin for Kubernetes の管理」を参照してください。

pods のセキュリティグループ用の Amazon VPC CNI アドオンの設定

pods のセキュリティグループをデプロイするには

Fargate pods のセキュリティグループのみを使用し、クラスターに Amazon EC2 ノードがない場合は、サンプルアプリケーションをデプロイする に進みます。

  1. 次のコマンドを使用して、現在の CNI プラグインのバージョンをチェックします。

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

    出力例を次に示します。

    amazon-k8s-cni-init:1.7.5-eksbuild.1 amazon-k8s-cni:1.7.5-eksbuild.1

    CNI プラグインのバージョンが 1.7.7 より前の場合は、CNI プラグインをバージョン 1.7.7 以降に更新してください。詳細については、「Amazon VPC CNI plugin for Kubernetes アドオンの更新」を参照してください。

  2. AmazonEKSVPCResourceController マネージドポリシーを Amazon EKS クラスターに関連付けられているクラスターのロールに追加します。ポリシーにより、ロールはネットワークインターフェイス、プライベート IP アドレス、およびネットワークインスタンスへのアタッチとデタッチを管理できます。

    1. クラスター IAM ロールの ARN を決定します。my-cluster を自分のクラスター名に置き換えます。

      aws eks describe-cluster --name my-cluster --query cluster.roleArn --output text

      出力例を次に示します。

      arn:aws:iam::111122223333:role/eksClusterRole
    2. 次のコマンドでは、eksClusterRole という名前のクラスターロールにこのポリシーが追加されます。eksClusterRole をロールの名前で置き換えます。

      aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKSVPCResourceController \ --role-name eksClusterRole
  3. Amazon VPC CNI アドオンを有効にして pods のネットワークインターフェイスを管理するには、aws-node DaemonSetENABLE_POD_ENI 変数を true に設定します。この設定が true になると、クラスター内の各ノードについて、アドオンで値が vpc.amazonaws.com/has-trunk-attached=true のラベルが追加されます。VPC リソースコントローラーは、1 つの特別なネットワークインターフェイスを作成してアタッチします。これは、トランクネットワークインターフェイスと呼ばれ、説明は aws-k8s-trunk-eni です。

    kubectl set env daemonset aws-node -n kube-system ENABLE_POD_ENI=true
    注記

    トランクネットワークインターフェイスは、インスタンスタイプでサポートされているネットワークインターフェイスの最大数に含まれます。各インスタンスタイプによりサポートされるネットワークインターフェイスの最大数のリストについては、「Amazon EC2 Linux インスタンス用ユーザーガイド」の「各インスタンスタイプのネットワークインターフェイスあたりの IP アドレス数」を参照してください。ノードにすでに最大数の標準ネットワークインターフェイスがアタッチされている場合、VPC リソースコントローラーはスペースを予約します。コントローラーが標準ネットワークインターフェイスをデタッチして削除し、トランクネットワークインターフェイスを作成し、インスタンスにアタッチできるように、実行中の pods をスケールダウンする必要があります。

    true に設定されている aws-k8s-trunk-eni がどのノードにあるか、次のコマンドで確認できます。[No resources found] が返された場合、数秒待ってから、もう一度試してください。前のステップで、CNI pods を再起動する必要があります。再起動には数秒かかります。

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

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

    後のステップで pod のセキュリティグループをデプロイすると、VPC リソースコントローラーは、ブランチネットワークインターフェイスと呼ばれる特別なネットワークインターフェイスを aws-k8s-branch-eni の説明とともに作成し、セキュリティグループを関連付けます。ノードにアタッチされた標準ネットワークインターフェイスとトランクネットワークインターフェイスに加えて、ブランチネットワークインターフェイスが作成されます。Liveness プローブまたは Readiness プローブを使用している場合は、TCP Early Demux も無効にする必要があります。これにより、kubelet は TCP を使用してブランチネットワークインターフェイス上の pods に接続できます。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 に設定している場合、次のステップで説明されているように、前のコマンドを実行する必要はありません。

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

    kubectl set env daemonset aws-node -n kube-system POD_SECURITY_GROUP_ENFORCING_MODE=standard
    重要
    • Pod セキュリティグループルールは、kubeletnodeLocalDNS など、同じノードにある pods 間のトラフィックまたは pods と services 間のトラフィックには適用されません。

    • pods から VPC の外部のアドレスへのアウトバウンドトラフィックは、インスタンスのプライマリネットワークインターフェイスの IP アドレスに変換されたネットワークアドレスです (AWS_VPC_K8S_CNI_EXTERNALSNAT=true に設定していない場合)。このトラフィックには、pod's のセキュリティグループ内のルールではなく、プライマリネットワークインターフェイスのセキュリティグループ内のルールが適用されます。

    • この設定を既存の pods に適用するには、pods または pods が実行されているノードを再起動する必要があります。

  5. リソースをデプロイする 名前空間を作成します。

    kubectl create namespace my-namespace
  6. Amazon EKS SecurityGroupPolicy をクラスターにデプロイします。

    1. 次のセキュリティポリシーの例を、my-security-group-policy.yaml という名前のファイルに保存します。podSelectorserviceAccountSelector で置き換えると、サービスアカウントのラベルに基づいて pods を選択することができます。セレクターをどちらか 1 つ指定する必要があります。podSelector が空 (例: podSelector: {}) であると、名前空間内のすべての pods が選択されます。serviceAccountSelector が空であると、名前空間内のすべてのサービスアカウントが選択されます。groupIds には、1~5 個のセキュリティグループ ID を指定する必要があります。複数の ID を指定した場合、すべてのセキュリティグループ内のすべてのルールの組み合わせが、選択した pods に対して有効になります。

      apiVersion: vpcresources.k8s.aws/v1beta1 kind: SecurityGroupPolicy metadata: name: my-security-group-policy namespace: my-namespace spec: podSelector: matchLabels: role: my-role securityGroups: groupIds: - sg-abc123
      重要
      • ポリシーで指定するセキュリティグループが存在している必要があります。セキュリティグループが存在しない場合、セレクターに一致する pod をデプロイすると、pod は作成プロセスでスタックしたままになります。pod を記述すると、An error occurred (InvalidSecurityGroupID.NotFound) when calling the CreateNetworkInterface operation: The securityGroup ID 'sg-abc123' does not exist のようなエラーメッセージが表示されます。

      • セキュリティグループは、プローブを設定した任意のポート経由のクラスターセキュリティグループ (kubelet の場合) からのインバウンド通信を許可する必要があります。

      • セキュリティグループは、TCP および UDP 53 番ポート経由のインバウンドで許可されているセキュリティグループ (CoreDNS podsの場合) へのアウトバウンド通信を許可する必要があります。

      • Fargate でセキュリティグループポリシーを使用している場合は、セキュリティグループに pods と Kubernetes コントロールプレーンとの通信を許可するルールを含めていることを必ず確認してください。最も簡単な方法は、クラスターセキュリティグループをセキュリティグループの 1 つとして指定することです。

      • セキュリティグループポリシーは、新しくスケジュールされた pods にのみ適用されます。実行中の pods には影響しません。

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

      kubectl apply -f my-security-group-policy.yaml
  7. 前のステップで指定した podselectormy-role の値に一致するラベルを持つサンプルアプリケーションをデプロイします。

    1. 次の内容をファイルに保存します。

      apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment namespace: my-namespace labels: app: my-app spec: replicas: 1 selector: matchLabels: app: my-app template: metadata: labels: app: my-app role: my-role spec: containers: - name: my-container image: my-image ports: - containerPort: 80
    2. 次のコマンドを使用して、アプリケーションをデプロイします。アプリケーションをデプロイすると、Amazon VPC CNI plugin for Kubernetes は role ラベルと一致し、前のステップで指定したセキュリティグループが pod に適用されます。

      kubectl apply -f my-security-group-policy.yaml
      注記
      • pod が Waiting 状態にスタックし、pod の記述時に Insufficient permissions: Unable to create Elastic Network Interface. が表示された場合、前のステップで IAM クラスターロールに IAM ポリシーを追加したことを確認します。

      • pod が Pending 状態にスタックした場合、ノードのインスタンスタイプに Github の limits.goIsTrunkingCompatible: true が含まれていることと、インスタンスタイプでサポートされるブランチネットワークインターフェイスの最大数とノードグループ内のノード数を乗算した数にまだ達していないことを確認します。例えば、m5.large インスタンスでは、9 つのブランチネットワークインターフェイスがサポートされています。ノードグループに 5 つのノードがある場合、ノードグループに対して最大 45 のブランチネットワークインターフェイスを作成できます。46 個目の pod をデプロイしようとすると、セキュリティグループに関連付けられた別の pod が削除されるまで Pending 状態のままになります。

      kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace を実行したときに次のようなメッセージが表示されている場合は、無視しても問題ありません。このメッセージは、CNI プラグインがホストネットワークの設定を試み、ネットワークインターフェイスの作成中に失敗したときに表示される場合があります。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-59f5f68b58-c89wx": networkPlugin cni failed to set up pod "my-deployment-59f5f68b58-c89wx_my-namespace" network: add cmd: failed to assign an IP address to container

      インスタンスタイプで実行できる pods の最大数を超えることはできません。各インスタンスタイプで実行できる pods の最大数の一覧については、GitHub の「eni-max-pods.txt」を参照してください。セキュリティグループが関連付けられている pod を削除するか、pod が実行されているノードを削除すると、VPC リソースコントローラーによってブランチネットワークインターフェイスが削除されます。セキュリティグループ用 pods を使用して pods を含むクラスターを削除した場合、コントローラーがブランチネットワークインターフェイスを削除しないため、自分で削除する必要があります。

サンプルアプリケーションをデプロイする

pods にセキュリティグループを使用するには、既存のセキュリティグループがあり、かつ次の手順で説明するように、クラスターに Amazon EKS SecurityGroupPolicy をデプロイする必要があります。次のステップは、pod に対してセキュリティグループポリシーを使用する方法を示しています。次のステップではターミナル間で保持されない変数が使用されるため、特に明記されていない限り、同じターミナルからすべてのステップを完了してください。

セキュリティグループでサンプル pod をデプロイするには

  1. pod で使用するセキュリティグループを作成します。次の手順は、例示のみを目的としたシンプルなセキュリティグループを作成するのに役立ちます。実稼働クラスターでは、ルールが異なる可能性があります。

    1. クラスターの VPC およびクラスターセキュリティグループの ID を取得します。my-cluster を自分のクラスター名に置き換えます。

      my_cluster_name=my-cluster my_cluster_vpc_id=$(aws eks describe-cluster \ --name $my_cluster_name \ --query cluster.resourcesVpcConfig.vpcId \ --output text) my_cluster_security_group_id=$(aws eks describe-cluster \ --name $my_cluster_name \ --query cluster.resourcesVpcConfig.clusterSecurityGroupId \ --output text)
    2. pod のセキュリティグループを作成します。my-pod-security-group をユーザー自身の値に置き換えます。コマンドの実行後に出力で返されるセキュリティグループの ID を書き留めます。これは、後のステップで使用します。

      my_pod_security_group_name=my-pod-security-group aws ec2 create-security-group \ --vpc-id $my_cluster_vpc_id \ --group-name $my_pod_security_group_name \ --description "My pod security group" my_pod_security_group_id=$(aws ec2 describe-security-groups \ --filters Name=group-name,Values=$my_pod_security_group_name \ --query 'SecurityGroups[].GroupId' \ --output text) echo $my_pod_security_group_id
    3. 前のステップで作成した pod セキュリティグループからクラスターセキュリティグループへの、TCP および UDP 53 番ポート経由のトラフィックを許可します。クラスターセキュリティグループとは別のセキュリティグループへの pod からの DNS トラフィックの流入が必要な場合、$my_cluster_security_group_id をユーザー自身のセキュリティグループ ID で置き換えます。各コマンドに対して返される出力のうち、SecurityGroupRuleId に対して返された値を書き留めます。これらは、後のステップで使用します。

      aws ec2 authorize-security-group-ingress \ --group-id $my_cluster_security_group_id \ --protocol tcp --port 53 --source-group $my_pod_security_group_id aws ec2 authorize-security-group-ingress \ --group-id $my_cluster_security_group_id \ --protocol udp --port 53 --source-group $my_pod_security_group_id
    4. セキュリティグループが任意のプロトコルおよびポートを経由して関連付けられる任意の pod から pod セキュリティグループへの、インバウンドトラフィックを許可します。セキュリティグループには、セキュリティグループが任意のプロトコルおよびポートを経由して任意の送信先に関連付けられている pods からのアウトバウンドトラフィックを許可する、デフォルトのアウトバウンドルールが含められています。

      aws ec2 authorize-security-group-ingress \ --group-id $my_pod_security_group_id \ --protocol -1 --port -1 --source-group $my_pod_security_group_id
  2. リソースをデプロイする Kubernetes 名前空間を作成します。

    kubectl create namespace my-namespace
  3. Amazon EKS SecurityGroupPolicy をクラスターにデプロイします。

    1. 次のセキュリティポリシーの例を、my-security-group-policy.yaml という名前のファイルに保存します。podSelectorserviceAccountSelector で置き換えると、サービスアカウントのラベルに基づいて pods を選択することができます。セレクターをどちらか 1 つ指定する必要があります。podSelector が空 (例: podSelector: {}) であると、名前空間内のすべての pods が選択されます。serviceAccountSelector が空であると、名前空間内のすべてのサービスアカウントが選択されます。groupIds には、1~5 個のセキュリティグループ ID を指定する必要があります。複数の ID を指定した場合、すべてのセキュリティグループ内のすべてのルールの組み合わせが、選択した pods に対して有効になります。sg-05b1d815d1EXAMPLE を、前のステップで pod のセキュリティグループを作成したときにメモしたセキュリティグループの ID で置き換えます。

      apiVersion: vpcresources.k8s.aws/v1beta1 kind: SecurityGroupPolicy metadata: name: my-security-group-policy namespace: my-namespace spec: podSelector: matchLabels: role: my-role securityGroups: groupIds: - sg-05b1d815d1EXAMPLE
      重要

      pod に対して指定した 1 つまたは複数のセキュリティグループは、次の基準を満たす必要があります。

      • 存在している必要があります。セキュリティグループが存在しない場合、セレクターに一致する pod をデプロイすると、pod は作成プロセスでスタックしたままになります。pod を記述すると、An error occurred (InvalidSecurityGroupID.NotFound) when calling the CreateNetworkInterface operation: The securityGroup ID 'sg-05b1d815d1EXAMPLE' does not exist のようなエラーメッセージが表示されます。

      • セキュリティグループは、プローブを設定した任意のポート経由のクラスターセキュリティグループ (kubelet の場合) からのインバウンド通信を許可する必要があります。

      • セキュリティグループは、CoreDNS を実行している pods に割り当てられたセキュリティグループへの、TCP および UDP 53 番ポート経由のアウトバウンド通信を許可する必要があります。CoreDNS pods のセキュリティグループは、セキュリティグループからの TCP および UDP 53 番ポート経由のインバウンドトラフィックを許可する必要があります。

      • セキュリティグループには、通信を行う必要がある他の pods との通信に必要なインバウンドルールとアウトバウンドルールを含める必要があります。

      • Fargate でセキュリティグループを使用している場合は、セキュリティグループに、pods と Kubernetes コントロールプレーンとの通信を許可するルールを含める必要があります。最も簡単な方法は、クラスターセキュリティグループをセキュリティグループの 1 つとして指定することです。

      セキュリティグループポリシーは、新しくスケジュールされた pods にのみ適用されます。実行中の pods には影響しません。

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

      kubectl apply -f my-security-group-policy.yaml
  4. 前のステップで指定した podSelectormy-role の値に一致するラベルを持つサンプルアプリケーションをデプロイします。

    1. 次の内容を sample-application.yaml という名前のファイルに保存します。

      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.21 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
    2. 次のコマンドを使用して、アプリケーションをデプロイします。アプリケーションをデプロイすると、Amazon VPC CNI plugin for Kubernetes は role ラベルと一致し、前のステップで指定したセキュリティグループが pod に適用されます。

      kubectl apply -f sample-application.yaml
      注記
      • pod が Waiting 状態にスタックし、pod の記述時に Insufficient permissions: Unable to create Elastic Network Interface. が表示された場合、前のステップで IAM クラスターロールに IAM ポリシーを追加したことを確認します。

      • pod が Pending 状態にスタックした場合、ノードのインスタンスタイプが limits.go のリストに含まれていることと、インスタンスタイプでサポートされるブランチネットワークインターフェイスの最大数とノードグループ内のノード数を乗算した数にまだ達していないことを確認します。例えば、m5.large インスタンスでは、9 つのブランチネットワークインターフェイスがサポートされています。ノードグループに 5 つのノードがある場合、ノードグループに対して最大 45 のブランチネットワークインターフェイスを作成できます。46 個目の pod をデプロイしようとすると、セキュリティグループに関連付けられた別の pod が削除されるまで Pending 状態のままになります。

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

      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

      インスタンスタイプで実行できる pods の最大数を超えることはできません。各インスタンスタイプで実行できる pods の最大数の一覧については、GitHub の「eni-max-pods.txt」を参照してください。セキュリティグループが関連付けられている pod を削除するか、pod が実行されているノードを削除すると、VPC リソースコントローラーによってブランチネットワークインターフェイスが削除されます。セキュリティグループ用 pods を使用して pods を含むクラスターを削除した場合、コントローラーがブランチネットワークインターフェイスを削除しないため、自分で削除する必要があります。

  5. サンプルアプリケーションでデプロイされた pods を表示します。このトピックの以降の説明では、このターミナルを 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>
  6. 別のターミナルから pods のいずれかをシェルで操作します。このトピックの以降の説明では、このターミナルを TerminalB と呼びます。5df6f7687b-4fbjm を、前のステップの出力で返されたいずれかの pods の ID で置き換えます。

    kubectl exec -it -n my-namespace my-deployment-5df6f7687b-4fbjm -- /bin/bash
  7. TerminalB のシェルから、サンプルアプリケーションが動作することを確認します。

    curl my-app

    出力例を次に示します。

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

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

  8. TerminalA で、クラスターセキュリティグループへの DNS 通信を許可するセキュリティグループルールを、セキュリティグループから削除します。前のステップで DNS ルールをクラスターセキュリティグループに追加しなかった場合は、$my_cluster_security_group_id をルールを作成したセキュリティグループの ID で置き換えます。sgr-0407e21efdEXAMPLE および sgr-04dedf9701EXAMPLE を、前のステップでメモしたセキュリティグループルールの ID で置き換えます。

    aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids sgr-0407e21efdEXAMPLE aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids sgr-04dedf9701EXAMPLE
  9. TerminalB で、アプリケーションにもう一度アクセスしてみます。

    curl my-app

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

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

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

    kubectl delete namespace my-namespace aws ec2 delete-security-group --group-id $my_pod_security_group_id