

 **帮助改进此页面** 

要帮助改进本用户指南，请选择位于每个页面右侧窗格中的**在 GitHub 上编辑此页面**链接。

# 配置 Amazon VPC CNI 插件以使用 IRSA
<a name="cni-iam-role"></a>

[适用于 Kubernetes 的 Amazon VPC CNI 插件](https://github.com/aws/amazon-vpc-cni-k8s)是在 Amazon EKS 集群中用于容器组（pod）联网的联网插件。该插件负责向 Kubernetes 容器组分配 VPC IP 地址并为每个节点上的容器组配置所需网络。

**注意**  
Amazon VPC CNI 插件还支持 Amazon EKS 容器组身份。有关更多信息，请参阅 [向 Kubernetes 服务账户分配 IAM 角色](pod-id-association.md)。

该插件：
+ 需要 AWS Identity and Access Management（IAM）权限。如果集群使用 `IPv4` 系列，则权限在 [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEKS_CNI_Policy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEKS_CNI_Policy.html) AWS 托管式策略中指定。如果集群使用 `IPv6` 系列，则必须将权限添加到您创建的 IAM 策略中；有关说明，请参阅[为使用 `IPv6` 系列的集群创建 IAM policy](#cni-iam-role-create-ipv6-policy)。您可以将该策略附加到 Amazon EKS 节点 IAM 角色或单独 IAM 角色。有关将策略附加到 Amazon EKS 节点 IAM 角色的说明，请参阅[Amazon EKS 节点 IAM 角色](create-node-role.md)。我们建议您按照本主题中的详细说明，将其分配给一个单独的角色。
+ 在部署时创建并配置为使用名为 `aws-node` 的 Kubernetes 服务账户。服务账户绑定到被分配了所需的 Kubernetes 权限的名为 `aws-node` 的 Kubernetes `clusterrole`。

**注意**  
适用于 Kubernetes 的 Amazon VPC CNI 插件容器组（pod）有权访问分配给 [Amazon EKS 节点 IAM 角色](create-node-role.md)的权限，除非您阻止对 IMDS 的访问。有关更多信息，请参阅[限制对分配给 Worker 节点的实例配置文件的访问](https://aws.github.io/aws-eks-best-practices/security/docs/iam/#restrict-access-to-the-instance-profile-assigned-to-the-worker-node)。
+ 需要现有 Amazon EKS 集群。要部署一个角色，请参阅[开始使用 Amazon EKS](getting-started.md)。
+ 需要适用于集群的现有 AWS Identity and Access Management（IAM）OpenID Connect（OIDC）提供者。要确定您是否已经拥有一个或是否要创建一个，请参阅[为集群创建 IAM OIDC 提供商](enable-iam-roles-for-service-accounts.md)。

## 步骤 1：创建适用于 Kubernetes 的 Amazon VPC CNI 插件 IAM 角色
<a name="cni-iam-role-create-role"></a>

1. 确定您的集群的 IP 系列。

   ```
   aws eks describe-cluster --name my-cluster | grep ipFamily
   ```

   示例输出如下。

   ```
   "ipFamily": "ipv4"
   ```

   输出可能会返回 `ipv6`。

1. 创建 IAM 角色。您可以使用 `eksctl` 或 `kubectl` 和 AWS CLI 以创建 IAM 角色。  
eksctl  
   + 使用与您的集群的 IP 系列匹配的命令创建 IAM 角色并将 IAM 策略附加到该角色。此命令创建并部署一个创建 IAM 角色的 AWS CloudFormation 堆栈，向其附加您指定的策略，并使用所创建 IAM 角色的 ARN 对现有 `aws-node` Kubernetes 服务账户添加注释。
     +  `IPv4` 

       将 *my-cluster* 替换为您自己的值。

       ```
       eksctl create iamserviceaccount \
           --name aws-node \
           --namespace kube-system \
           --cluster my-cluster \
           --role-name AmazonEKSVPCCNIRole \
           --attach-policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \
           --override-existing-serviceaccounts \
           --approve
       ```
     +  `IPv6` 

       将 *my-cluster* 替换为您自己的值。将 *111122223333* 替换为您的账户 ID 并将 *AmazonEKS\$1CNI\$1IPv6\$1Policy* 替换为您的 `IPv6` 策略的名称。如果没有 `IPv6` 策略，请参阅[为使用 `IPv6` 系列的集群创建 IAM policy](#cni-iam-role-create-ipv6-policy)创建一个。要将 `IPv6` 用于您的集群，它必须满足多项要求。有关更多信息，请参阅 [了解如何将 IPv6 地址分配给集群、容器组（pod）和服务](cni-ipv6.md)。

       ```
       eksctl create iamserviceaccount \
           --name aws-node \
           --namespace kube-system \
           --cluster my-cluster \
           --role-name AmazonEKSVPCCNIRole \
           --attach-policy-arn arn:aws:iam::111122223333:policy/AmazonEKS_CNI_IPv6_Policy \
           --override-existing-serviceaccounts \
           --approve
       ```  
kubectl 和 AWS CLI  

   1. 查看集群的 OIDC 提供者 URL。

      ```
      aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text
      ```

      示例输出如下。

      ```
      https://oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE
      ```

      如果没有返回输出，则您必须[为集群创建 IAM OIDC 提供程序](enable-iam-roles-for-service-accounts.md)。

   1. 将以下内容复制到名为 *vpc-cni-trust-policy.json* 的文件中。将 *111122223333* 替换为您的账户 ID，将 *EXAMPLED539D4633E53DE1B71EXAMPLE* 替换为在上一步中返回的输出。将 *region-code* 替换为您的集群所在的 AWS 区域。

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Principal": {
                      "Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
                  },
                  "Action": "sts:AssumeRoleWithWebIdentity",
                  "Condition": {
                      "StringEquals": {
                          "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com",
                          "oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:aws-node"
                      }
                  }
              }
          ]
      }
      ```

   1. 创建角色。您可以将 *AmazonEKSVPCCNIRole* 替换为选择的任何名称。

      ```
      aws iam create-role \
        --role-name AmazonEKSVPCCNIRole \
        --assume-role-policy-document file://"vpc-cni-trust-policy.json"
      ```

   1. 将所需的 IAM 策略附加到角色。运行与集群的 IP 系列匹配的命令。
      +  `IPv4` 

        ```
        aws iam attach-role-policy \
          --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \
          --role-name AmazonEKSVPCCNIRole
        ```
      +  `IPv6` 

        将 *111122223333* 替换为您的账户 ID 并将 *AmazonEKS\$1CNI\$1IPv6\$1Policy* 替换为您的 `IPv6` 策略的名称。如果没有 `IPv6` 策略，请参阅[为使用 `IPv6` 系列的集群创建 IAM policy](#cni-iam-role-create-ipv6-policy)创建一个。要将 `IPv6` 用于您的集群，它必须满足多项要求。有关更多信息，请参阅 [了解如何将 IPv6 地址分配给集群、容器组（pod）和服务](cni-ipv6.md)。

        ```
        aws iam attach-role-policy \
          --policy-arn arn:aws:iam::111122223333:policy/AmazonEKS_CNI_IPv6_Policy \
          --role-name AmazonEKSVPCCNIRole
        ```

   1. 运行以下命令以使用您以前创建的 IAM 角色的 ARN 对 `aws-node` 服务账户添加注释。将示例值替换为您自己的值。

      ```
      kubectl annotate serviceaccount \
          -n kube-system aws-node \
          eks.amazonaws.com/role-arn=arn:aws:iam::111122223333:role/AmazonEKSVPCCNIRole
      ```

1. （可选）配置 Kubernetes 服务账户使用的 AWS Security Token Service 端点类型。有关更多信息，请参阅 [为服务账户配置 AWS Security Token Service 端点](configure-sts-endpoint.md)。

## 步骤 2：重新部署适用于 Kubernetes 的 Amazon VPC CNI 插件容器组（pod）
<a name="cni-iam-role-redeploy-pods"></a>

1. 删除并重新创建任何与服务账户关联的现有容器组（pod），以应用凭证环境变量。注释未应用于目前在没有注释的情况下运行的容器组（pod）。以下命令将删除现有的 `aws-node` DaemonSet 容器组（pod）并使用服务账户注释对其进行部署。

   ```
   kubectl delete Pods -n kube-system -l k8s-app=aws-node
   ```

1. 确认容器组（pod）已全部重新启动。

   ```
   kubectl get pods -n kube-system -l k8s-app=aws-node
   ```

1. 描述其中一个容器组（pod）并确保 `AWS_WEB_IDENTITY_TOKEN_FILE` 和 `AWS_ROLE_ARN` 环境变量存在。将 *cpjw7* 替换为上一步输出中返回的其中一个容器组（pod）的名称。

   ```
   kubectl describe pod -n kube-system aws-node-cpjw7 | grep 'AWS_ROLE_ARN:\|AWS_WEB_IDENTITY_TOKEN_FILE:'
   ```

   示例输出如下。

   ```
   AWS_ROLE_ARN:                 arn:aws:iam::111122223333:role/AmazonEKSVPCCNIRole
         AWS_WEB_IDENTITY_TOKEN_FILE:  /var/run/secrets/eks.amazonaws.com/serviceaccount/token
         AWS_ROLE_ARN:                           arn:aws:iam::111122223333:role/AmazonEKSVPCCNIRole
         AWS_WEB_IDENTITY_TOKEN_FILE:            /var/run/secrets/eks.amazonaws.com/serviceaccount/token
   ```

   由于容器组（pod）包含两个容器，因此会返回两组重复的结果。两个容器具有相同的值。

   如果容器组（pod）正在使用 AWS 区域级端点，之前的输出中也将返回以下行。

   ```
   AWS_STS_REGIONAL_ENDPOINTS=regional
   ```

## 步骤 3：从节点 IAM 角色中删除 CNI 策略
<a name="remove-cni-policy-node-iam-role"></a>

如果 [Amazon EKS 节点 IAM 角色](create-node-role.md)当前附加有 `AmazonEKS_CNI_Policy` IAM (`IPv4`) 策略或 [IPv6 策略](#cni-iam-role-create-ipv6-policy)，而且您已另行创建了 IAM 角色，已将该策略附加到该 IAM 角色，并将其分配给了 `aws-node` Kubernetes 服务账户，则我们建议您使用与集群的 IP 系列匹配的 AWS CLI 命令，从节点角色中删除该策略。将 *AmazonEKSNodeRole* 替换为您的节点角色的名称。
+  `IPv4` 

  ```
  aws iam detach-role-policy --role-name AmazonEKSNodeRole --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
  ```
+  `IPv6` 

  将 *111122223333* 替换为您的账户 ID 并将 *AmazonEKS\$1CNI\$1IPv6\$1Policy* 替换为您的 `IPv6` 策略的名称。

  ```
  aws iam detach-role-policy --role-name AmazonEKSNodeRole --policy-arn arn:aws:iam::111122223333:policy/AmazonEKS_CNI_IPv6_Policy
  ```

## 为使用 `IPv6` 系列的集群创建 IAM policy
<a name="cni-iam-role-create-ipv6-policy"></a>

如果您创建了使用 `IPv6` 系列的集群，并且集群配置了版本 `1.10.1` 或更高版本的适用于 Kubernetes 附加组件的 Amazon VPC CNI 插件，则需要创建一个可以将其分配给 IAM 角色的 IAM 策略。如果您现有的集群在创建时没有使用 `IPv6` 系列进行配置，则必须创建一个新集群才能使用 `IPv6`。有关集群使用 `IPv6` 的详细信息，请参阅 [了解如何将 IPv6 地址分配给集群、容器组（pod）和服务](cni-ipv6.md)。

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