

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# ポッドあたりのセキュリティグループ
<a name="sgpp"></a>

**ヒント**  
 Amazon EKS [https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el)ワークショップを通じてベストプラクティスをご覧ください。

AWS セキュリティグループは、EC2 インスタンスの仮想ファイアウォールとして機能し、インバウンドトラフィックとアウトバウンドトラフィックを制御します。デフォルトでは、Amazon VPC CNI はノード上のプライマリ ENI に関連付けられたセキュリティグループを使用します。具体的には、インスタンスに関連付けられているすべての ENI に同じ EC2 セキュリティグループがあります。したがって、ノード上のすべての Pod は、実行されるノードと同じセキュリティグループを共有します。

次の図に示すように、ワーカーノードで動作しているすべてのアプリケーションポッドは RDS データベースサービスにアクセスできます (RDS インバウンドではノードセキュリティグループが許可されます）。セキュリティグループは、ノードで実行されているすべての Pod に適用されるため、粗すぎます。Pod のセキュリティグループは、ワークロードのネットワークセグメンテーションを提供します。これは、多層防御戦略にとって不可欠な部分です。

![RDS に接続するセキュリティグループを持つノードの図](http://docs.aws.amazon.com/ja_jp/eks/latest/best-practices/images/networking/sgpp_image.png)


Pod のセキュリティグループを使用すると、共有コンピューティングリソースでさまざまなネットワークセキュリティ要件を持つアプリケーションを実行することで、コンピューティング効率を向上させることができます。Pod-to-Pod や Pod-to-External AWS サービスなど、複数のタイプのセキュリティルールを EC2 セキュリティグループで 1 か所で定義し、Kubernetes ネイティブ APIs を使用するワークロードに適用できます。以下の図は、Pod レベルで適用されるセキュリティグループと、アプリケーションのデプロイとノードアーキテクチャを簡素化する方法を示しています。Pod が Amazon RDS データベースにアクセスできるようになりました。

![RDS に接続するさまざまなセキュリティグループを持つポッドとノードの図](http://docs.aws.amazon.com/ja_jp/eks/latest/best-practices/images/networking/sgpp_image-2.png)


`ENABLE_POD_ENI=true` VPC CNI の を設定することで、Pod のセキュリティグループを有効にできます。有効にすると、コントロールプレーン (EKS によって管理) で実行されている [VPC リソースコントローラー](https://github.com/aws/amazon-vpc-resource-controller-k8s)は、「aws-k8s-trunk-eni」というトランクインターフェイスを作成してノードにアタッチします。トランクインターフェイスは、インスタンスにアタッチされた標準ネットワークインターフェイスとして機能します。トランクインターフェイスを管理するには、Amazon EKS クラスターと連携するクラスターロールに `AmazonEKSVPCResourceController`管理ポリシーを追加する必要があります。

また、コントローラーは「aws-k8s-branch-eni」という名前のブランチインターフェイスを作成し、トランクインターフェイスに関連付けます。ポッドには [SecurityGroupPolicy](https://github.com/aws/amazon-vpc-resource-controller-k8s/blob/master/config/crd/bases/vpcresources.k8s.aws_securitygrouppolicies.yaml) カスタムリソースを使用してセキュリティグループが割り当てられ、ブランチインターフェイスに関連付けられます。セキュリティグループはネットワークインターフェイスで指定されているため、これらの追加のネットワークインターフェイスで特定のセキュリティグループを必要とするポッドをスケジュールできるようになりました。デプロイの前提条件を含め[、ポッドのセキュリティグループに関する EKS ユーザーガイドセクション](https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html)を確認してください。

![ENIs に関連付けられたセキュリティグループを持つワーカーサブネットの図](http://docs.aws.amazon.com/ja_jp/eks/latest/best-practices/images/networking/sgpp_image-3.png)


ブランチインターフェイス容量は、セカンダリ IP アドレスの既存のインスタンスタイプの制限*に追加されます*。セキュリティグループを使用するポッドは、max-pods 式では考慮されません。ポッドにセキュリティグループを使用する場合は、max-pods 値を増やすことを検討するか、ノードが実際にサポートできる数よりも少ないポッドを実行することで問題ありません。

m5.large には、最大 9 つのブランチネットワークインターフェイスと最大 27 のセカンダリ IP アドレスを標準ネットワークインターフェイスに割り当てることができます。以下の例に示すように、m5.large のデフォルトの最大ポッドは 29 で、EKS はセキュリティグループを使用するポッドを最大ポッドにカウントします。ノードの最大ポッドを変更する方法については、[EKS ユーザーガイド](https://docs.aws.amazon.com/eks/latest/userguide/cni-increase-ip-addresses.html)を参照してください。

ポッドのセキュリティグループを[カスタムネットワーキング](https://docs.aws.amazon.com/eks/latest/userguide/cni-custom-network.html)と組み合わせて使用する場合、ポッドのセキュリティグループで定義されたセキュリティグループはENIConfig で指定されたセキュリティグループではなく使用されます。その結果、カスタムネットワーキングが有効になっている場合は、Pod ごとにセキュリティグループを使用しながら、セキュリティグループの順序を慎重に評価します。

## 推奨事項
<a name="_recommendations"></a>

### Liveness Probe の TCP Early Demux を無効にする
<a name="_disable_tcp_early_demux_for_liveness_probe"></a>

ライブネスプローブまたは準備状況プローブを使用している場合は、kubelet が TCP 経由でブランチネットワークインターフェイス上の Pod に接続できるように、TCP 早期デマックスを無効にする必要もあります。これは strict モードでのみ必要です。これを行うには、次のコマンドを実行します。

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

`initContainer` セクションで、 の値を `DISABLE_TCP_EARLY_DEMUX` に変更します。 `true.`

### Security Group For Pods を使用して、既存の AWS 設定投資を活用します。
<a name="_use_security_group_for_pods_to_leverage_existing_aws_configuration_investment"></a>

セキュリティグループを使用すると、RDS データベースや EC2 インスタンスなどの VPC リソースへのネットワークアクセスを簡単に制限できます。Pod あたりのセキュリティグループの明らかな利点の 1 つは、既存の AWS セキュリティグループリソースを再利用できることです。セキュリティグループをネットワークファイアウォールとして使用して AWS サービスへのアクセスを制限する場合は、ブランチ ENIs を使用してセキュリティグループを Pod に適用することをお勧めします。EC2 インスタンスから EKS にアプリケーションを転送し、セキュリティグループを使用して他の AWS サービスへのアクセスを制限する場合は、Pod のセキュリティグループの使用を検討してください。

### ポッドセキュリティグループの強制モードを設定する
<a name="_configure_pod_security_group_enforcing_mode"></a>

Amazon VPC CNI プラグインバージョン 1.11 に、 `POD_SECURITY_GROUP_ENFORCING_MODE` (「強制モード」) という名前の新しい設定が追加されました。強制モードは、ポッドに適用するセキュリティグループと、ソース NAT が有効になっているかどうかの両方を制御します。強制モードは strict または standard として指定できます。Strict はデフォルトであり、 を `ENABLE_POD_ENI`に設定した場合の VPC CNI の以前の動作を反映しています`true`。

Strict Mode では、ブランチ ENI セキュリティグループのみが強制されます。ソース NAT も無効になっています。

標準モードでは、プライマリ ENI とブランチ ENI (ポッドに関連付けられている) の両方に関連付けられたセキュリティグループが適用されます。ネットワークトラフィックは、両方のセキュリティグループに準拠する必要があります。

**警告**  
モードの変更は、新しく起動された Pod にのみ影響します。既存のポッドは、ポッドの作成時に設定されたモードを使用します。トラフィック動作を変更する場合は、セキュリティグループを持つ既存の Pod をリサイクルする必要があります。

### 強制モード: ポッドとノードのトラフィックを分離するには、厳密なモードを使用します。
<a name="_enforcing_mode_use_strict_mode_for_isolating_pod_and_node_traffic"></a>

デフォルトでは、Pod のセキュリティグループは「厳格モード」に設定されています。Pod トラフィックをノードの残りのトラフィックから完全に分離する必要がある場合は、この設定を使用します。厳格モードでは、ソース NAT がオフになっているため、ブランチ ENI アウトバウンドセキュリティグループを使用できます。

**警告**  
Strict モードを有効にすると、ポッドからのすべてのアウトバウンドトラフィックがノードを離れ、VPC ネットワークに入ります。同じノード上のポッド間のトラフィックは VPC を経由します。これにより、VPC トラフィックが増加し、ノードベースの機能が制限されます。NodeLocal DNSCache は strict モードではサポートされていません。

### 強制モード: 次の状況で標準モードを使用する
<a name="_enforcing_mode_use_standard_mode_in_the_following_situations"></a>

 **Pod のコンテナに表示されるクライアントソース IP** 

Pod のコンテナにクライアントソース IP を表示したままにする必要がある場合は、 `POD_SECURITY_GROUP_ENFORCING_MODE`を に設定することを検討してください`standard`。Kubernetes サービスは externalTrafficPolicy=local をサポートし、クライアントソース IP (デフォルトタイプクラスター) の保存をサポートします。標準モードで externalTrafficPolicy が Local に設定されているインスタンスターゲットを使用して、NodePort および LoadBalancer タイプの Kubernetes サービスを実行できるようになりました。 はクライアントソース IP `Local`を保持し、LoadBalancer および NodePort タイプのサービスの 2 番目のホップを回避します。

 **NodeLocal DNSCache のデプロイ** 

ポッドにセキュリティグループを使用する場合は、[NodeLocal DNSCache](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) を使用するポッドをサポートするように標準モードを設定します。NodeLocal DNSCache は、クラスターノードで DNS キャッシュエージェントを DaemonSet として実行することで、クラスター DNS のパフォーマンスを向上させます。これにより、DNS QPS 要件が最も高いポッドがローカルキャッシュを持つローカル kube-dns/CoreDNS をクエリできるため、レイテンシーが向上します。

NodeLocal DNSCache は、ノードへのすべてのネットワークトラフィックが VPC に入るため、厳密なモードではサポートされていません。

 **Kubernetes ネットワークポリシーのサポート** 

セキュリティグループが関連付けられている Pod でネットワークポリシーを使用する場合は、標準強制モードを使用することをお勧めします。

ポッドのセキュリティグループを利用して、クラスターに含まれていない AWS のサービスへのネットワークレベルのアクセスを制限することを強くお勧めします。クラスター内のポッド間のネットワークトラフィックを制限するネットワークポリシーを検討してください。これは、多くの場合、東部/西部トラフィックと呼ばれます。

### ポッドごとにセキュリティグループとの非互換性を特定する
<a name="_identify_incompatibilities_with_security_groups_per_pod"></a>

Windows ベースのインスタンスと Nitro 以外のインスタンスは、Pod のセキュリティグループをサポートしていません。Pod でセキュリティグループを利用するには、インスタンスに isTrunkingEnabled というタグを付ける必要があります。Pod が VPC 内外の AWS のサービスに依存していない場合は、セキュリティグループではなくネットワークポリシーを使用して Pod 間のアクセスを管理します。

### ポッドあたりのセキュリティグループを使用して AWS サービスへのトラフィックを効率的に制御する
<a name="_use_security_groups_per_pod_to_efficiently_control_traffic_to_aws_services"></a>

EKS クラスター内で実行されているアプリケーションが RDS データベースなどの VPC 内の別のリソースと通信する必要がある場合は、ポッドSGs を使用することを検討してください。CIDR または DNS 名を指定できるポリシーエンジンはありますが、VPC 内に存在するエンドポイントを持つ AWS サービスと通信するときは最適ではありません。

対照的に、Kubernetes [ネットワークポリシー](https://kubernetes.io/docs/concepts/services-networking/network-policies/)は、クラスター内外の両方の入出力トラフィックを制御するメカニズムを提供します。アプリケーションが他の AWS のサービスへの依存関係を制限している場合は、Kubernetes ネットワークポリシーを検討する必要があります。SGs などの AWS ネイティブセマンティクスではなく、CIDR 範囲に基づいて出力ルールを指定するネットワークポリシーを設定して、AWS サービスへのアクセスを制限できます。Kubernetes ネットワークポリシーを使用して、ポッド間 (多くの場合、東部/西部トラフィック) およびポッドと外部サービス間のネットワークトラフィックを制御できます。Kubernetes ネットワークポリシーは OSI レベル 3 および 4 で実装されます。

Amazon EKS では、[Calico](https://projectcalico.docs.tigera.io/getting-started/kubernetes/managed-public-cloud/eks) や [Cilium](https://docs.cilium.io/en/stable/intro/) などのネットワークポリシーエンジンを使用できます。デフォルトでは、ネットワークポリシーエンジンはインストールされません。のセットアップ方法については、それぞれのインストールガイドを確認してください。ネットワークポリシーの使用方法の詳細については、[「EKS Security best practices](https://docs.aws.amazon.com/eks/latest/best-practices/network-security.html#iam-network-policy)」を参照してください。DNS ホスト名機能は、エンタープライズバージョンのネットワークポリシーエンジンで使用できます。これは、Kubernetes サービス/ポッドと AWS の外部で実行されるリソース間のトラフィックを制御するのに役立ちます。また、デフォルトでセキュリティグループをサポートしていない AWS サービスの DNS ホスト名のサポートを検討することもできます。

### AWS Loadbalancer Controller を使用するように単一のセキュリティグループにタグ付けする
<a name="_tag_a_single_security_group_to_use_aws_loadbalancer_controller"></a>

Pod に多くのセキュリティグループが割り当てられている場合、Amazon EKS では[http://kubernetes.io/cluster/$name](http://kubernetes.io/cluster/$name)、共有または所有されている単一のセキュリティグループにタグ付けすることをお勧めします。タグを使用すると、AWS Loadbalancer Controller はセキュリティグループのルールを更新して、トラフィックを Pod にルーティングできます。Pod にセキュリティグループが 1 つだけ指定されている場合、タグの割り当てはオプションです。セキュリティグループで設定されたアクセス許可は付加的であるため、ロードバランサーコントローラーがルールを見つけて調整するには、1 つのセキュリティグループにタグ付けするだけで十分です。また、セキュリティグループで定義されている[デフォルトのクォータ](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-security-groups)に従うのにも役立ちます。

### アウトバウンドトラフィックの NAT を設定する
<a name="_configure_nat_for_outbound_traffic"></a>

ソース NAT は、セキュリティグループが割り当てられた Pod からのアウトバウンドトラフィックに対して無効になります。NAT ゲートウェイまたはインスタンスで設定されたプライベートサブネット上のインターネット起動ワーカーノードへのアクセスを必要とするセキュリティグループを使用するポッドの場合、CNI で[外部 SNAT](https://docs.aws.amazon.com/eks/latest/userguide/external-snat.html) を有効にします。

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

### セキュリティグループを持つポッドをプライベートサブネットにデプロイする
<a name="_deploy_pods_with_security_groups_to_private_subnets"></a>

セキュリティグループが割り当てられたポッドは、プライベートサブネットにデプロイされているノードで実行する必要があります。パブリックサブネットにデプロイされたセキュリティグループが割り当てられたポッドは、インターネットにアクセスできないことに注意してください。

### ポッド仕様ファイルで *terminationGracePeriodSeconds* を検証する
<a name="_verify_terminationgraceperiodseconds_in_pod_specification_file"></a>

Pod 仕様ファイルで `terminationGracePeriodSeconds`がゼロ以外であることを確認します (デフォルトは 30 秒）。これは、Amazon VPC CNI がワーカーノードから Pod ネットワークを削除するために不可欠です。ゼロに設定すると、CNI プラグインはホストから Pod ネットワークを削除せず、ブランチ ENI は効果的にクリーンアップされません。

### Fargate でのポッドのセキュリティグループの使用
<a name="_using_security_groups_for_pods_with_fargate"></a>

Fargate で実行される Pod のセキュリティグループは、EC2 ワーカーノードで実行される Pod と非常によく似ています。たとえば、Fargate Pod に関連付ける SecurityGroupPolicy でセキュリティグループを参照する前に、セキュリティグループを作成する必要があります。デフォルトでは、SecurityGroupPolicy を Fargate Pod に明示的に割り当てない場合、[クラスターセキュリティグループは](https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html)すべての Fargate Pod に割り当てられます。わかりやすくするために、クラスターセキュリティグループを Fagate Pod の SecurityGroupPolicy に追加すると、セキュリティグループに最小限のセキュリティグループルールを追加する必要があります。describe-cluster API を使用してクラスターセキュリティグループを見つけることができます。

```
 aws eks describe-cluster --name CLUSTER_NAME --query 'cluster.resourcesVpcConfig.clusterSecurityGroupId'
```

```
cat >my-fargate-sg-policy.yaml <<EOF
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
  name: my-fargate-sg-policy
  namespace: my-fargate-namespace
spec:
  podSelector:
    matchLabels:
      role: my-fargate-role
  securityGroups:
    groupIds:
      - cluster_security_group_id
      - my_fargate_pod_security_group_id
EOF
```

セキュリティグループの最小ルールを[以下](https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html)に示します。これらのルールにより、Fargate Pod は kube-apiserver、kubelet、CoreDNS などのクラスター内サービスと通信できます。また、Fargate Pod との間のインバウンド接続とアウトバウンド接続を許可するルールを追加する必要があります。これにより、Pod は VPC 内の他の Pod またはリソースと通信できるようになります。さらに、Fargate が Amazon ECR または DockerHub などの他のコンテナレジストリからコンテナイメージをプルするためのルールを含める必要があります。詳細については、AWS 全般のリファレンスの「[AWS IP アドレス範囲](https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html)」を参照してください。

次のコマンドを使用して、Fargate Pod に適用されているセキュリティグループを検索できます。

```
kubectl get pod FARGATE_POD -o jsonpath='{.metadata.annotations.fargate\.amazonaws\.com/pod-sg}{"\n"}'
```

上記のコマンドの eniId を書き留めます。

```
aws ec2 describe-network-interfaces --network-interface-ids ENI_ID --query 'NetworkInterfaces[*].Groups[*]'
```

新しいセキュリティグループを適用するには、既存の Fargate ポッドを削除して再作成する必要があります。たとえば、次のコマンドは example-app のデプロイを開始します。特定のポッドを更新するには、次のコマンドで名前空間とデプロイ名を変更できます。

```
kubectl rollout restart -n example-ns deployment example-pod
```