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

配置 Kubernetes 服务账户以代入 IAM 角色

本主题介绍如何配置 Kubernetes 服务账户以代入 Amazon Identity and Access Management(IAM)角色。然后,配置为使用服务账号的任何容器组(pod)都可以访问该角色有权访问的任何 Amazon Web Service。

先决条件

  • 现有集群。如果您没有,可以按照 开始使用 Amazon EKS 指南之一创建一个。

  • 集群的现有 IAM OpenID Connect(OIDC)提供商。要了解您是否已拥有一个提供商或如何创建一个提供商,请参阅 为集群创建 IAM OIDC 提供商

  • 您的设备或 Amazon CloudShell 上安装并配置了 2.8.0 版或更高版本,或 1.25.87 版或更高版本的 Amazon CLI。您可以使用 aws --version | cut -d / -f2 | cut -d ' ' -f1 检查您的当前版本。软件包管理器(如 yumapt-get 或适用于 macOS 的 Homebrew)通常比 Amazon CLI 的最新版本落后几个版本。要安装最新版本,请参阅《Amazon Command Line Interface 用户指南》中的安装、更新和卸载 Amazon CLI使用 aws configure 进行快速配置。Amazon CloudShell 中安装的 Amazon CLI 版本也可能比最新版本落后几个版本。要对其进行更新,请参阅《Amazon CloudShell 用户指南》中的将 Amazon CLI 安装到您的主目录

  • 您的设备或 Amazon CloudShell 上安装了 kubectl 命令行工具。该版本可以与集群的 Kubernetes 版本相同,或者最多早于或晚于该版本一个次要版本。例如,如果您的集群版本为 1.22,则可以将 kubectl 版本 1.211.221.23 用于它。要安装或升级 kubectl,请参阅 安装或更新 kubectl

  • 包含集群配置的现有 kubectl config 文件。要创建 kubectl config 文件,请参阅 为 Amazon EKS 集群创建或更新 kubeconfig 文件

将 IAM 角色与 Kubernetes 服务账户关联。

  1. 要将现有 IAM policy 关联到您的 IAM 角色,请跳至下一步

    创建一个 IAM policy。您可以创建自己的策略,也可以复制已授予您部分所需权限的 Amazon 托管策略,并根据您的特定要求对其进行自定义。有关更多信息,请参阅 IAM 用户指南 中的创建 IAM policy

    1. 创建一个包含 pods 访问 Amazon Web Services 所需权限的文件。有关所有 Amazon Web Services 的所有操作的列表,请参阅服务授权参考

      您可以运行以下命令创建一个示例策略文件,以实现对 Amazon S3 存储桶的只读访问权限。您可以选择将配置信息或引导脚本存储在此存储桶中,并且您 pod 中的容器可以从存储桶读取文件并将其加载到应用程序中。如果您要创建此示例策略,请将以下内容复制到您的设备。将 my-pod-secrets-bucket 替换为您的存储桶名称并运行该命令。

      cat >my-policy.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::my-pod-secrets-bucket" } ] } EOF
    2. 创建 IAM policy。

      aws iam create-policy --policy-name my-policy --policy-document file://my-policy.json
  2. 创建 IAM 角色并将其与 Kubernetes 服务账户关联。您可以使用 eksctl 或 Amazon CLI。

    eksctl

    先决条件

    您的设备或 Amazon CloudShell 上安装了 0.114.0 版或更高版本的 eksctl 命令行工具。要安装或更新 eksctl,请参阅 安装或更新 eksctl

    my-service-account 替换为您希望 eksctl 创建并与 IAM 角色关联的 Kubernetes 服务账户的名称。将 default 替换为您希望 eksctl 在其中创建服务账户的命名空间。将 my-cluster 替换为您集群的名称。将 my-role 替换为您希望将服务账户关联到的角色名称。如果角色尚不存在,eksctl 会为您创建它。将 111122223333 替换为您的账户 ID,并将 my-policy 替换为现有策略的名称。

    eksctl create iamserviceaccount --name my-service-account --namespace default --cluster my-cluster --role-name "my-role" \ --attach-policy-arn arn:aws:iam::111122223333:policy/my-policy --approve
    重要
    • 如果角色或服务账户已经存在,则之前的命令可能会失败。在这些情况下,Eksctl 提供不同的选项供您使用。有关更多信息,请运行 eksctl create iamserviceaccount --help

    • 使用具有 pod 的服务账户之前,您指定的或 eksctl 创建的服务账户必须绑定到现有的 Kubernetes role,或包括服务账户所需 Kubernetes 权限的 clusterrole。有关更多信息,请参阅 Kubernetes 文档中的使用 RBAC 授权

    Amazon CLI
    1. 如果您有要代入 IAM 角色的现有 Kubernetes 服务账户,则您可以跳过此步骤。

      创建 Kubernetes 服务账户。将以下内容复制到您的设备。将 my-service-account 替换为所需的名称,如有必要,将 default 替换为其他命名空间。如更改 default,则命名空间必须已经存在。

      cat >my-service-account.yaml <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: my-service-account namespace: default EOF kubectl apply -f my-service-account.yaml
      重要

      使用具有 pod 的服务账户之前,您创建的服务账户必须绑定到现有的 Kubernetes role,或包括服务账户所需 Kubernetes 权限的 clusterrole。有关更多信息,请参阅 Kubernetes 文档中的使用 RBAC 授权

    2. 使用以下命令将 Amazon Web Services 账户 ID 设置为环境变量。

      account_id=$(aws sts get-caller-identity --query "Account" --output text)
    3. 使用以下命令将集群的 OIDC 身份提供商设置为环境变量。将 my-cluster 替换为您的集群名称。

      oidc_provider=$(aws eks describe-cluster --name my-cluster --region $AWS_REGION --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
    4. 为服务账户的命名空间和名称设置变量。将 my-service-account 替换为要代入角色的 Kubernetes 服务账户。将 default 替换为服务账户的命名空间。

      export namespace=default export service_account=my-service-account
    5. 运行以下命令为 IAM 角色创建信任策略文件。若要允许命名空间内的所有服务账户使用该角色,请将以下内容复制到您的设备。将 StringEquals 替换为 StringLike,并将 $service_account 替换为 *。您可在 StringEqualsStringLike 条件中添加多个条目,以允许多个服务账户或命名空间代入角色。要允许其他 Amazon Web Services 账户 中的角色(而不是您的集群所在账户中的角色)代入该角色户,请参阅 跨账户 IAM 权限 获取更多信息。

      cat >trust-relationship.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::$account_id:oidc-provider/$oidc_provider" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "$oidc_provider:aud": "sts.amazonaws.com", "$oidc_provider:sub": "system:serviceaccount:$namespace:$service_account" } } } ] } EOF
    6. 创建角色。将 my-role 替换为您的 IAM 角色名称,并将 my-role-description 替换为您的角色描述。

      aws iam create-role --role-name my-role --assume-role-policy-document file://trust-relationship.json --description "my-role-description"
    7. 将 IAM policy 附加到您的角色。将 my-role 替换为您的 IAM 角色的名称,并将 my-policy 替换为您创建的现有策略的名称。

      aws iam attach-role-policy --role-name my-role --policy-arn=arn:aws:iam::$account_id:policy/my-policy
    8. 请使用要让服务账户代入的 IAM 角色的 Amazon 资源名称(ARN)注释您的服务账户。将 my-role 替换为您的现有 IAM 角色的名称。假设您在上一步中允许其他 Amazon Web Services 账户 中的角色(而不是您的集群所在账户中的角色)代入该角色户。那么,请确保指定其他账户中的 Amazon Web Services 账户 和角色。有关更多信息,请参阅跨账户 IAM 权限

      kubectl annotate serviceaccount -n $namespace $service_account eks.amazonaws.com.cn/role-arn=arn:aws:iam::$account_id:role/my-role
  3. 确认角色和服务账户配置正确。

    1. 确认 IAM 角色的信任策略配置正确。

      aws iam get-role --role-name my-role --query Role.AssumeRolePolicyDocument

      输出示例如下。

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.region-code.amazonaws.com.cn/id/EXAMPLED539D4633E53DE1B71EXAMPLE" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.region-code.amazonaws.com.cn/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:default:my-service-account", "oidc.eks.region-code.amazonaws.com.cn/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com" } } } ] }
    2. 确认您在上一步中附加到角色的策略已附加到该角色。

      aws iam list-attached-role-policies --role-name my-role --query AttachedPolicies[].PolicyArn --output text

      输出示例如下。

      arn:aws:iam::111122223333:policy/my-policy
    3. 设置一个变量以存储要使用策略的 Amazon 资源名称(ARN)。将 my-policy 替换为要确认其权限的策略的名称。

      export policy_arn=arn:aws:iam::111122223333:policy/my-policy
    4. 查看该策略的默认版本。

      aws iam get-policy --policy-arn $policy_arn

      输出示例如下。

      { "Policy": { "PolicyName": "my-policy", "PolicyId": "EXAMPLEBIOWGLDEXAMPLE", "Arn": "arn:aws:iam::111122223333:policy/my-policy", "Path": "/", "DefaultVersionId": "v1", ... } }
    5. 查看策略内容以确保该策略包括您的 pod 所需的所有权限。如有必要,将以下命令中的 1 替换为上一个输出中返回的版本。

      aws iam get-policy-version --policy-arn $policy_arn --version-id v1

      输出示例如下。

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::my-pod-secrets-bucket" } ] }

      如果您在上一步中创建了示例策略,则您的输出与示例相同。如果您创建了其他策略,则与示例内容不同。

    6. 确认使用角色注释 Kubernetes 服务账户。

      kubectl describe serviceaccount my-service-account -n default

      输出示例如下。

      Name: my-service-account Namespace: default Annotations: eks.amazonaws.com.cn/role-arn: arn:aws:iam::111122223333:role/my-role Image pull secrets: <none> Mountable secrets: my-service-account-token-qqjfl Tokens: my-service-account-token-qqjfl ...
  4. (可选)配置服务账户的 Amazon Security Token Service 端点。Amazon 建议使用区域 Amazon STS 端点而不是全局端点。这可以减少延迟,提供内置冗余并提高会话令牌的有效性。

下一步

配置容器组(pod)以使用 Kubernetes 服务账户