跳至内容

如何对 Amazon EKS 中的 OIDC 提供商和 IRSA 问题进行故障排除?

4 分钟阅读
0

我的容器组无法通过 Amazon Elastic Kubernetes Service (Amazon EKS) AWS 账户令牌使用 AWS Identity and Access Management (IAM) 角色权限。

解决方案

**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

检查您的集群是否已有 IAM OIDC 提供商

如果 OpenID Connect (OIDC) 提供商不存在,则您会收到类似于以下内容的错误:

“WebIdentityErr: failed to retrieve credentials\ncaused by: InvalidIdentityToken: No OpenIDConnect provider found in your account for https://oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E\n\tstatus code: 400”

要检查您是否已有 IAM OIDC 提供商,请完成以下步骤:

  1. 要检查集群的 OIDC 提供商 URL,请运行以下 describe-cluster AWS CLI 命令:

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

    **注意:**请将 cluster_name 替换为您的集群名称。
    输出示例:

    https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E
  2. 要列出账户中的 IAM OIDC 提供商,请运行以下 list-open-id-connect-providers 命令:

    aws iam list-open-id-connect-providers | grep EXAMPLED539D4633E53DE1B716D3041E

    **注意:**请将 EXAMPLED539D4633E53DE1B716D3041E 替换为您从上一个命令中获取的 OIDC 提供商 URL。
    如果该命令返回输出,则说明您的集群已有提供商。如果命令未返回输出,则必须创建 IAM OIDC 提供商。输出示例:

    "Arn": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"

检查您的 IAM 角色是否具有所需的权限,以及是否附加了 IAM 策略

完成以下步骤:

  1. 打开 IAM 控制台
  2. 在导航窗格中,选择 Roles(角色)。
  3. 选择与您的 Kubernetes 服务账户关联的角色。
  4. 选择 Permissions(权限)选项卡。然后,检查附加到该角色的策略,确保其包含您的配置所需的权限。
  5. 选择 Trust relationships(信任关系)选项卡。然后,验证您的 IAM 策略的格式是否与以下 JSON 策略的格式相匹配:
    {  "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:SERVICE_ACCOUNT_NAMESPACE:SERVICE_ACCOUNT_NAME",
              "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com"
            }
          }
        }
      ]
    }
    或者,运行以下 get-role 命令以检查您的信任关系:
    aws iam get-role --role-name EKS-IRSA
    **注意:**请将 EKS-IRSA 替换为您的服务账户 IAM 角色 (IRSA) 的角色名称。
    输出示例:
    {  "Role": {
        "Path": "/",
        "RoleName": "EKS-IRSA",
        "RoleId": "AROAQ55NEXAMPLELOEISVX",
        "Arn": "arn:aws:iam::ACCOUNT_ID:role/EKS-IRSA",
        "CreateDate": "2021-04-22T06:39:21+00:00",
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
              },
              "Action": "sts:AssumeRoleWithWebIdentity",
              "Condition": {
                "StringEquals": {
                  "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:aud": "sts.amazonaws.com",
                  "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:SERVICE_ACCOUNT_NAMESPACE:SERVICE_ACCOUNT_NAME"
                }
              }
            }
          ]
        },
        "MaxSessionDuration": 3600,
        "RoleLastUsed": {
          "LastUsedDate": "2021-04-22T07:01:15+00:00",
          "Region": "AWS_REGION"
        }
      }
    }
    在输出 JSON 中,检查 AssumeRolePolicyDocument 部分以验证信任关系策略。
  6. (可选)将角色的信任关系更新为正确的 AWS 区域、Kubernetes 服务账户名称或 Kubernetes 命名空间。

检查您是否已创建服务账户

要检查服务账户是否存在,请运行以下命令:

kubectl get sa -n YOUR_NAMESPACE

**注意:**用您的 Kubernetes 命名空间替换 YOUR_NAMESPACE

输出示例:

NAME      SECRETS   AGEdefault   1         28d
irsa      1         66m

确保输出中列出了您的服务账户。如果您没有服务账户,请参阅 Kubernetes 网站上的为容器组配置服务账户

验证服务账户的 IAM 角色注释是否正确

要验证您的服务账户是否具有正确的 IAM 角色注释,请运行以下命令:

kubectl describe sa irsa -n YOUR_NAMESPACE

**注意:**将 irsa 替换为您的 Kubernetes 服务账户名,将 YOUR_NAMESPACE 替换为您的Kubernetes 命名空间。

输出示例:

Name:                irsa
Namespace:           default
Labels:              none
Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::ACCOUNT_ID:role/IAM_ROLE_NAME
Image pull secrets:  none
Mountable secrets:   irsa-token-v5rtc
Tokens:              irsa-token-v5rtc
Events:              none

检查 Annotations(注释)以确保 IAM 角色正确无误。如果不正确,请运行以下命令编辑服务账户:

kubectl edit sa -n NAMESPACE

**注意:**请将 NAMESPACE 替换为您的命名空间。

然后,使用正确的 IAM 角色更新 Annotations(注释)的值。

验证您在容器组中是否正确指定了 serviceAccountName

要验证 serviceAccountName,请运行以下命令:

kubectl get pod POD_NAME  -o yaml -n YOUR_NAMESPACE| grep -i serviceAccountName:

**注意:**请将 POD_NAME 替换为您的 Kubernetes 容器组,将 YOUR_NAMESPACE 替换为您的命名空间。

输出示例:

serviceAccountName: irsa

如果输出中的值是错误的服务账户名称,请使用正确的名称编辑部署清单。然后,重新部署部署清单

检查环境变量和权限

要检查容器组的环境变量,请运行以下命令:

kubectl -n YOUR_NAMESPACE exec -it POD_NAME -- env | grep AWS

输出示例:

AWS_REGION=ap-southeast-2
AWS_ROLE_ARN=arn:aws:iam::111122223333:role/EKS-IRSA
AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
AWS_DEFAULT_REGION=ap-southeast-2

确保输出中列出了您的服务账户。如果您没有服务账户,请参阅 Kubernetes 网站上的为容器组配置服务账户

验证应用程序是否使用受支持的 AWS SDK

您的 AWS SDK 版本必须高于或等于您的 AWS SDK 所需的版本

重新创建容器组

如果您在应用 IRSA 之前创建了容器组,请运行以下命令重新创建容器组:

kubectl rollout restart deploy nginx

输出示例:

deployment.apps/nginx restarted

对于进程守护程序集或有状态集部署,请运行以下命令:

kubectl rollout restart deploy DEPLOYMENT_NAME

如果您只创建了一个容器组,则必须删除该容器组并重新创建。完成以下步骤:

  1. 要删除容器组,请运行以下命令:
    kubectl delete pod POD_NAME
    **注意:**请将 POD_NAME 替换为您的容器组的名称。
  2. 要重新创建容器组,请运行以下命令:
    kubectl apply -f SPEC_FILE
    **注意:**将 SPEC_FILE 替换为您的 Kubernetes 清单文件路径和文件名。

确认受众是正确的

如果您创建的 OIDC 提供商的受众不正确,则会收到以下错误:

“Error - An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Incorrect token audience”

要检查集群的 IAM 身份提供者,请运行以下 get-open-id-connect-provider 命令:

aws iam get-open-id-connect-provider --open-id-connect-provider-arn arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E

**注意:**请将 ACCOUNT_ID 替换为您的账户 ID,将 AWS_REGION 替换为您的区域,将 EXAMPLED539D4633E53DE1B716D3041E 替换为您的 OIDC 提供商 URL。

输出示例:

{  "Url": "oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E",
  "ClientIDList": [
    "sts.amazonaws.com"
  ],
  "ThumbprintList": [
    "9e99a48a9960b14926bb7f3b02e22da2b0ab7280"
  ],
  "CreateDate": "2021-01-21T04:29:09.788000+00:00",
  "Tags": []
}

在输出中,确保 ClientIDListsts.amazonaws.com。如果不是,请向该角色添加一个身份提供者,然后在 Audience(受众)中输入 sts.amazonaws.com

验证您是否配置了正确的指纹

如果您在 IAM OIDC 中配置的指纹不正确,则会收到以下错误:

“failed to retrieve credentials caused by: InvalidIdentityToken: OpenIDConnect provider's HTTPS certificate doesn't match configured thumbprint”

要自动配置正确的指纹,请使用 eksctl 或 Amazon EKS 控制台创建 IAM 身份提供者。有关获取指纹的其他方法,请参阅获取 OpenID Connect 身份提供者的指纹

(仅限 AWS 中国区域)检查 AWS_DEFAULT_REGION 环境变量

要将应用了 IRSA 的容器组或进程守护程序集部署到 AWS 中国区域集群,必须在容器组规范中设置 AWS_DEFAULT_REGION。如果未设置 AWS_DEFAULT_REGION 环境变量,您可能会收到有关容器组或进程守护程序集的以下错误:

“An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid”

要将 AWS_DEFAULT_REGION 环境变量添加到您的容器组或进程守护程序集规范中,请创建一个类似于以下示例的部署清单:

apiVersion: apps/v1kind: Deployment
metadata:
  name: my-app
spec:
  template:
    metadata:
      labels:
        app: my-app
    spec:
      serviceAccountName: my-app
      containers:
      - name: my-app
        image: my-app:latest
        env:
        - name: AWS_DEFAULT_REGION
          value: "AWS_REGION"
...

或者,运行以下命令以设置环境变量:

kubectl set env deployment deployment_name AWS_DEFAULT_REGION=example_region -n NAMESPACE"

**注意:**请将 deployment_name 替换为您的部署名称,将 example_region 替换为 AWS 中国区域,将 NAMESPACE 替换为您的命名空间。

AWS 官方已更新 7 个月前