配置 Amazon VPC CNI 插件以将 IAM 角色用于服务账户 - Amazon EKS
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

配置 Amazon VPC CNI 插件以将 IAM 角色用于服务账户

适用于 Kubernetes 的 Amazon VPC CNI 插件是在 Amazon EKS 集群中用于 Pod 联网的联网插件。该插件负责向 Kubernetes 节点分配 VPC IP 地址并为每个节点上的 Pod 配置所需网络。该插件:

  • 需要 IAM 权限。如果您要为集群使用 IPv4,则权限由 AmazonEKS_CNI_Policy Amazon 托管策略提供。如果您要为集群使用 IPv6,则您将在以下程序中创建自定义 IAM 策略。您可以将该策略附加到 Amazon EKS 节点 IAM 角色 或单独 IAM 角色。我们建议您按照本主题中的详细说明,将其分配给一个单独的角色。

  • 在部署时创建并配置为使用名为 aws-node 的服务账户。服务账户绑定到被分配了所需的 Kubernetes 权限的名为 aws-node 的 Kubernetes clusterrole

注意

无论是否将 Amazon VPC CNI 插件配置为将 IAM 角色用于服务账户,Pod(一组容器)都可以访问分配给 Amazon EKS 节点 IAM 角色 的权限,除非您阻止对 IMDS 进行访问。有关更多信息,请参阅限制访问分配给 Worker 节点的实例配置文件

先决条件

  • 现有 Amazon EKS 集群。要部署一个角色,请参阅 开始使用 Amazon EKS

  • 集群的现有 Amazon Identity and Access Management IAM OpenID Connect (OIDC) 提供程序。要确定您是否已经拥有一个或是否要创建一个,请参阅 为集群创建 IAM OIDC 提供商

第 1 步:(可选)为 IPv6 创建 IAM 策略

如果您创建了使用 IPv6 系列的 1.21 版或更高版本的集群,并且集群配置了 1.10.1 版或更高版本的 VPC CNI 附加组件,则需要创建一个 IAM 策略,您可以在后面的步骤中将其分配给 IAM 角色。如果您现有的 1.21 版或更高版本的集群在创建时没有使用 IPv6 系列进行配置,则必须创建一个新集群才能使用 IPv6。有关集群使用 IPv6 的详细信息,请参阅 将 IPv6 地址分配给容器和服务

  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/*" ] } ] }
  2. 创建 IAM 策略。

    aws iam create-policy \ --policy-name AmazonEKS_CNI_IPv6_Policy \ --policy-document file://vpc-cni-ipv6-policy.json

第 2 步:创建 Amazon VPC CNI 插件 IAM 角色

如果集群使用 IPv4,您可将 AmazonEKS_CNI_Policy 托管 IAM 策略附加到该角色。如果集群使用 IPv6,您将附加 AmazonEKS_CNI_IPv6_Policy

您可以使用 eksctl 或 Amazon Web Services Management Console 创建您的 CNI 插件 IAM 角色。

eksctl
  1. 使用以下命令创建 IAM 角色并将 IAM 策略附加到该角色。将 my-cluster 替换为您自己的值。此命令创建并部署一个创建 IAM 角色的 Amazon CloudFormation 堆栈,向其附加您指定的策略,并使用所创建 IAM 角色的 ARN 对现有 aws-node 服务账户添加注释。

    eksctl create iamserviceaccount \ --name aws-node \ --namespace kube-system \ --cluster my-cluster \ --attach-policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \ --approve \ --override-existing-serviceaccounts
  2. (可选)向服务账户添加注释,注明使用 Amazon Security Token Service Amazon Web Services 区域端点而不是全局端点。有关更多信息,请参阅将 IAM 角色与服务账户关联

  3. 查看正在运行的 Amazon VPC CNI Pod。

    kubectl get pods -n kube-system -l k8s-app=aws-node
  4. 描述 Pod 之一并确保 AWS_WEB_IDENTITY_TOKEN_FILEAWS_ROLE_ARN 环境变量存在。将 9rgzw 替换为上一步输出中返回的其中一个 Pod 的名称。

    kubectl exec -n kube-system aws-node-9rgzw -c aws-node -- env | grep AWS

    输出:

    ... AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token ... AWS_ROLE_ARN=arn:arn:aws::111122223333:role/eksctl-prod-addon-iamserviceaccount-kube-sys-Role1-V66K5I6JLDGK ...

    如果将注释添加到服务账户,以使用 Amazon Security Token Service Amazon Web Services 区域端点而不是全局端点,请验证之前的输出是否还返回以下行。

    AWS_STS_REGIONAL_ENDPOINTS=regional
Amazon Web Services Management Console

先决条件

集群的现有 Amazon Identity and Access Management (IAM) OpenID Connect (OIDC) 提供程序。要确定您是否已经拥有一个或是否要创建一个,请参阅 为集群创建 IAM OIDC 提供商

使用 Amazon Web Services Management Console 创建 CNI 插件 IAM 角色

  1. 在左侧导航窗格中,选择 Roles (角色)。然后选择 Create role (创建角色)

  2. Trusted entity type(受信任的实体类型)部分中,选择 Web identity(Web 身份)。

  3. Web identity(Web 身份)部分:

    1. 对于 Identity provider (身份提供商),选择您集群的 URL。

    2. 对于 Audience (受众),请选择 sts.amazonaws.com

  4. 选择 Next (下一步)

  5. Filter policies(筛选策略)框中,输入 AmazonEKS_CNI_PolicyAmazonEKS_CNI_IPv6_Policy,然后选中搜索返回的策略名称左侧的复选框。

  6. 选择 Next (下一步)

  7. 对于 Role name (角色名称),为角色输入唯一名称,例如 AmazonEKSCNIRole

  8. 对于 Description(说明),输入描述性文本,例如 Amazon EKS - CNI role

  9. 选择 Create role (创建角色)

  10. 创建角色后,在控制台中选择角色以将其打开进行编辑。

  11. 选择 Trust relationships(信任关系)选项卡,然后选择 Edit trust policy(编辑信任策略)。

  12. 该行看起来类似于以下行:

    "oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com"

    将该行更改为类似于以下行。将 EXAMPLED539D4633E53DE1B716D3041E 替换为集群的 OIDC 提供程序 ID,将 region-code 替换为集群所在的 Amazon Web Services 区域代码,务必在以下字符串中将 aud(来自之前的输出)更改为 sub

    "oidc.eks.region-code.amazonaws.com.cn/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:kube-system:aws-node"
  13. 选择 Update policy(更新策略)以完成操作。

为具有 IAM 角色的 aws-node Kubernetes 服务账户添加注释

  1. 如果您将 Amazon EKS 附加组件与 1.18 版或更高版本的 Amazon EKS 集群结合使用,请改为参阅 更新 Amazon VPC CNI Amazon EKS 附加组件,而不是完成此程序。如果您没有使用 Amazon VPC CNI Amazon EKS 附加组件,请通过以下命令使用您先前创建的 IAM 角色的 ARN 注释 aws-node 服务账户。将 example values 替换为您自己的值。

    kubectl annotate serviceaccount \ -n kube-system aws-node \ eks.amazonaws.com/role-arn=arn:aws:iam::AWS_ACCOUNT_ID:role/AmazonEKSCNIRole
  2. (可选)向服务账户添加额外注释,注明使用 Amazon Security Token Service Amazon Web Services 区域端点而不是全局端点。有关更多信息,请参阅将 IAM 角色与服务账户关联

  3. 删除并重新创建任何与服务账户关联的现有 Pod,以应用凭据环境变量。变异 Webhook 不将其应用到已经在运行的 Pod。以下命令删除现有的 aws-node DaemonSet Pod 并使用服务账户注释部署这些 Pod。

    kubectl delete pods -n kube-system -l k8s-app=aws-node
  4. 确认 Pod 已全部重新启动。

    kubectl get pods -n kube-system -l k8s-app=aws-node
  5. 描述 Pod 之一并确保 AWS_WEB_IDENTITY_TOKEN_FILEAWS_ROLE_ARN 环境变量存在。将 9rgzw 替换为上一步输出中返回的其中一个 Pod 的名称。

    kubectl exec -n kube-system aws-node-9rgzw -c aws-node -- env | grep AWS

    输出:

    ... AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token ... AWS_ROLE_ARN=arn:arn:aws::111122223333:role/eksctl-prod-addon-iamserviceaccount-kube-sys-Role1-V66K5I6JLDGK ...

    如果将注释添加到服务账户,以使用 Amazon Security Token Service Amazon Web Services 区域端点而不是全局端点,请验证之前的输出是否还返回以下行。

    AWS_STS_REGIONAL_ENDPOINTS=regional

从节点 IAM 角色中删除 CNI 策略

如果您的 Amazon EKS 节点 IAM 角色 当前附加有 AmazonEKS_CNI_Policy IAM 策略或 IPv6 策略,而且您已另行创建了一个 IAM 角色,并已将该策略附加到该 IAM 角色并将其分配给了 aws-node Kubernetes 服务账户,那么我们建议您从节点角色中删除该策略。

  1. 通过以下网址打开 IAM 控制台:https://console.aws.amazon.com/iam/

  2. 在左侧导航窗格中,选择 Roles(角色),然后搜索您的节点实例角色。

  3. 请选择节点实例角色的 Permissions(权限)选项卡,然后选择 AmazonEKS_CNI_PolicyAmazonEKS_CNI_IPv6_Policy 右侧的 X

  4. 选择 Detach (分离) 以完成操作。