为 Kubernetes 服务账户分配 IAM 角色 - Amazon EKS

帮助改进此页面

想为本用户指南做出贡献? 选择位于每个页面右侧窗格中的在 GitHub 上编辑此页面链接。您的贡献有助于我们的用户指南为每个人提供更充分的参考。

为 Kubernetes 服务账户分配 IAM 角色

本主题介绍如何配置 Kubernetes 服务账户,以使用 AWS Identity and Access Management (IAM)角色。然后,配置为使用服务账户的任何Pods都可以访问该角色有权访问的任何 AWS 服务。

先决条件

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

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

  • 在您的设备或 AWS CloudShell 上安装和配置 AWS 命令行界面(AWS CLI)的版本 2.12.3 或更高版本,或版本 1.27.160 或更高版本。要查看当前版本,请使用 aws --version | cut -d / -f2 | cut -d ' ' -f1。软件包管理器(如 yumapt-get 或适用于 macOS 的 Homebrew)通常比 AWS CLI 的最新版本落后几个版本。要安装最新版本,请参阅《AWS 命令行界面用户指南》中的安装使用 aws configure 快速配置。AWS CloudShell 中安装的 AWS CLI 版本也可能比最新版本落后几个版本。要对其进行更新,请参阅《AWS CloudShell 用户指南》中的将 AWS CLI 安装到您的主目录

  • 您的设备或 AWS CloudShell 上安装了 kubectl 命令行工具。该版本可以与集群的 Kubernetes 版本相同,或者最多早于或晚于该版本一个次要版本。例如,如果您的集群版本为 1.29,则可以将 kubectl1.281.291.30 版本与之配合使用。要安装或升级 kubectl,请参阅 设置 kubectl 和 eksctl

  • 包含集群配置的现有 kubectl config 文件。要创建 kubectl config 文件,请参阅 通过创建 kubeconfig 文件将 kubectl 连接到 EKS 集群

步骤 1:创建 IAM 策略

要将现有 IAM 策略关联到您的 IAM 角色,请跳至下一步。

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

  2. 创建一个文件,其包含您希望那您的Pods访问的 AWS 服务所需的权限。有关所有 AWS 服务的所有操作的列表,请参阅服务授权参考

    您可以运行以下命令创建一个示例策略文件,以实现对 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
  3. 创建 IAM 策略。

    aws iam create-policy --policy-name my-policy --policy-document file://my-policy.json

步骤 2:创建和关联 IAM 角色

创建 IAM 角色并将其与 Kubernetes 服务账户关联。您可以使用 eksctl 或 AWS CLI。

创建和关联角色(eksctl)

您的设备或 AWS CloudShell 上安装 0.199.0 版或更高版本的 eksctl 命令行工具。要安装或更新 eksctl,请参阅 eksctl 文档中的 Installation

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

创建和关联角色(AWS CLI)

如果您有要分派 IAM 角色的现有 Kubernetes 服务账户,则您可以跳过此步骤。

  1. 创建 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
  2. 使用以下命令将 AWS 账户 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 条件中添加多个条目,以允许多个服务账户或命名空间分派角色。要允许其它 AWS 账户中的角色(而不是您的集群所在账户中的角色)分派该角色户,请参阅使用 IRSA 对另一个账户进行身份验证获取更多信息。

    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 策略附加到您的角色。将 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 角色的名称。假设您在上一步中允许其它 AWS 账户中的角色(而不是您的集群所在账户中的角色)分派该角色户。那么,请确保指定其它账户中的 AWS 账户和角色。有关更多信息,请参阅使用 IRSA 对另一个账户进行身份验证

    kubectl annotate serviceaccount -n $namespace $service_account eks.amazonaws.com/role-arn=arn:aws:iam::$account_id:role/my-role
  9. (可选)为服务账户配置 AWS Security Token Service 端点为服务账户配置 AWS Security Token Service 端点。AWS 建议使用区域级 AWS STS 端点而不是全局端点。这可以减少延迟,提供内置冗余并提高会话令牌的有效性。

步骤 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/id/EXAMPLED539D4633E53DE1B71EXAMPLE" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.region-code.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:default:my-service-account", "oidc.eks.region-code.amazonaws.com/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/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 [...]

后续步骤