为什么不能在我的 Amazon EKS 容器组中使用服务账户的 IAM 角色?

上次更新时间:2021 年 10 月 5 日

我尝试使用一个服务账户的 AWS Identity and Access Management(IAM)角色。但是我的 Amazon Elastic Kubernetes Service(Amazon EKS)容器组(pod)未能代入分配的 IAM 角色。我收到了授权错误消息。或者,我的容器组尝试使用分配给 Amazon EKS 节点的默认 IAM 角色,而不是分配给我的容器组的 IAM 角色。

简短描述

要排查使用服务账户的 IAM 角色功能时出现的问题,请尝试以下操作:

  • 验证您的 Amazon EKS 集群是否有 IAM OpenID Connect(OIDC)身份提供商
  • 验证您的 IAM 角色策略和信任策略配置
  • 确认您的服务账户存在且具有格式正确的 IAM 角色 ARN 注释
  • 使用测试容器组验证服务账户工作正常

注意:如果您在运行 AWS Command Line Interface(AWS CLI)命令时遇到错误,请确保您使用的是最新版本的 AWS CLI

解决方法

验证您的 Amazon EKS 集群是否有 IAM OIDC 身份提供商

如果您还没有此身份提供商,则为您的集群创建一个 IAM OIDC 提供商。您必须具有集群的 OIDC 身份提供商才能使用服务账户的 IAM 角色。

然后验证 OIDC 身份提供商的配置是否正确:

1.    打开 IAM 控制台,然后从导航窗格中选择 Identity providers(身份提供商)。

2.    在 Provider(提供商)列中,找到并记下 OIDC 提供商 URL。

3.    在单独的选项卡或窗口中,打开 Amazon EKS 控制台,然后从导航窗格中选择 Clusters(集群)。

4.    选择您的集群,然后选择 Configuration(配置)选项卡。

5.    在 Details(详细信息)部分中,记下 OpenID Connect provider URL(OpenID Connect 提供商 URL)属性的值。

6.    验证 Amazon EKS 控制台中的 OIDC 提供商 URL(第 5 步)是否与 IAM 控制台中的 OIDC 提供商 URL 匹配(第 2 步)。

如果 Amazon EKS 集群的 OIDC 提供商 URL 与 IAM 控制台中的任何 OIDC 提供商 URL 都不匹配,则必须创建一个新的 IAM OIDC 提供商

验证您的 IAM 角色策略和信任策略配置

您的 IAM 角色可能不具有您希望分配给该角色的全部权限。如果您使用 AWS 管理控制台或 AWS CLI 创建了 IAM 角色,则您的 IAM 角色的信任关系策略也可能存在语法错误。

要验证您的 IAM 角色策略并检查信任策略中是否存在语法错误,请执行以下操作:

1.    打开 IAM 控制台

2.    在导航窗格中,选择 Roles(角色),然后选择您的角色。

3.    选择角色页面上的 Permissions(权限)选项卡,然后验证是否已将所有需要的权限分配给该角色。

4.    选择 Trust Relationships(信任关系)选项卡,然后选择 Edit trust relationship(编辑信任关系)。

5.    在信任关系的策略文档中,验证策略的格式是否与以下 JSON 策略的格式一致:

  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::your-account-id:oidc-provider/oidc.eks.your-region-code.amazonaws.com/id/EXAMPLE_OIDC_IDENTIFIER"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.your-region-code.amazonaws.com/id/EXAMPLE_OIDC_IDENTIFIER:sub": "system:serviceaccount:your-namespace:your-service-account"
        }
      }
    }
  ]
}

在上述 JSON 策略中,查看 Federated 属性行和 StringEquals 属性行的格式。在 Federated 行中,确认您的 AWS 区域代码(your-region-code)、账户 ID(your-account-id)和唯一 OIDC 标识符(EXAMPLE_OIDC_IDENTIFIER)的格式正确。在 StringEquals 行中,确认您的区域代码(your-region-code)、OIDC 唯一标识符(EXAMPLE_OIDC_IDENTIFIER)、Kubernetes 命名空间(your-namespace)和 Kubernetes 服务账户名称(your-namespace)的格式正确。

6.    如果要编辑策略文档以更正格式错误,请选择 Update Trust Policy(更新信任策略)。

确认您的服务账户存在且具有格式正确的 IAM 角色 ARN 注释

1.    确认您的 Kubernetes 服务账户存在:

$ kubectl get serviceaccount YOUR_ACCOUNT_NAME -n YOUR_NAMESPACE -o yaml

注意:请将 YOUR_ACCOUNT_NAME 替换为您的账户名称。将 YOUR_NAMESPACE 替换为您的命名空间。

如果上述命令没有返回服务账户名称,则创建一个服务账户(从 Kubernetes 网站)。

2.    确认您的服务账户具有您期望的名称,并且其 role-arn 注释的格式正确。例如:

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::012345678912:role/my-example-iam-role
  name: my-example-serviceaccount
  namespace: my-test-namespace

使用测试容器组验证服务账户工作正常

您可以通过运行测试容器组来验证服务账户是否正常工作。然后检查该容器组是否可以正确挂载环境变量并可以代入指定的 IAM 角色。

注意:即使服务账户的 IAM 角色功能正常运行,您也可能会遇到与应用程序凭证相关的问题。即使您的容器组具有正确的环境变量,您也可能会遇到这个问题。为防止出现此问题,您可以使用 AWS CLI 容器镜像进行验证。

1.    创建一个名为 awscli-pod.yaml 的本地 YAML 文件。例如:

apiVersion: v1
kind: Pod
metadata:
  name: awscli
  labels:
    app: awscli
spec:
  serviceAccountName: YOUR_SERVICE_ACCOUNT
  containers:
  - image: amazon/aws-cli
    command:
      - "sleep"
      - "604800"
    imagePullPolicy: IfNotPresent
    name: awscli
  restartPolicy: Always

注意:请将 YOUR_SERVICE_ACCOUNT 替换为您的 Kubernetes 服务账户名称。

2.    在您的命名空间中创建测试容器组(从该 YAML 文件):

$ kubectl apply -f ./awscli-pod.yaml -n YOUR_NAMESPACE

注意:YOUR_NAMESPACE 替换为您的命名空间。

3.    确认 awscli 容器组具有正确的环境变量

$ kubectl exec -n YOUR_NAMESPACE awscli env | grep AWS

输出:

AWS_ROLE_ARN=arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME
AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token

4.    确认测试容器组使用的是正确的 IAM 角色:

$ kubectl exec -it awscli -n YOUR_NAMESPACE -- aws sts get-caller-identity

输出:

{
    "UserId": "REDACTEDY471234567890:botocore-session-1632772568",
    "Account": "012345678912",
    "Arn": "arn:aws:sts::012345678912:assumed-role/your-iam-role/botocore-session-1632772568"
}

记下在第 4 步的命令输出中收到的 Arn 值,包括 IAM 角色名称(your-iam-role)。

5.    验证 IAM 角色后删除 awscli 容器组:

$ kubectl delete -f ./awscli-pod.yaml -n YOUR_NAMESPACE

如果 awscli 容器组显示正确的 IAM 角色,则表示服务账户的 IAM 角色功能正常工作。

上述步骤确认 IAM 令牌已正确挂载到容器中。如果您的应用程序仍然无法正确使用令牌文件,则可能存在应用程序或 SDK 级别的问题。此问题可能与应用程序如何摄取 AWS 凭证有关。有关更多信息,请参阅使用默认凭证提供程序链凭证(Boto3 网站)。


这篇文章对您有帮助吗?


您是否需要账单或技术支持?