

 **協助改進此頁面** 

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

若要為本使用者指南貢獻內容，請點選每個頁面右側面板中的**在 GitHub 上編輯此頁面**連結。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 了解 VPC CNI 模式與組態
<a name="pod-networking-use-cases"></a>

適用於 Kubernetes 的 Amazon VPC CNI 外掛程式為 Pod 提供聯網功能。使用下面的資料，了解可用聯網功能的詳細資訊。


| 聯網功能 | 進一步了解 | 
| --- | --- | 
|  設定叢集指派 IPv6 位址到叢集、Pod 與服務  |   [了解叢集、Pod 與服務的 IPv6 位址](cni-ipv6.md)   | 
|  使用 Pod 的 IPv4 來源網路位址轉譯  |   [啟用 Pod 的傳出網際網路存取](external-snat.md)   | 
|  限制傳入與傳出 Pod 的網路流量  |   [使用 Kubernetes 網路政策來限制 Pod 網路流量](cni-network-policy-configure.md)   | 
|  自訂節點中的次要網路介面  |   [使用自訂聯網在替代子網路中部署 Pod](cni-custom-network.md)   | 
|  增加節點的 IP 位址  |   [將更多 IP 位址指派給具有字首的 Amazon EKS 節點](cni-increase-ip-addresses.md)   | 
|  使用適用於 Pod 網路流量的安全群組  |   [將安全群組指派至個別 Pod](security-groups-for-pods.md)   | 
|  使用適用於 Pod 的多個網路介面  |   [連接多個網路介面至 Pod](pod-multiple-network-interfaces.md)   | 

# 了解叢集、Pod 與服務的 IPv6 位址
<a name="cni-ipv6"></a>

 **適用於**：具有 Amazon EC2 執行個體的 Pod 和 Fargate Pod

預設情況下，Kubernetes 會為您的 Pod 和服務指派 `IPv4` 位址。您可以將叢集設定為對 Pod 和服務指派 `IPv6` 位址，而不是指派 `IPv4` 位址。即使 Kubernetes 本身支援，Amazon EKS 也不支援雙重堆疊 Pod 或服務。因此，您無法同時將 `IPv4` 和 `IPv6` 位址指派給 Pod 和服務。

您可以在建立叢集時選擇要用於此叢集的 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 節點**：在 Amazon EC2 節點與 Fargate 節點上，皆可搭配 [將安全群組指派至個別 Pod](security-groups-for-pods.md) 使用 `IPv6`。
+  **不支援 Outpost**：無法在 [使用 AWS Outposts 在內部部署 Amazon EKS](eks-outposts.md) 上使用 `IPv6`。
+  **不支援 FSx for Lustre**：不支援 [搭配 Amazon FSx for Lustre 使用高效能應用程式儲存](fsx-csi.md)。
+  **不支援自訂聯網**：如果您以前使用 [使用自訂聯網在替代子網路中部署 Pod](cni-custom-network.md) 來幫助緩解 IP 位址耗盡情況，則可以改用 `IPv6`。您無法將自訂聯網與 `IPv6` 搭配使用。如果您使用自訂聯絡進行網路隔離，則可能需要繼續為叢集使用自訂聯網和 `IPv4` 系列。

## IP 位址指派
<a name="_ip_address_assignments"></a>
+  **Kubernetes 服務**：Kubernetes 服務只會指派一個 `IPv6` 位址。它們不會被指派 IPv4 位址。
+  **Pod**：Pod 會被指派一個 IPv6 位址和一個主機本機的 IPv4 位址。主機本機 IPv4 位址透過使用與 VPC CNI 鏈結的主機本機 CNI 外掛程式指派，且位址不會報告給 Kubernetes 控制平面。它僅在 Pod 需要與另一個 Amazon VPC 或網際網路中的外部 IPv4 資源通訊時使用。主機本機 IPv4 位址會透過 VPC CNI 進行來源網路位址轉換 (SNAT)，對應到工作節點主要 ENI 的主要 IPv4 位址。
+  **Pod 和服務**：Pod 和服務只會接收 `IPv6` 位址，而非 `IPv4` 位址。當 Pod 需要與外部 `IPv4` 端點通訊時，會使用節點本身的 NAT。此內建的 NAT 功能消除了對 [DNS64 和 NAT64](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html#nat-gateway-nat64-dns64) 的需求。對於需要公有網際網路存取的流量，Pod 的流量是轉換為公有 IP 位址的來源網路位址。
+  **路由位址**：當 Pod 在 VPC 外部通訊時，會保留其原始 `IPv6` 位址 (不會轉譯為節點的 `IPv6` 位址)。此流量會直接透過網際網路閘道或僅限輸出的網際網路閘道進行路由。
+  **節點**：為所有節點指派 `IPv4` 和 `IPv6` 位址。
+  **Fargate Pod**：每個 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 字首委派的詳細資訊，請參閱 [將更多 IP 位址指派給具有字首的 Amazon EKS 節點](cni-increase-ip-addresses.md)。
+  **設定 `IPv4` 和 `IPv6` 位址**：建立叢集時，您指定的 VPC 和子網路必須具有指派給所指定 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 使用者指南中的[遷移至 IPv6](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)。
+  **設定 `IPv6` 的安全群組**：您的安全群組必須允許 `IPv6` 位址。如需詳細資訊，請參閱 Amazon VPC 使用者指南中的[遷移至 IPv6](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html)。
+  **設定負載平衡器**：使用版本 `2.3.1`或更新版本的 AWS Load Balancer控制器，在 IP 模式下使用 [透過 Application Load Balancer 路由應用程式與 HTTP 流量](alb-ingress.md)或 網路流量將 HTTP 應用程式負載平衡[透過 Network Load Balancer 路由 TCP 與 UDP 流量](network-load-balancing.md)至具有任一負載平衡器的 `IPv6` Pod，但不使用執行個體模式。如需詳細資訊，請參閱[使用 AWS Load Balancer控制器路由網際網路流量](aws-load-balancer-controller.md)。
+  **新增 `IPv6` IAM 政策**：您必須將 `IPv6` IAM 政策連接至節點 IAM 或 CNI IAM 角色。在兩者之間，建議您將其連接至 CNI IAM 角色。如需詳細資訊，請參閱[為使用 `IPv6` 系列的叢集建立 IAM 政策](cni-iam-role.md#cni-iam-role-create-ipv6-policy)及[步驟 1：建立 Kubernetes 專用 Amazon VPC CNI 外掛程式 IAM 角色](cni-iam-role.md#cni-iam-role-create-role)。
+  **評估所有元件**：在部署`IPv6`叢集之前，執行與您整合的應用程式、Amazon EKS 附加元件 AWS 和服務的完整評估。這是為了確保使用 `IPv6` 時一切都能正常工作。

# 部署 Amazon EKS `IPv6` 叢集和受管 Amazon Linux 節點
<a name="deploy-ipv6-cluster"></a>

在本教學課程中，您將部署 `IPv6` Amazon VPC、含 `IPv6` 系列的 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)。您只可在建立叢集時啟用某些設定。
+ `kubectl` 命令列工具安裝在您的裝置或 AWS CloudShell 上。版本可以與您的叢集 Kubernetes 版本相同，或是為最多比該版本更舊一版或更新一版的次要版本。例如，如果您的叢集版本為 `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` 文件中的 [Installation](https://eksctl.io/installation) 一節。
+ 裝置或 AWS CloudShell 上安裝和設定的 AWS 命令列界面 (AWS CLI) 版本 `1.27.160` `2.12.3`或更新版本。若要檢查您目前的版本，請使用 `aws --version | cut -d / -f2 | cut -d ' ' -f1`。適用於 macOS 的 `yum`、 `apt-get`或 Homebrew 等套件管理員通常是最新版本 CLI AWS 後面的幾個版本。若要安裝最新版本，請參閱《 * AWS 命令列界面使用者指南*》中的使用 aws 設定[安裝](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) 和快速組態。 [https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)在 AWS CloudShell 中安裝的 AWS CLI 版本也可能是最新版本後面的幾個版本。若要更新它，請參閱《CloudShell [AWS 使用者指南》中的將 CLI 安裝到您的主目錄](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software)。 * AWS CloudShell * 如果您使用 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 支援的版本](https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html)。
   + 將 *my-nodegroup* 取代為您的節點群組名稱。節點群組名稱不可超過 63 個字元。它必須以字母或數字開頭，但剩餘字元也可以包含連字符和底線。
   + 將 *t3.medium* 取代為任何 [AWS Nitro 系統執行個體類型](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
   ```

## 使用 CLI 部署 IPv6 AWS 叢集
<a name="deploy_an_ipv6_cluster_with_shared_aws_cli"></a>

**重要**  
您必須以同一位使用者的身分完成本程序中的所有步驟。若要檢查目前使用者，請執行以下命令：  

  ```
  aws sts get-caller-identity
  ```
必須在同一 shell 中完成此程序中的所有步驟。若干步驟使用前面步驟中設定的變數。如果在其他 shell 中設定變數值，則使用此變數的步驟將無法正常工作。如果您使用 [AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/welcome.html) 完成以下程序，請記住，如果您在大約 20—30 分鐘內沒有使用鍵盤或指標與其互動，則 shell 工作階段將結束。正在執行的進程不算作互動。
這些指示是針對 Bash shell 編寫的，在其他 shell 中可能需要進行調整。

將程序此步驟中的所有範例值取代為您自己的值。

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 個字元。它必須以字母或數字開頭，但剩餘字元也可以包含連字符和底線。使用您的帳戶 ID 取代 *111122223333*。

   ```
   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 叢集。如果發生這種情況，錯誤輸出包含的可用區域可支援新的叢集。使用至少兩個位於帳戶的支援可用區域子網路來建立您的叢集。如需詳細資訊，請參閱[容量不足](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
   ```

   根據預設，已在 `~/.kube` 建立了 `config` 檔案，或者已將新叢集的組態新增至 `~/.kube` 中的現有 `config` 檔案。

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 角色。如需詳細資訊，請參閱[設定 Amazon VPC CNI 外掛程式以使用 IRSA](cni-iam-role.md)。

   1. 將兩個所需的 IAM 受管政策連接到 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 系統執行個體類型](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. 確認在 `IP` 欄中已為預設 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. 確認在 `IP` 欄中已為預設服務指派 `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. 在完成為本教學建立的叢集和節點後，您應該使用如下命令清除所建立的資源。在刪除之前，請確保您沒有使用本教程以外的任何資源。

   1. 如果您在與完成之前步驟不同的 shell 中完成此步驟，請設定之前步驟中使用的所有變數的值，並將範例值取代為在完成之前步驟時指定的值。如果您要在與完成之前步驟相同的 shell 中完成此步驟，請跳至下一步。

      ```
      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>

 **適用於**：包含 Amazon EC2 執行個體的 Linux `IPv4` Fargate 節點、Linux 節點

如果您使用 `IPv6` 系列部署叢集，則本主題中的資訊並不適用於您的叢集，因為 `IPv6` 位址未經過網路轉換。如需搭配使用 `IPv6` 與叢集的詳細資訊，請參閱 [了解叢集、Pod 與服務的 IPv6 位址](cni-ipv6.md)。

預設情況下，叢集中的每個 Pod 均從與部署 Pod 的 VPC 關聯的無類別域間路由 (CIDR) 區塊指派一個[私有](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-private-addresses) `IPv4` 位址。同一 VPC 中的 Pod 使用這些私有 IP 位址作為端點相互通訊。當 Pod 與任何不在與您的 VPC 關聯的 CIDR 區塊內的 `IPv4` 位址通訊時，預設情況下，Amazon VPC CNI 外掛程式 (適用於 [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)) 會將 Pod 的 `IPv4` 位址轉譯為正在執行 Pod 的節點的主要[彈性網路介面](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 SNAT 到執行個體 ENI 的主要 IP 位址。Windows 的此預設組態可確保 Pod 可以使用與主機執行個體相同的方式存取 VPC 外部的網路。

由於此行為：
+ 僅當 Pod 執行的節點獲指派[公有](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-public-addresses)或[彈性](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)時，您的 Pod 才能與網際網路資源進行通訊。公有子網路與具有網際網路閘道路由的[路由表](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 的資源，無法針對輔助彈性網路介面背後的 Pod 啟動通訊。您的 Pod 可以啟動與這些資源的通訊並接收來自資源的回應。

如果在您的環境中下列任一陳述式成立，請使用下列命令變更預設組態。
+ 您在網路或 VPC 擁有資源，且其使用 [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) 連線到叢集，且其需使用 `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 節點。Windows 不支援停用 SNAT。對於從 SNAT 排除 `IPv4` CIDR，您可透過在 Windows 引導指令碼中指定 `ExcludedSnatCIDRs` 參數來進行定義。如需使用此參數的詳細資訊，請參閱 [引導指令碼組態參數](eks-optimized-windows-ami.md#bootstrap-script-configuration-parameters)。

## 主機聯網
<a name="snat-exception"></a>

\$1 如果 Pod 規格包含 `hostNetwork=true` (預設為 `false`)，則其 IP 位址不會被轉譯為其他位址。根據預設，在您叢集上執行的 `kube-proxy` 和 Kubernetes 專用 Amazon VPC CNI 外掛程式 Pod 屬於這種情況。對於這些 Pod，IP 位址與節點的主 IP 位址相同，因此未轉譯 Pod 的 IP 位址。如需有關 Pod `hostNetwork` 設定的詳細資訊，請參閱 Kubernetes API 參考中的 [PodSpec v1 核心](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 之間或您的 Pod 與任何其他網路中的資源之間的連結。您可以使用 Kubernetes *網路政策*來限制往返 Pod 之間的網路流量。如需詳細資訊，請參閱 Kubernetes 文件的[網路政策](https://kubernetes.io/docs/concepts/services-networking/network-policies/)。

## 標準網路政策
<a name="_standard_network_policy"></a>

您可以使用 標準`NetworkPolicy`來分割叢集中的 pod-to-pod 流量。這些網路政策會在 OSI 網路模型的第 3 層和第 4 層運作，可讓您控制 Amazon EKS 叢集內 IP 地址或連接埠層級的流量流程。標準網路政策的範圍是命名空間層級。

### 使用案例
<a name="_use_cases"></a>
+ 分割工作負載之間的網路流量，以確保只有相關的應用程式可以互相通訊。
+ 使用 政策在命名空間層級隔離租用戶，以強制執行網路分離。

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

在下面的政策中，來自*太陽*命名空間中 *Webapp* Pod 的輸出流量受到限制。

```
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`中具有 標籤的 Pod。
+ 允許流量：TCP 連接埠上`moon`命名空間`role: frontend`中具有 標籤的 Pod `8080` 
+ 允許流量：具有標籤角色的 Pod：TCP 連接埠`stars`命名空間中的前端 `8080` 
+ 封鎖流量：來自 Pod `webapp` 的所有其他傳出流量會隱含拒絕

## 管理員 （或叢集） 網路政策
<a name="_admin_or_cluster_network_policy"></a>

![\[EKS 網路政策評估順序的虛構\]](http://docs.aws.amazon.com/zh_tw/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>

下列組態支援適用於 Kubernetes 的 Amazon VPC CNI 外掛程式中的網路政策。
+ 適用於標準和管理網路政策的 Amazon VPC CNI 外掛程式 1.21.0 版 （或更新版本）。
+ 設定為 `IPv4` 或 `IPv6` 地址的叢集。
+ 您可以搭配 [Pod 的安全群組](security-groups-for-pods.md)來使用網路政策。有了網路政策，您就可以控制所有叢集內通訊。使用 Pod 的安全群組，您可以從 Pod 內的應用程式控制對 AWS 服務的存取。
+ 您可以搭配*自訂聯網*和*字首委派*來使用網路政策。

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

 **架構** 
+ 使用 Kubernetes 專用 Amazon VPC CNI 外掛程式將 Kubernetes 專用 Amazon VPC CNI 外掛程式網路政策套用至您的叢集時，您只能將這些政策套用至 Amazon EC2 Linux 節點。您無法將這些政策套用至 Fargate 或 Windows 節點。
+ 網路政策只會套用 `IPv4` 或 `IPv6` 位址，但不能同時套用兩者。在 `IPv4` 叢集中，VPC CNI 會將 `IPv4` 位址指派給 Pod 並套用 `IPv4` 政策。在 `IPv6` 叢集中，VPC CNI 會將 `IPv6` 位址指派給 Pod 並套用 `IPv6` 政策。套用至 `IPv6` 叢集的任何 `IPv4` 網路政策規則都會遭到忽略。套用至 `IPv4` 叢集的任何 `IPv6` 網路政策規則都會遭到忽略。

 **網路政策** 
+ 網路政策僅會套用至屬於部署一部分的 Pod。沒有 `metadata.ownerReferences` 集合的獨立 Pod 無法套用網路政策。
+ 您可以將多個網路政策套用至相同的 Pod。當設定了兩個以上選取相同 Pod 的政策，所有政策皆會套用至 Pod。
+ 在所有網路政策中，單一 IP 位址範圍 (CIDR) 的連接埠和通訊協定組合數目上限為 24。選取器，如 `namespaceSelector` 解析為一或多個 CIDRs。如果多個選擇器解析為單一 CIDR，或者您在相同或不同的網路政策中多次指定相同的直接 CIDR，這些都會計入此限制。
+ 對於任何一種您的 Kubernetes 服務，服務連接埠必須與容器連接埠相同。如果您使用的是已命名連接埠，請也要在服務規格中使用相同的名稱。

 **管理員網路政策** 

1.  **管理員層政策 （先評估）**：所有管理員層 ClusterNetworkPolicies 都會在任何其他政策之前進行評估。在管理員層中，政策會依優先順序處理 （優先順序最低的數字優先）。動作類型會決定接下來會發生的情況。
   +  **拒絕動作 （最高優先順序）**：當具有拒絕動作的管理員政策符合流量時，無論任何其他政策為何，都會立即封鎖該流量。不會處理其他 ClusterNetworkPolicy 或 NetworkPolicy 規則。這可確保命名空間層級政策不會覆寫整個組織的安全控制。
   +  **允許動作**：評估拒絕規則之後，使用允許動作的管理員政策會依優先順序 （優先順序最低的數字優先） 處理。當允許動作相符時，系統會接受流量，而不會進行進一步的政策評估。這些政策可以根據標籤選擇器授予多個命名空間的存取權，從而集中控制哪些工作負載可以存取特定資源。
   +  **傳遞動作**：在管理員層政策中傳遞動作，將決策委派給較低的層。當流量符合通過規則時，評估會略過該流量的所有剩餘管理員層規則，並直接進入 NetworkPolicy 層。這可讓管理員將特定流量模式的控制明確委派給應用程式團隊。例如，您可以使用傳遞規則將命名空間內流量管理委派給命名空間管理員，同時對外部存取維持嚴格的控制。

1.  **網路政策層**：如果沒有管理員層政策與拒絕或允許相符，或者如果通過動作相符，則會評估命名空間範圍的 NetworkPolicy 資源。這些政策可在個別命名空間內提供精細的控制，並由應用程式團隊管理。命名空間範圍政策只能比管理員政策更嚴格。他們無法覆寫管理員政策的拒絕決策，但可以進一步限制管理員政策允許或傳遞的流量。

1.  **基準層管理員政策**：如果沒有管理員或命名空間範圍的政策符合流量，則會評估基準層 ClusterNetworkPolicies。這些提供可由命名空間範圍政策覆寫的預設安全狀態，允許管理員設定整個組織的預設值，同時為團隊提供視需要自訂的彈性。基準政策會依優先順序 （優先順序最低的數字優先） 進行評估。

1.  **預設拒絕 （如果沒有政策相符）**：此deny-by-default行為可確保只允許明確允許的連線，並維持強大的安全狀態。

 **移轉** 
+ 如果您的叢集目前正在使用第三方解決方案來管理 Kubernetes 網路政策，您可以搭配 Kubernetes 專用 Amazon VPC CNI 外掛程式來使用那些相同的政策。然而，您必須移除現有的解決方案，如此才不會管理相同的政策。

**警告**  
我們建議在移除網路政策解決方案後，更換所有曾套用該網路政策解決方案的節點。這是因為如果解決方案的 Pod 突然退出，流量規則可能會殘留。

 **安裝** 
+ 網路政策功能會建立且需要稱為 `policyendpoints.networking.k8s.aws` 的 `PolicyEndpoint` 自訂資源定義 (CRD)。自訂資源的 `PolicyEndpoint` 物件是由 Amazon EKS 管理。您不應修改或刪除這些資源。
+ 如果您執行使用執行個體角色 IAM 憑證的 Pod 或連線至 EC2 IMDS，請小心檢查是否有會封鎖 EC2 IMDS 存取的網路政策。您可能需要新增網路政策以允許 EC2 IMDS 的存取權。如需詳細資訊，請參閱《Amazon EC2 使用者指南》中的[執行個體中繼資料和使用者資料](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)。

  使用*服務帳戶的 IAM 角色*或 *EKS Pod 身分識別*的 Pod 不會存取 EC2 IMDS。
+ Kubernetes 專用 Amazon VPC CNI 外掛程式不會將網路政策套用至每個 Pod 的其他網路介面，而只會套用每個 Pod 的主要介面 (`eth0`)。這會影響下列架構：
  +  `ENABLE_V4_EGRESS` 變數設定為 `true` 的 `IPv6` Pod。此變數可讓 `IPv4` 輸出功能將 IPv6 Pod 連線到 `IPv4` 端點，例如叢集外部的端點。`IPv4` 輸出功能的運作方式是使用本機迴路 IPv4 地址建立額外的網路介面。
  + 使用鏈結的網絡外掛程式（例如 Multus）時。由於這些外掛程式會將網路介面新增至每個 Pod，因此網路政策不會套用至鏈結的網路外掛程式。

# 使用 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 與平台版本更新的版本。您可使用叢集名稱取代下列命令的 *my-cluster*，然後執行修改的命令來檢查目前 Kubernetes 版本：

```
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>

您的節點必須具有 Linux 核心版本 `5.10` 或更高版本。您可以使用 `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>

Kubernetes 專用 Amazon VPC CNI 外掛程式 會在 Pod 佈建的同時設定 Pod 的網路政策。在為新 Pod 設定所有政策之前，新 Pod 中的容器會以*預設允許政策*啟動。這稱為*標準模式*。預設允許政策意味著允許進出新 Pod 的所有輸入和輸出流量。例如，在使用作用中的政策更新新 Pod 之前，Pod 不會強制執行任何防火牆規則 (允許所有流量)。

將 `NETWORK_POLICY_ENFORCING_MODE` 變數設定為 `strict` 時，使用 VPC CNI 的 Pod 會從*預設拒絕政策*開始，然後設定政策。這稱為*嚴格模式*。在嚴格模式下，您必須為 Pod 需要存取的叢集中的每個端點都設定網路政策。請注意，此要求適用於 CoreDNS Pod。預設拒絕政策不會針對具有主機聯網的 Pod 進行設定。

您可以透過在 VPC CNI `DaemonSet` 的 `aws-node` 容器中將環境變數 `strict` 設定為 `NETWORK_POLICY_ENFORCING_MODE` 來變更預設網路政策。

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

## 步驟 2：啟用附加元件的網路政策參數
<a name="enable-network-policy-parameter"></a>

依預設，網路政策功能會使用節點的連接埠 `8162` 做為指標。此外，此功能會使用連接埠`8163`進行運作狀態探查。如果您在需要使用這些連接埠的節點或 Pod 內部執行另一應用程式，則該應用程式將無法執行。從 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. 選取附加元件方塊右上方的方塊，然後選擇 **Edit** (編輯)。

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` 安裝 Kubernetes 專用 Amazon VPC CNI 外掛程式，您可更新組態來變更連接埠。

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` daemonset 清單檔案的 `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. 選取附加元件方塊右上方的方塊，然後選擇 **Edit** (編輯)。

1. 在**設定 `Amazon VPC CNI`** 頁面上：

   1. 在**版本**清單中，選取 `v1.14.0-eksbuild.3` 或更高版本。

   1. 展開**選用組態設定**。

   1. 在**組態值**中輸入 JSON 金鑰 `"enableNetworkPolicy":` 和值 `"true"`。產生的文字必須是有效的 JSON 物件。如果此金鑰和值是文字方塊中唯一的資料，請以大括號 `{ }` 括住該金鑰和值。以下範例顯示已啟用網路政策：

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

      下列螢幕擷取畫面展示了案例的範例。  
![\[<shared id="consolelong"/> 顯示選用組態中具有網路政策的 VPC CNI 附加元件的 。\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/console-cni-config-network-policy.png)

### 自我管理附加元件
<a name="cni-network-policy-setup-procedure-self-managed-add-on"></a>

如果您已透過 `helm` 安裝 Kubernetes 專用 Amazon VPC CNI 外掛程式，您可以更新組態以啟用網路政策。

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` daemonset 清單檔案的 `aws-network-policy-agent` 容器，以 `true` 取代 `args:` 中命令引數 `--enable-network-policy=false` 裡的 `false`。

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

## 步驟 4. 後續步驟
<a name="cni-network-policy-setup-procedure-confirm"></a>

完成組態後，請確認 `aws-node` Pod 正在叢集上執行。

```
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` Pod 中有 2 個容器。在先前版本中，如果網路政策已停用，則 `aws-node` Pod 中只會有單一容器。

您現在可以將 Kubernetes 網路政策部署到您叢集。

若要實作 Kubernetes 網路政策，您可以建立 Kubernetes `NetworkPolicy`或`ClusterNetworkPolicy`物件並將其部署到您的叢集。 `NetworkPolicy` 物件的範圍是命名空間，而`ClusterNetworkPolicy`物件的範圍可以是整個叢集或多個命名空間。您實施政策以允許或拒絕根據標籤選取工具、命名空間及 IP 位址範圍的 Pod 之間的流量。如需有關建立 `NetworkPolicy` 物件的詳細資訊，請參閱 Kubernetes 文件中的[網路政策](https://kubernetes.io/docs/concepts/services-networking/network-policies/#networkpolicy-resource)。

Kubernetes `NetworkPolicy` 物件的強制執行是使用延伸式 Berkeley 封包篩選 (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` daemonset 清單檔案的 `aws-network-policy-agent` 容器，以 `false` 取代 `args:` 中命令引數 `--enable-network-policy=true` 裡的 `true`。

   ```
        - 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 *部署*建立的 Pod。如需 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 作出的關於網路政策是否允許或拒絕連線的每項決策，都會記錄在*流程日誌*中。每個節點上的網路政策日誌均包含具有網路政策的每個 Pod 之流程日誌。網路政策日誌會儲存於 `/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` 容器額外配備 1 個 vCPU。

### 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. 選取附加元件方塊右上方的方塊，然後選擇 **Edit** (編輯)。

1. 在**設定 *Amazon VPC CNI* **頁面上：

   1. 在**版本**下拉式清單中，選取 `v1.14.0-eksbuild.3` 或更高版本。

   1. 展開**選用組態設定**。

   1. 輸入最上層 JSON 金鑰 `"nodeAgent":`，且值為具有**組態值**中的金鑰 `"enablePolicyEventLogs":` 與 `"true"` 的值之物件。產生的文字必須是有效的 JSON 物件。下列範例顯示網路政策和網路政策日誌已啟用，並且網路政策日誌會傳送至 CloudWatch Logs：

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

下列螢幕擷取畫面展示了案例的範例。

![\[顯示選用組態中具有網路政策的 VPC CNI 附加元件和 CloudWatch 日誌的 <shared id="consolelong"/>。\]](http://docs.aws.amazon.com/zh_tw/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` 安裝 Kubernetes 專用 Amazon VPC CNI 外掛程式，您可以更新組態，以寫入網路政策日誌。  

1. 執行下列命令以啟用網路政策。

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

kubectl  
如果您已透過 `kubectl` 安裝 Kubernetes 專用 Amazon VPC CNI 外掛程式，您可以更新組態，以寫入網路政策日誌。  

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` 中的 `true` 取代 `false`。

   ```
        - 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/` 下。

#### 使用 Kubernetes 專用 Amazon VPC CNI 外掛程式傳送網路政策日誌
<a name="network-policies-cwl-agent"></a>

如果您啟用網路政策，系統會將第二個容器新增至*節點代理程式*的 `aws-node` Pod。此節點代理程式可以將網路政策日誌傳送到 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. 選取附加元件方塊右上方的方塊，然後選擇 **Edit** (編輯)。

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",
          }
      }
      ```
下列螢幕擷取畫面展示了案例的範例。

![\[顯示選用組態中具有網路政策的 VPC CNI 附加元件和 CloudWatch 日誌的 <shared id="consolelong"/>。\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/console-cni-config-network-policy-logs-cwl.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", "enableCloudWatchLogs": "true"}}'
   ```

##### 自我管理附加元件
<a name="cni-network-policy-cwl-agent-selfmanaged"></a>

 **Helm**   
如果您已透過 `helm` 安裝 Kubernetes 專用 Amazon VPC CNI 外掛程式，您可以更新組態，以傳送網路政策日誌至 CloudWatch 日誌。  

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:` 中的兩個命令引數 `--enable-policy-event-logs=false` 和 `--enable-cloudwatch-logs=false` 中的 `true` 取代 `false`。

   ```
        - 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>

Kubernetes 專用 Amazon VPC CNI 外掛程式會在節點上安裝 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>

 **問題**：刪除 Pod 後，網路 `policyendpoint` 仍然存在並且無法清除的問題。

 **解決方案**：此問題是因 VPC CNI 附加元件版本 1.19.3-eksbuild.1 的問題所造成。更新至較新版本的 VPC CNI 附加元件來解決此問題。

### 未套用網路政策
<a name="network-policies-troubleshooting-policyendpoint"></a>

 **問題**：Amazon VPC CNI 外掛程式中已啟用網路政策功能，但網路政策未正確套用。

如果您建立網路政策 `kind: NetworkPolicy`，但其不會影響 Pod，請檢查政策端點物件是否在與 Pod 相同的命名空間中建立。如果命名空間中沒有 `policyendpoint` 物件，則網路政策控制器 (EKS 叢集的一部分) 無法為要套用的網路政策代理程式 (VPC CNI 的一部分) 建立網路政策規則。

 **解決方案**：解決方案是修正 VPC CNI (`ClusterRole`：`aws-node`) 和網路政策控制站 (`ClusterRole`：`eks:network-policy-controller`) 的許可，並在任何政策強制執行工具 (例如 Kyverno) 中允許這些動作。確保 Kyverno 政策不會封鎖 `policyendpoint` 物件的建立。如需了解 [新的 `policyendpoints` CRD 和許可](#network-policies-troubleshooting-permissions) 中的必要許可，請參閱上一節。

### 在嚴格模式下刪除政策後，Pod 不會返回預設拒絕狀態
<a name="network-policies-troubleshooting-strict-mode-fallback"></a>

 **問題**：在嚴格模式下啟用網路政策時，Pod 會從預設拒絕政策開始。套用政策後，允許流量到達指定的端點。不過，刪除政策時，Pod 不會返回預設拒絕狀態，而是進入預設允許狀態。

 **解決方案**：此問題已在 VPC CNI 1.19.3 版中進行修正，其中包括網路政策代理程式 1.2.0 版。修正後，在啟用嚴格模式的情況下，只要移除政策，Pod 即會如預期返回到預設拒絕狀態。

### Pod 啟動延遲的安全群組
<a name="network-policies-troubleshooting-sgfp-latency"></a>

 **問題**：在 EKS 中使用 Pod 的安全群組功能時，Pod 啟動延遲會增加。

 **解決方案**：延遲是因資源控制器中來自 `CreateNetworkInterface` API 上的 API 限流的速率限制所致，其中 VPC 資源控制器會用於為 Pod 建立分支 ENI。檢查您帳戶的此操作的 API 限制，並考慮視需要請求提高限制。

### 由於 vpc.amazonaws.com/pod-eni 不足而導致 FailedScheduling
<a name="network-policies-troubleshooting-insufficient-pod-eni"></a>

 **問題**：Pod 無法排程並出現錯誤：`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.`

 **解決方案**：與上一個問題一樣，將安全群組指派給 Pod 會增加 Pod 排程延遲，並且新增每個 ENI 的時間可能會超出 CNI 閾值，進而導致啟動 Pod 的失敗。這是使用 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 映像和新的網路政策控制器映像，它們沒有任何漏洞。可以更新掃描器，以解決先前版本中找到的漏洞。

### 日誌中的流程資訊 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 移轉後的 Pod 至 pod 通訊問題
<a name="network-policies-troubleshooting-calico-migration"></a>

 **問題**：將 EKS 叢集升級至版本 1.30 並針對網路政策從 Calico 切換到 Amazon VPC CNI 後，套用網路政策時 Pod 至 Pod 通訊即會失敗。刪除網路政策時，即會還原通訊。

 **解決方案**：VPC CNI 中的網路政策代理程式指定的連接埠數量無法與 Calico 相比。請在網路政策中改用連接埠範圍。網路政策中每個通訊協定`ingress:`或`egress:`選擇器中每個通訊協定的唯一連接埠組合數目上限為 24。使用連接埠範圍來減少唯一的連接埠的數量，並避免此限制。

### 網路政策代理程式不支援獨立 Pod
<a name="network-policies-troubleshooting-standalone-pods"></a>

 **問題**：套用至獨立 Pod 的網路政策可能會有不一致的行為。

 **解決方案**：網路政策代理程式目前僅支援部署為 deployment/replicaset 一部分的 Pod。如果將網路政策套用至獨立 Pod，則行為中可能會出現一些不一致。此頁面頂端、[考量事項](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) 中會記載這一情況。將 Pod 部署為 deployment 或 replicaset 的一部分，以實現一致的網路政策行為。

# 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
   ```

   範例輸出如下。

   在輸出中，您應該在以下輸出中顯示的命名空間中看到 pod。*NAMES* 和 `READY` 直欄中的 Pod 數量與下列輸出中的數量不同。不要繼續，直到您看到具有相似名稱的 Pod 並且其在 `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/zh_tw/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/zh_tw/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/zh_tw/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/zh_tw/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>

 **適用於**：包含 Amazon EC2 執行個體的 Linux `IPv4` Fargate 節點、Linux 節點

![\[具有多個網路介面的節點圖表\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/cn-image.png)


預設情況下，當 Kubernetes 專用 Amazon VPC CNI 外掛程式為您的 Amazon EC2 節點建立次要[彈性網路介面](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) (網路介面) 時，會在與節點的主網路介面相同的子網路中建立這些介面。它還會將與主網路介面關聯的相同安全群組關聯至次要網路介面。由於以下一或多個原因，您可能希望外掛程式在不同子網中建立次要網路介面，或者希望將不同的安全群組與次要網路介面關聯 (或者兩者兼具)：
+ 主網路介面所在的子網路中可用的 `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。僅有來自次要網路介面的 IP 位址會指派給 Pod。
+ 如果您的叢集使用 `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>

開始本教學之前，先完成下列動作：
+ 檢閱考量事項
+ 熟悉 Kubernetes 專用 Amazon VPC CNI 外掛程式如何建立次要網路介面並將 IP 位址指派給 Pod。如需詳細資訊，請參閱 GitHub 上的 [ENI Allocation](https://github.com/aws/amazon-vpc-cni-k8s#eni-allocation) (ENI 分配)。
+ 在您的裝置或 AWS CloudShell 上安裝和設定的 AWS 命令列界面 (AWS CLI) 版本 `1.27.160` `2.12.3`或更新版本。若要檢查您目前的版本，請使用 `aws --version | cut -d / -f2 | cut -d ' ' -f1`。適用於 macOS 的 `yum`、 `apt-get`或 Homebrew 等套件管理員通常是最新版本 CLI AWS 後面的幾個版本。若要安裝最新版本，請參閱《 * AWS 命令列界面使用者指南*》中的使用 aws 設定[安裝](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) 和快速組態。 [https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config)在 AWS CloudShell 中安裝的 AWS CLI 版本也可能是最新版本後面的幾個版本。若要更新它，請參閱《CloudShell [AWS 使用者指南》中的將 CLI 安裝到您的主目錄](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software)。 * AWS CloudShell *
+ `kubectl` 命令列工具安裝在您的裝置或 AWS CloudShell 上。若要安裝或升級 `kubectl`，請參閱 [設定 `kubectl` 和 `eksctl`](install-kubectl.md)。
+ 建議您在 Bash shell 中完成本主題中的步驟。如果您不使用 Bash shell，則某些指令碼命令 (如行接續字元以及設定和使用變數的方式) 需要針對 shell 進行調整。此外，您的 Shell 的引用及轉義規則可能會有所不同。如需詳細資訊，請參閱《 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 AWS [描述](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-profiles)檔中定義的預設 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 CloudFormation 範本建立 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 CloudFormation 堆疊需要幾分鐘的時間才能建立。若要檢查堆疊的部署狀態，請執行下列命令。

      ```
      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 政策連接至 [IAM 主體](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#iam-term-principal)，必須為連接政策的 IAM 實體指派以下 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 叢集。如果發生這種情況，錯誤輸出包含的可用區域可支援新的叢集。使用至少兩個位於帳戶的支援可用區域子網路來建立您的叢集。如需詳細資訊，請參閱[容量不足](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。對於生產叢集，透過將所有範例值取代為您自己的值，為您的 VPC 相應地調整步驟。

1. 確認目前安裝的 Kubernetes 專用 Amazon VPC CNI 外掛程式是最新版本。若要確定 Amazon EKS 附加元件類型的最新版本並更新您的版本，請參閱 [更新 Amazon EKS 附加元件](updating-an-add-on.md)。若要確定自我管理附加元件類型的最新版本並更新您的版本，請參閱 [使用 Amazon VPC CNI 將 IP 指派給 Pod](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. 將額外的無類別域間路由 (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 區塊中，建立一個子網。建立的子網 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 中部署的所有資源之間進行通訊。但是，不允許與其 IP 位址在與 VPC 關聯的 CIDR 區塊之外的資源進行通訊。您可以將自己的路由表與子網相關聯以變更此行為。如需詳細資訊，請參閱《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. 擷取[叢集安全群組的 ID](sec-group-reqs.md)，並將其存放在變數中以供下一步驟使用。在您建立叢集時，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. 為每個網路介面組態建立唯一的檔案。

      以下命令為在上一步中建立的兩個子網建立單獨的 `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。
      + 我們建議盡可能將您的 `ENIConfigs` 命名為與您將使用 `ENIConfig` 的可用區域相同的名稱。由於各種原因，您可能需要為您的 `ENIConfigs` 使用與可用區域名稱不同的名稱。例如，如果您在同一可用區域中有兩個以上的子網，並且希望將其與自訂聯網一起使用，則需要多個 `ENIConfigs` 用於相同的可用區域。由於每個 `ENIConfig` 都需要一個唯一的名稱，因此您不能使用可用區域名稱命名多個 `ENIConfigs`。

        如果您的 `ENIConfig` 名稱與可用區域名稱並不完全相同，則將 \$1az\$11 和 \$1az\$12 取代為在前面命令中您自己的名稱，並使用在本教學課程後的 [ENIConfig 註釋您的節點](#custom-networking-annotate-eniconfig)。
**注意**  
如果您未指定用於生產叢集的有效安全群組，並且您正在使用：
      + `1.8.0` 版或更高版本的 Kubernetes 專用 Amazon VPC CNI 外掛程式，則會使用與節點的主要彈性網路介面關聯的安全群組。
      + Kubernetes 專用 Amazon VPC CNI 外掛程式的版本低於 `1.8.0`，則 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 節點。

   啟用 Kubernetes 以將可用區域的 `ENIConfig` 自動套用至叢集中建立的任何新 Amazon EC2 節點。

   1. 對於本教學課程中的測試叢集，請跳至[下一步](#custom-networking-automatically-apply-eniconfig)。

      對於生產叢集，請檢查 `aws-node` DaemonSet 的容器規格中是否存在含有 ` [ENI\$1CONFIG\$1ANNOTATION\$1DEF](https://github.com/aws/amazon-vpc-cni-k8s#eni_config_annotation_def) ` 環境變數的金鑰 `k8s.amazonaws.com/eniConfig` 的注釋。

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

      如果傳回輸出，則表示註釋已存在。如果未傳回輸出，表示變數尚未設定。對於生產叢集，您可以使用此設定或以下步驟中的設定。如果使用此設定，將會覆寫以下步驟中的設定。在本教學課程中，將使用下一步中的設定。

   1.  更新您的 `aws-node` DaemonSet 以將可用區域的 `ENIConfig` 自動應用至叢集中建立的任何新 Amazon EC2 節點。

      ```
      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 Resource Name (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 受管政策連接到 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 角色。但是，在生產叢集中，我們建議將政策連接至僅與 Kubernetes 專用 Amazon VPC CNI 外掛程式一起使用的單獨 IAM 角色。如需詳細資訊，請參閱[設定 Amazon VPC CNI 外掛程式以使用 IRSA](cni-iam-role.md)。

1. 建立下列其中一種節點群組類型。若要確定您想要部署的執行個體類型，請參閱 [選擇最佳的 Amazon EC2 節點執行個體類型](choosing-instance-type.md)。在本教學課程中，請完成**受管**、**沒有啟動範本或未指定 AMI ID 的啟動範本**選項。如果要將節點群組用於生產工作負載，我們建議您熟悉所有[受管節點群組](create-managed-node-group.md)和[自我管理節點群組](worker.md)選項，然後再部署節點群組。
   +  **受管**：使用下列其中一個選項，部署節點群組：
     +  **沒有啟動範本，或有啟動範本，但沒有指定 AMI ID**：執行下列命令。對於本教學課程，請使用範例值。對於生產節點群組，請將所有 example-values 取代為您自己的值。節點群組名稱不可超過 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. 確定 Amazon EKS 為您的節點推薦的 Pod 數目上限。請遵循 中的指示，將 `--cni-custom-networking-enabled` 新增至該主題中的步驟 3。請記下輸出，以便在下一個步驟中使用。

       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
          ```

          如果您建立的自訂 AMI 並非基於 Amazon EKS 最佳化 AMI，則需要自行自訂建立組態。
   +  **自我管理** 

     1. 確定 Amazon EKS 為您的節點推薦的 Pod 數目上限。請遵循  中的指示，將 `--cni-custom-networking-enabled` 新增至該主題的步驟 3。請記下輸出，以便在下一個步驟中使用。

     1. 使用 [建立自我管理的 Amazon Linux 節點](launch-workers.md) 中的指示部署節點群組。
**注意**  
如果您希望生產叢集中的節點支援更多數量的 ，請再次在  中執行指令碼。此外，將 `--cni-prefix-delegation-enabled` 選項新增制命令中。例如：`m5.large` 執行個體類型會傳回 `110`。如需有關如何啟用此功能的說明，請參閱 [將更多 IP 位址指派給具有字首的 Amazon EKS 節點](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` 名稱來註釋您的節點。如果您在每個可用區域中只有一個子網路，且將 `ENIConfigs` 命名為與可用區域相同的名稱，則無需執行此步驟。這是因為當您在[上一步](#custom-networking-automatically-apply-eniconfig)中啟用時，Kubernetes 專用 Amazon VPC CNI 外掛程式會自動為您將正確的 `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` 註釋一個節點，但可以使用相同的 `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 文件中的[安全地耗盡節點](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 從 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>
   ```

   您可以看到 CoreDNS Pod 被指派了 IP 位址來自您新增至 VPC 的 `192.168.1.0` CIDR 區塊的 IP 位址。如果沒有自訂網路，他們將被指派來自 `192.168.0.0` CIDR 區塊的地址，因為其是最初與 VPC 關聯的唯一 CIDR 區塊。

   如果 Pod `spec` 包含 `hostNetwork=true`，則會為其指派節點的主 IP 位址。它不會從您新增的子網路中指派位址。依預設，此值是設為 `false`。此值針對在您叢集上執行的 `kube-proxy` 和 Kubernetes 專用 Amazon VPC CNI 外掛程式 (`aws-node`) Pod 設定為 `true`。這就是為什麼在前面的輸出中沒有為 `kube-proxy` 和外掛程式的 `aws-node` Pod 指派 192.168.1.x 位址的原因。如需有關 Pod `hostNetwork` 設定的詳細資訊，請參閱 Kubernetes API 參考中的 [PodSpec v1 核心](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. 即使 CLI AWS 輸出顯示叢集已刪除後，刪除程序仍可能實際上未完成。刪除程序需要幾分鐘。執行下列命令來確認已完成。

   ```
   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
   ```

# 將更多 IP 位址指派給具有字首的 Amazon EKS 節點
<a name="cni-increase-ip-addresses"></a>

 **適用於**：包含 Amazon EC2 執行個體的 Linux 和 Windows 節點

 **適用於**：公有和私有子網路

每個 Amazon EC2 執行個體都支援最大數量的彈性網路介面，以及可指派給每個網路介面的最大數量的 IP 地址。每個節點的每個網路介面都需要一個 IP 地址。所有其他可用的 IP 地址都可以指派給 `Pods`。每個 `Pod` 都需要專屬的 IP 地址。因此，您的節點可能具有可用的運算和記憶體資源，但無法容納其他 `Pods`，因為節點已耗盡要指派給 `Pods` 的 IP 位址。

您可以透過指派 IP 字首 (而不是將個別的次要 IP 位址指派給節點)，大幅增加節點可指派給 `Pods` 的 IP 位址數量。每個字首都包含多個 IP 地址。如果您未針對 IP 字首指派設定叢集，則叢集必須進行更多 Amazon EC2 應用程式介面 (API) 呼叫，才能設定 Pod 連線所需的網路介面和 IP 位址。隨著叢集規模不斷擴大，這些 API 呼叫的頻率可能會導致 Pod 和執行個體的啟動時間變得更長。這樣一來，會導致擴展延遲以滿足大型和高峰工作負載的需求，並增加成本和管理負荷，因為您需要佈建額外的叢集和 VPC 以符合擴展需求。如需詳細資訊，請參閱 GitHub 上的 [Kubernetes 可擴展性閾值](https://github.com/kubernetes/community/blob/master/sig-scalability/configs-and-limits/thresholds.md)。

## 與適用於 Kubernetes 功能的 Amazon VPC CNI 外掛程式相容
<a name="cni-increase-ip-addresses-compatability"></a>

您可以搭配 IP 字首使用下列功能：
+ IPv4 來源網路位址轉譯 - 如需詳細資訊，請參閱 [啟用 Pod 的傳出網際網路存取](external-snat.md)。
+ 叢集、Pod 及服務的 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 數量上限會套用至叢集中的所有節點。
+ 依預設，您最多可在節點上執行 110 個 `Pods`，但您可以變更該數量。如果您變更該數量且擁有現有受管節點群組，則節點群組的下一個 AMI 或啟動範本更新會導致新的工作節點出現變更後的值。
+ 從指派 IP 地址轉換為指派 IP 字首時，建議您建立新的節點群組來增加可用 IP 地址的數量，而不是對現有節點執行輪流取代。在同時指派 IP 位址和字首的節點上執行 Pod，可能會導致公告的 IP 位址容量不一致，進而影響節點日後的工作負載。有關執行轉換的建議方式，請參閱《*Amazon EKS 最佳實務指南*》中的 [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 彈性網路介面相關聯。需要特定安全群組的 Pod 會被指派分支網路介面的主要 IP 地址。您可以把取得 IP 位址的 Pod，或從 IP 字首的 IP 位址與在相同節點上取得分支網路介面的 Pod 混合。
+ 僅適用於具有 Linux 節點的叢集。
  + 設定附加元件以指派字首給網路介面後，您就無法將 Kubernetes 專用 Amazon VPC CNI 外掛程式附加元件降級為低於 `1.9.0` (或 `1.10.1`) 的版本，且不移除叢集中所有節點群組中的所有節點。
  + 如果您也使用 Pod 的安全群組，且 `POD_SECURITY_GROUP_ENFORCING_MODE` = `standard`、`AWS_VPC_K8S_CNI_EXTERNALSNAT` = `false`，則當 Pod 與 VPC 外部端點通訊時，將使用節點的安全群組，而不會使用您指派給 Pod 的任何安全群組。

    如果您也使用 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` (針對 `IPv6` 叢集) 無類別域間路由 (CIDR) 區塊。`IPv6` 叢集中只能包含 Linux 節點。如果 IP 地址分散在子網路 CIDR 中，則使用 IP 字首可能會失敗。我們建議下列作法：
  + 使用子網路 CIDR 保留，如此一來，即使保留範圍內的任何 IP 位址仍在使用中，發布後也不會重新指派 IP 位址。此舉可確保字首無需分割，即可用於配置。
  + 使用專門用於執行指派 IP 字首之工作負載的新子網路。指派 IP 字首時，Windows 和 Linux 工作負載可在同一子網路中同時執行。
+ 若要將 IP 字首指派給節點，您的節點必須是 AWS Nitro 型。非 Nitro 型執行個體會繼續分配個別的次要 IP 位址，但要指派給 Pod 的 IP 位址數量遠低於 Nitro 型執行個體。
+  **僅適用於具有節點的叢集**：如果您的叢集針對 `IPv4` 系列設定，則必須安裝 Kubernetes 專用 Amazon VPC CNI 外掛程式附加元件的版本 `1.9.0` 或更新版本。您可以使用下列命令來檢查目前版本：

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

  如果您的叢集針對 `IPv6` 系列設定，則必須安裝附加元件的版本 `1.10.1`。如果您的外掛程式版本早於所需版本，則必須對其進行更新。如需詳細資訊，請參閱[使用 Amazon VPC CNI 將 IP 指派給 Pod](managing-vpc-cni.md)的更新章節。
+  **僅適用於具有 Windows 節點的叢集** 
  + 您必須為您的叢集啟用 Windows 支援。如需詳細資訊，請參閱[在 EKS 叢集上部署 Windows 節點](windows-support.md)。

## 將 IP 位址字首指派給節點
<a name="cni-increase-ip-procedure"></a>

設定叢集以將 IP 地址字首指派給節點。完成與節點作業系統相符的程序。

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

1. 啟用參數以為 Amazon VPC CNI DaemonSet 的網路介面指派字首。當您部署叢集時，Kubernetes 專用 Amazon VPC CNI 外掛程式附加元件的版本 `1.10.1` 或更高版本將與其一起部署。如果您使用 `IPv6` 系列建立叢集，則此設定會預設設為 `true`。如果您使用 `IPv4` 系列建立叢集，則此設定會預設設為 `false`。

   ```
   kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true
   ```
**重要**  
即使子網路有可用的 IP 位址，如果子網路沒有任何可用的連續 `/28` 區塊，您也會在 Kubernetes 專用 Amazon VPC CNI 外掛程式日誌中看到下列錯誤。  

   ```
   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. 如果計劃在沒有啟動範本的情況下或使用未在其中指定 AMI ID 的啟動範本來部署受管節點群組，且您使用的是先決條件中列出的 Kubernetes 專用 Amazon VPC CNI 外掛程式版本或更新版本，則請跳至下一個步驟。受管節點群組會自動為您計算 Pod 的數量上限。

   如果要部署的是自我管理節點群組，或使用其中具有指定 AMI ID 的啟動範本來部署受管節點群組，則必須決定 Amazon EKS 為節點建議的 Pod 數量上限。請遵循 中的指示，將 `--cni-prefix-delegation-enabled` 新增至步驟 3。請記下輸出，以便在稍後步驟中使用。
**重要**  
受管節點群組會強制對 `maxPods` 的值執行數量上限。對於少於 30 個 vCPU 的執行個體，數量上限為 110；對於所有其他執行個體，數量上限為 250。無論是否啟用字首委派，都會套用此數量上限。

1. 如果您使用針對 `IPv6` 設定叢集，請跳到下一個步驟。

   在下列其中一個選項中指定參數。要判斷哪個選項適合您，以及提供哪個值，請參閱 GitHub 上的 [WARM\$1PREFIX\$1TARGET、WARM\$1IP\$1TARGET 和 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. 使用至少一種 Amazon EC2 Nitro Amazon Linux 2023 執行個體類型，建立下列其中一個類型的節點群組。如需 Nitro 執行個體類型的清單，請參閱《Amazon EC2 使用者指南》中的[建置在 Nitro 系統上的執行個體](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
       ```

       如果您建立的自訂 AMI 並非基於 Amazon EKS 最佳化 AMI，則需要自行自訂建立組態。
**注意**  
如果您還想要將 IP 位址指派給來自與執行個體不同子網路的 Pod，則需要在此步驟中啟用該功能。如需詳細資訊，請參閱[使用自訂聯網在替代子網路中部署 Pod](cni-custom-network.md)。

### Windows
<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` 區塊，您也會在 Kubernetes 專用 Amazon VPC CNI 外掛程式日誌中看到下列錯誤。  

      ```
      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. 將範例值取代為大於零的值，並將您需要的項目新增至 的 `data`區段`ConfigMap`。如果您為 `warm-ip-target` 或 `minimum-ip-target` 設定了值，則該值會覆寫任何為 `warm-prefix-target` 設定的值。

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

   1. 儲存檔案並關閉編輯器。

1. 建立 Windows 節點群組，其中至少包含一個 Amazon EC2 Nitro 執行個體類型。如需 Nitro 執行個體類型的清單，請參閱《Amazon EC2 使用者指南》中的[建置在 Nitro 系統上的執行個體](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/instance-types.html#ec2-nitro-instances)。依預設，您最多可將 110 個 Pod 部署到節點。如果您要增加或減少該數量，請在引導組態的使用者資料中指定以下內容：將 *max-pods-quantity* 取代為您的 max Pod 值。

   ```
   -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 地址的數量。使用上一個輸出中傳回的其中一個節點名稱中的 `IPv4` 位址取代 *192.168.30.193*。

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

   範例輸出如下。

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

   在先前的輸出中，`110` 是 Kubernetes 將部署至節點的 Pod 數量上限，即使有 *144* 個可用的 IP 位址。

# 將安全群組指派至個別 Pod
<a name="security-groups-for-pods"></a>

 **適用於**：包含 Amazon EC2 執行個體的 Linux 節點

 **適用於**：私有子網路

Pod 的安全群組整合了 Amazon EC2 安全群組與 Kubernetes Pod。您可以使用 Amazon EC2 安全群組定義規則，允許您部署的 Pod 到許多 Amazon EC2 執行個體類型和 Fargate 上執行的節點之間的對內和對外網路流量。如需此功能的詳細說明，請參閱 [Pod 的安全群組簡介](https://aws.amazon.com/blogs/containers/introducing-security-groups-for-pods)部落格文章。

## 與適用於 Kubernetes 功能的 Amazon VPC CNI 外掛程式相容
<a name="security-groups-for-pods-compatability"></a>

您可針對具備以下功能的 Pod 使用安全群組：
+ IPv4 來源網路位址轉譯 - 如需詳細資訊，請參閱 [啟用 Pod 的傳出網際網路存取](external-snat.md)。
+ 叢集、Pod 及服務的 IPv6 位址 - 如需詳細資訊，請參閱 [了解叢集、Pod 與服務的 IPv6 位址](cni-ipv6.md)。
+ 使用 Kubernetes 網路政策來限制流量 - 如需詳細資訊，請參閱 [使用 Kubernetes 網路政策限制 Pod 流量](cni-network-policy.md)。

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

部署 Pod 的安全群組之前，請考慮下列限制和條件：
+ Pod 的安全群組無法與 Windows 節點或 EKS Auto 模式搭配使用。
+ Pod 的安全群組可與為包含 Amazon EC2 節點的 `IPv6` 系列設定的叢集搭配使用，方法是使用 1.16.0 版或更新的 Amazon VPC CNI 外掛程式。Pod 的安全群組可與為僅包含 Fargate 節點的 `IPv6` 系列設定的叢集搭配使用，方法是使用 1.7.7 版或更新的 Amazon VPC CNI 外掛程式。如需詳細資訊，請參閱[了解叢集、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 的安全群組，則會使用 Pod 安全群組指定的安全群組，而不是 `ENIConfig` 指定的安全群組。
+ 如果您使用的是版本 `1.10.2` 或更新版本的 Amazon VPC CNI 外掛程式，且 Pod 規格包括 `terminationGracePeriodSeconds` 設定，則該設置的值不能為零。
+ 如果您使用的是版本 `1.10` 或更舊版本的 Amazon VPC CNI 外掛程式或預設設定為 `POD_SECURITY_GROUP_ENFORCING_MODE`=`strict` 的版本 `1.11`，則使用具有設定為 `externalTrafficPolicy` 的 `Local` 的 `NodePort` 和 `LoadBalancer` 類型的 Kubernetes 服務不支援指派安全群組至其的 Pod。如需將負載平衡器與執行個體目標搭配使用的詳細資訊，請參閱 [透過 Network Load Balancer 路由 TCP 與 UDP 流量](network-load-balancing.md)。
+ 如果您使用的是版本 `1.10` 或更舊版本的 Amazon VPC CNI 外掛程式或預設設定為 `POD_SECURITY_GROUP_ENFORCING_MODE`=`strict` 的版本 `1.11`，來自具有指派安全群組之 Pod 的對外流量會停用來源 NAT，以便套用輸出安全群組規則。若要存取網際網路，必須在部署在使用 NAT 閘道或執行個體設定的私有子網路中的節點上啟動具有指派安全群組的 Pod。已指派安全群組部署至公有子網路的 Pod 無法存取網際網路。

  如果您使用的是版本 `1.11` 或更新版本的搭配 `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard` 的外掛程式，則以 VPC 外部為目標的 Pod 流量會轉換為執行個體主要網路介面的 IP 位址。對於此流量，將使用主要網路介面的安全群組中的規則，而不是使用 Pod 安全群組中的規則。
+ 若要將 Calico 網路政策與關聯安全群組的 Pod 搭配使用，則必須使用 `1.11.0` 版或更新版本的 Amazon VPC CNI 外掛程式，並設定為 `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard`。否則，具有關聯的安全群組之 Pod 的流量流出和流向不受 Calico 網路政策強制執行的約束，且僅限於 Amazon EC2 安全群組強制執行。若要更新 Amazon VPC CNI 版本，請參閱 [使用 Amazon VPC CNI 將 IP 指派給 Pod](managing-vpc-cni.md) 
+ Pod 在 Amazon EC2 節點上執行，這些節點使用的安全群組位於使用 [NodeLocal DNSCache](https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/) 的叢集，僅受 Amazon VPC CNI 外掛程式 `1.11.0` 版或更新版本支援，且設定為 `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard`。若要更新您的 Amazon VPC CNI 外掛程式版本，請參閱 [使用 Amazon VPC CNI 將 IP 指派給 Pod](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 的安全群組設定適用於 Kubernetes 的 Amazon VPC CNI 外掛程式
<a name="security-groups-pods-deployment"></a>

若您將 Pod 與 Amazon EC2 執行個體配合使用，則需針對安全群組設定適用於 Kubernetes 的 Amazon VPC CNI 外掛程式

若您僅使用 Fargate Pod，且叢集中沒有任何 Amazon EC2 節點，請參閱 [使用適用於 Amazon EKS Pod 的安全群組政策](sg-pods-example-deployment.md)。

1. 使用下列命令檢查您目前適用於 Kubernetes 的 Amazon VPC CNI 外掛程式版本：

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

   範例輸出如下。

   ```
   v1.7.6
   ```

   若適用於 Kubernetes 的 Amazon VPC CNI 外掛程式版本早於 `1.7.7`，則請將外掛程式更新至 `1.7.7` 版或更新版本。如需詳細資訊，請參閱[使用 Amazon VPC CNI 將 IP 指派給 Pod](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 角色的名稱，並存放在變數中。使用您叢集的名稱取代 *my-cluster*。

      ```
      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. 藉由將 `ENABLE_POD_ENI` 變數設定為 `aws-node` DaemonSet 中的 `true`，啟用 Amazon VPC CNI 附加程式來管理 Pod 的網路介面。一旦此設定設定為 `true`，對於叢集中的每個節點，該附加元件會建立一個 `cninode` 自訂資源。VPC 資源控制器會建立並連接一個稱為*幹線網路介面*與描述 `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`，則等待幾秒鐘後再重試一次。上一步驟要求重新啟動適用於 Kubernetes Pod 的 Amazon VPC CNI 外掛程式，這需要幾秒鐘的時間。

   ```
   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"}]
   ```

   如果您使用的 VPC CNI 版本低於 `1.15`，則會使用節點標籤而非 `CNINode` 自訂資源。您可以使用以下命令查看您的哪些節點已將節點標籤 `aws-k8s-trunk-eni` 設定為 `true`。如果傳回 `No resources found`，則等待幾秒鐘後再重試一次。上一步驟要求重新啟動適用於 Kubernetes Pod 的 Amazon VPC CNI 外掛程式，這需要幾秒鐘的時間。

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

   一旦建立幹線網路介面，Pod 就可以從幹線或標準網路介面指派次要 IP 位址。如果刪除節點，則會自動刪除幹線介面。

   當您在稍後的步驟中為 Pod 部署安全群組時，VPC 資源控制器會建立稱為*分支網路介面*與 `aws-k8s-branch-eni` 的描述，並將安全群組與其關聯。除了連接至節點的標準和幹線網路介面之外，還會建立分支網路介面。

   如果您使用的是存活或整備探查，則還需要停用 *TCP 早期的 demux*，以便 `kubelet` 可以透過 TCP 連接到分支網路介面上的 Pod。若要停用 *TCP 早期的 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"}]}}}}'
   ```
**注意**  
若您使用的是適用於 Kubernetes 附加元件的 Amazon VPC CNI 外掛程式 `1.11.0` 版或更新版本，並設定 `POD_SECURITY_GROUP_ENFORCING_MODE`=`standard`，如下一個步驟所述，則不需要執行之前的命令。

1. 若您的叢集使用 `NodeLocal DNSCache`，或者您希望將 Calico 網路政策與具有自己的安全群組的 Pod 搭配使用，或者您的 Kubernetes 服務類型為 `NodePort` 和 `LoadBalancer`，其使用的執行個體目標中您欲指派安全群組的 Pod 的 `externalTrafficPolicy` 設定為 `Local`，則必須使用適用於 Kubernetes 附加元件的 Amazon VPC CNI 外掛程式 `1.11.0` 版或更新版本，且必須啟用下列設定：

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

   重要事項：**Pod 安全群組規則不會套用至介於 Pod 之間或介於 Pod 與服務之間的流量，例如位於同一個節點上的 `kubelet` 或 `nodeLocalDNS`。在相同節點上使用不同安全群組的 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 的安全群組設定適用於 Kubernetes 的 Amazon VPC CNI 外掛程式](security-groups-pods-deployment.md)。

1. 建立 Kubernetes 命名空間以部署 資源。您可以將 *my-namespace* 取代為要使用的命名空間的名稱。

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

1.  將 Amazon EKS `SecurityGroupPolicy` 部署至您的叢集。

   1. 將以下內容複製到您的裝置。若您希望根據服務帳戶標籤選取 Pod，則您可以使用 `serviceAccountSelector` 取代 *podSelector*。您必須指定其中一個選取器或其他工具。空白 `podSelector` (例如：`podSelector: {}`) 選取命名空間中的所有 Pood。您可以將 *my-role* 變更為您的角色名稱。空白 `serviceAccountSelector` 會選取命名空間中的所有服務帳戶。您可以將 *my-security-group-policy* 取代為您的 `SecurityGroupPolicy` 的名稱，將 *my-namespace* 取代為要在其中建立 `SecurityGroupPolicy` 的命名空間。

      您必須將 *my\$1pod\$1security\$1group\$1id* 取代為現有安全群組的 ID。如果您沒有現有的安全群組，則必須先建立一個。如需詳細資訊，請參閱《Amazon EC2 使用者指南》[https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/)中的[適用於 Linux 執行個體的 Amazon EC2 安全群組](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html)一節。您可以指定 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 的一個或多個安全群組 必須符合下列條件：  
它們必須存在。如果它們不存在，那麼當您部署符合選取器的 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 控制平面通訊的規則。執行此動作最簡單的方法是指定叢集安全群組為其中一個安全群組。
安全群組政策僅適用於新排程的 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. 使用下列命令部署應用程式。當您部署應用程式時，適用於 Kubernetes 的 Amazon VPC CNI 外掛程式會符合您在上一步驟中指定的 `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 停滯，則嘗試這些小貼士。  
若任何 Pod 停滯在 `Waiting` 狀態，則請執行 `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` 執行個體支援九個分支網路介面。如果您的節點群組有五個節點，則最多可以為節點群組建立 45 個分支網路介面。您嘗試部署的第 46 個 Pod 將位於 `Pending` 狀態，直到刪除具有相關聯安全群組的另一個 Pod 為止。

   如果您執行 `kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace `，並看到類似下列訊息的訊息，則可以放心地將其忽略。當適用於 Kubernetes 的 Amazon VPC 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
   ```

   您不能超過執行個體類型上可以執行的 Pod 數量上限。關於每種執行個體類型上可執行的 Pod 數目上限清單，請參閱 GitHub 上的 [eni-max-pods.txt](https://github.com/aws/amazon-vpc-cni-k8s/blob/master/misc/eni-max-pods.txt)。當您刪除具有關聯安全群組的 Pod，或刪除 Pod 執行所在的節點時，VPC 資源控制器會刪除分支網路介面。如果您使用安全群組的 Pod 來刪除具有 Pod 的叢集，則控制器不會刪除分支網路介面，因此您需要自行刪除它們。如需有關如何刪除網路介面的資訊，請參閱《Amazon EC2 使用者指南》中的[刪除網路介面](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#delete_eni)。

1. 在單獨的終端機中，shell 轉換為 Pod。對於本主題的餘數，該終端機稱為 `TerminalB`。使用從上一步驟傳回的輸出中的其中一個 Pod 的 ID 取代 *5df6f7687b-4fbjm*。

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

1. 從 `TerminalB` 中的 shell，確認範例應用程式是否正常運作。

   ```
   curl my-app
   ```

   範例輸出如下。

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

   您收到了輸出，因為所有執行該應用程式的 Pod 都與您建立的安全群組關聯。該群組包含一個規則，其允許與安全群組關聯的所有 Pod 之間的流量。允許從該安全群組傳出 DNS 流量到與節點關聯的叢集安全群組。這些節點正在執行 CoreDNS Pod，您的 Pod 對此進行了名稱查詢。

1. 從 `TerminalA` 中，移除允許從安全群組與叢集進行 DNS 通訊的安全群組規則。如果在上一步驟並未新增 DNS 規則至叢集安全群組，則用您在其中建立規則的安全群組的 ID 取代 *\$1my\$1cluster\$1security\$1group\$1id*。

   ```
   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
   ```

   嘗試失敗，因為 Pod 不再能存取 CoreDNS 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
   ```

# 連接多個網路介面至 Pod
<a name="pod-multiple-network-interfaces"></a>

依預設，Amazon VPC CNI 外掛程式將一個 IP 位址指派給每個 Pod。此 IP 位址連接至*彈性網路介面*，以便處理 Pod 的所有傳入與傳出流量。如需增加頻寬及每秒封包速率效能，您可利用 VPC CNI 的*多重 NIC 功能*來設定多重主目錄 Pod。多重主目錄 Pod 是使用多個網路介面 (及多個 IP 位址) 的單一 Kubernetes Pod。您可藉由執行多重主目錄 Pod，利用同時連線將其應用程式流量分佈到多個網路介面。對於人工智慧 (AI)、機器學習 (ML) 與高效能運算 (HPC) 使用案例，這樣做尤其有用。

下面的圖表顯示了在工作節點上執行的多重主目錄 Pod，其中使用了多個網路介面卡 (NIC)。

![\[多重主目錄 Pod 連接兩個網路介面，一個網路介面連接 ENA，另一個網路介面連接 ENA 與 EFA\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/multi-homed-pod.png)


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

在 Amazon EC2 上，*彈性網路介面*是代表虛擬網路卡之 VPC 中的邏輯網路元件。針對多種 EC2 執行個體類型，網路介面會在硬體中共用單一網路介面卡 (NIC)。此單一 NIC 具有最大頻寬與每秒封包速率。

若啟用多重 NIC 功能，VPC CNI 預設不會大量指派 IP 位址。取而代之的是，VPC CNI 在新的 Pod 啟動時，會隨需向每個網路卡上的網路介面指派一個 IP 位址。此行為會降低 IP 位址耗盡的速率，透過使用多重主目錄 Pod 而增加。由於 VPC CNI 將隨需指派 IP 位址，在啟用多重 NIC 功能的執行個體上，啟用 Pod 可能需要更長時間。

## 考量事項
<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 可能需要更長時間。如需詳細資訊，請參閱前一 [背景介紹](#pod-multi-nic-background) 節。
+ 啟用多重 NIC 功能後，依預設，Pod 沒有多個網路介面。必須設定每個工作負載使用多重 NIC。新增 `k8s.amazonaws.com/nicConfig: multi-nic-attachment` 註解至應擁有多個網路介面的工作負載。

### `IPv6` 考量
<a name="pod-multi-nic-considerations-ipv6"></a>
+  **自訂 IAM 政策** - 若是 `IPv6` 叢集，針對 VPC CNI 建立及使用以下自訂 IAM 政策。此政策專門針對多重 NIC 設定。若要了解 VPC CNI 與 `IPv6` 叢集配合的更多一般資訊，請參閱 [了解叢集、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 不會指派 `IPv4` 位址給 `IPv6` 叢集上的 Pod。VPC CNI 而是將主機本機 `IPv4` 位址指派給每個 Pod，以便 Pod 與其他 Amazon VPC 或網際網路的外部 `IPv4` 資源通訊。

## Usage
<a name="pod-multi-NIC-usage"></a>

在 VPC CNI 中啟用多重 NIC `aws-node` 功能，以及 Pod 重新啟動之後，您可將每個工作負載設定為多重主目錄。下面是包含必要註解的 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 網路卡。彈性網路介面 (ENI) 是這種底層網路卡的虛擬呈現方式。

某些 EC2 執行個體類型具有多重 NIC，能夠增加頻寬及封包速率效能。針對此類執行個體，您可指派次要 ENI 給額外的網路卡。舉例來說，ENI \$11 能夠用做 NIC 連接至網路卡索引 0 的介面；而 ENI \$12 則可用做 NIC 連接至單獨網路卡索引的介面。

### **2. 什麼是多重主目錄 Pod？**
<a name="pod-muti-nic-faqs-pod"></a>

多重主目錄 Pod 是使用多個網路介面 (及隱含多個 IP 位址) 的單一 Kubernetes Pod。每個 Pod 網路介面與[彈性網路介面 (ENI)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html) 關聯，並且這些 ENI 是底層工作節點上單獨 NIC 的邏輯呈現方式。藉助多個網路介面，多重主目錄 Pod 可擁有額外的資料傳輸容量，這亦可提高其資料傳輸率。

**重要**  
VPC CNI 僅可在擁有多重 NIC 的執行個體類型上設定多重主目錄 Pod。

### **3. 這項功能有什麼用？**
<a name="pod-muti-nic-faqs-why"></a>

若您需要在 Kubernetes 型工作負載中擴展網路效能，可使用多重 NIC 功能來執行多重主目錄 Pod，這些 Pod 能夠與所有連接 ENA 裝置的底層 NIC 互動。藉助額外的網路卡，將應用程式流量分佈至多個同時連線，藉此來增加應用程式的頻寬容量與封包速率效能。對於人工智慧 (AI)、機器學習 (ML) 與高效能運算 (HPC) 使用案例，這樣做尤其有用。

### **4. 如何使用此功能？**
<a name="pod-muti-nic-faqs-how-to-enable"></a>

1. 首先，必須確認 Kubernetes 叢集使用 VPC CNI 1.20 版或更新版本。若要了解作為 EKS 附加元件來更新 VPC CNI 的步驟，請參閱 [更新 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. 最後，設定每個工作負載使用多個網路介面 (多重主目錄 Pod) 或單一網路介面。

### **5. 如何設定我的工作負載在支援的工作節點上使用多重 NIC？**
<a name="pod-muti-nic-faqs-how-to-workloads"></a>

如需使用多重主目錄 Pod，需要新增以下註解：`k8s.amazonaws.com/nicConfig: multi-nic-attachment`。這會連接底層執行個體中每個 NIC 的 ENI 至 Pod (Pod 與 NIC 間的一至多映射)。

若缺少此註解，VPC CNI 則會假設 Pod 僅需 1 個網路介面，並且在任何可用的 NIC 上將其指派給 ENI 中的 IP。

### **6. 這項功能支援哪些網路介面卡？**
<a name="pod-muti-nic-faqs-adapters"></a>

若您至少有一個 ENA 連接至底層網路卡用於處理 IP 流量，則可使用任何網路介面卡。若要了解詳細詳細，請參閱 *Amazon EC2 使用者指南*中的[彈性網路介面卡 (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 會在佈建多重主目錄 Pod 的網路連線時將其略過。然而，若您結合使用 **EFA 限定**介面卡與網路卡上的 **ENA** 介面卡，則 VPC CNI 亦會管理此裝置上的 ENI。如需將 EFA 限定介面卡與 EKS 叢集配合使用，請參閱 [使用 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 支援的相關詳細資訊。在以下範例中，使用節點的 EC2 執行個體 ID 來取代 `<your-instance-id>`。

 AWS CLI 範例：

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

輸出範例：

```
[ true ]
```

### **8. 能否查看與 Pod 關聯的不同 IP 位址？**
<a name="pod-muti-nic-faqs-list-ips"></a>

否，不容易查看。但是，您可使用節點的 `nsenter` 來執行 `ip route show` 等常用網路工具，以及查看額外的 IP 位址與介面。

### **9. 能否控制 Pod 的網路介面數目？**
<a name="pod-muti-nic-faqs-number-of-enis"></a>

否。設定工作負載在支援的執行個體上使用多重 NIC 後，單一 Pod 將自動擁有執行個體上每個網路卡的 IP 位址。或者，單一主目錄 Pod 將一個網路介面連接至執行個體上的一個 NIC。

**重要**  
VPC CNI 會略過*僅*連接 **EFA 限定**裝置的網路卡。

### **10. 能否設定 Pod 使用特定 NIC？**
<a name="pod-muti-nic-faqs-specify-nic"></a>

否，不支援。若 Pod 擁有相關註解，VPC CNI 則自動將其設定為讓工作節點上的每一個 NIC 與 ENA 介面卡配合使用。

### **11. 這項功能是否適用於其他 VPC CNI 聯網功能？**
<a name="pod-muti-nic-faqs-modes"></a>

是，VPC CNI 中的多重 NIC 功能適用於*自訂聯網*與*增強型子網路探索*。然而，多重主目錄 Pod 不使用自訂子網路或安全群組。取而代之的是，VPC CNI 會將 IP 位址與網路介面指派到多重主目錄 Pod，其具有與節點相同的子網路及安全群組組態。如需自訂聯網的詳細資訊，請參閱 [使用自訂聯網在替代子網路中部署 Pod](cni-custom-network.md)。

VPC CNI 中的多重 NIC 功能不適用於 *Pod 的安全群組*，亦不能與其結合使用。

### **12. 能否搭配此功能使用網路政策？**
<a name="pod-muti-nic-faqs-netpol"></a>

是，您可搭配多重 NIC 使用 Kubernetes 網路政策。Kubernetes 網路政策限制傳入與傳出 Pod 的網路流量。若要了解藉助 VPC CNI 套用網路政策的相關詳細資訊，請參閱 [使用 Kubernetes 網路政策限制 Pod 流量](cni-network-policy.md)。

### **13. 在 EKS 自動模式中是否啟用多 NIC 支援？**
<a name="pod-muti-nic-faqs-auto-mode"></a>

EKS 自動模式叢集不支援多 NIC。