

 **協助改進此頁面** 

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

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

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

# 在 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. 根據您的執行個體類型，決定節點的 Pod 數量上限。如需詳細資訊，請參閱[maxPods的判斷方式](choosing-instance-type.md#max-pods-precedence)。請注意用於下一個步驟的值。

       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. 根據您的執行個體類型，決定節點的 Pod 數量上限。如需詳細資訊，請參閱[maxPods的判斷方式](choosing-instance-type.md#max-pods-precedence)。請注意用於下一個步驟的值。

     1. 使用 [建立自我管理的 Amazon Linux 節點](launch-workers.md) 中的指示部署節點群組。
**注意**  
如果您希望生產叢集中的節點支援大量 Pod，您可以啟用字首委派。例如：`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
   ```