如何排查 Amazon EKS 中的 OIDC 提供程序和 IRSA 问题?
我的容器组(pod)无法将 AWS Identity and Access Management(IAM)角色权限与 Amazon Elastic Kubernetes Service(Amazon EKS)账户令牌结合使用。
简短描述
要解决 Amazon EKS 中 OpenID Connect (OIDC) 提供程序和服务账户的 IAM 角色 (IRSA) 问题,请完成以下部分之一中的步骤:
- 检查您的集群是否存在现有的 IAM OIDC 提供程序
- 检查您的 IAM 角色是否附加了具有所需权限的必要 IAM policy
- 验证是否正确设置 IAM 角色信任关系
- 核实是否创建了服务账户
- 验证服务账户是否具有正确的 IAM 角色注释
- 验证是否在容器组(pod)中正确指定了 serviceAccountName
- 检查环境变量和权限
- 验证应用程序使用受支持的 AWS 开发工具包
- 检查 Pod 用户和组
- 重新创建 Pod
- 验证受众是否正确
- 验证配置的指纹是否正确
- 对于 AWS 中国区域,请检查 AWS_DEFAULT_REGION 环境变量
解决方法
检查您的集群是否存在现有的 IAM 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(WebIdentityErr:无法检索凭证\n原因是:InvalidIdentityToken:您的账户中找不到 OpenIDConnect 提供程序 https://oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E\n\t状态码:400)”
1. 检查集群的 OIDC 提供程序 URL:
$ aws eks describe-cluster --name cluster_name --query "cluster.identity.oidc.issuer" --output text
请参见以下示例输出:
https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E
2. 列出您账户中的 IAM OIDC 提供程序。将 EXAMPLED539D4633E53DE1B716D3041E(包括 <>)替换为从上一个命令返回的值:
aws iam list-open-id-connect-providers | grep EXAMPLED539D4633E53DE1B716D3041E
请参见以下示例输出:
"Arn": "arn:aws:iam::111122223333:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
如果前面的命令返回输出,则表明您已有集群的提供程序。如果命令没有返回输出,则必须创建 IAM OIDC 提供程序。
检查您的 IAM 角色是否附加了具有所需权限的必要 IAM policy
1. 打开 IAM 控制台。
2. 在导航窗格中,选择角色。
3. 选择要验证的角色。
4. 在权限选项卡下,验证此角色是否附加了所需的策略。
验证是否正确设置 IAM 角色信任关系
使用 AWS 管理控制台:
1. 打开 IAM 控制台。
2. 在导航窗格中,选择角色。
3. 选择要检查的角色。
4. 选择 Trust Relationships(信任关系)选项卡以验证策略的格式是否与以下 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" } } } ] }
要验证信任关系,请在 AWS 命令行界面(AWS CLI)中使用您的角色名称运行以下命令:
$ aws iam get-role --role-name EKS-IRSA
**注意:**将 EKS-IRSA 替换为您的 IAM 角色名称。
在输出 JSON 中,查找 AssumeRolePolicyDocument 部分。
请参见以下示例输出:
{ "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" } } }
**注意:**检查您是否指定了正确的 AWS 区域、Kubernetes 服务账户名称和 Kubernetes 命名空间。
核实是否创建了服务账户
使用以下命令:
$ kubectl get sa -n YOUR_NAMESPACE
**注意:**请将 YOUR_NAMESPACE 替换为您的 Kubernetes 命名空间。
请参见以下示例输出:
NAME SECRETS AGE default 1 28d irsa 1 66m
如果您没有服务账户,请参阅为容器组(pod)配置服务账户(从 Kubernetes 网站)。
验证服务账户是否具有正确的 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
验证是否在容器组(pod)中正确指定了 serviceAccountName
使用以下命令:
$ kubectl get pod POD_NAME -o yaml -n YOUR_NAMESPACE| grep -i serviceAccountName:
**注意:**将 POD_NAME 和 YOUR_NAMESPACE 替换为您的 Kubernetes 容器组(pod)和命名空间。
请参见以下示例输出:
serviceAccountName: irsa
检查环境变量和权限
在容器组(pod)的环境变量中查找 AWS_ROLE_ARN 和 AWS_WEB_IDENTITY_TOKEN_FILE:
$ 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
验证应用程序使用受支持的 AWS 开发工具包
SDK 版本必须大于或等于以下值:
Java (Version 2) — 2.10.11 Java — 1.11.704 Go — 1.23.13 Python (Boto3) — 1.9.220 Python (botocore) — 1.12.200 AWS CLI — 1.16.232 Node — 3.15.0 Ruby — 2.11.345 C++ — 1.7.174 .NET — 3.3.659.1 PHP — 3.110.7
要查看支持的最新开发工具包版本,请参阅使用支持的 AWS 开发工具包。
检查 Pod 用户和组
使用以下命令:
$ kubectl exec -it POD_NAME -- id uid=0(root) gid=0(root) groups=0(root)
注意:默认情况下,只有以根身份运行的容器才具有读取 Web 身份令牌文件的适当文件系统权限。
如果您的容器没有以根身份运行,那么您可能会收到以下错误:
Error: PermissionError: [Errno 13] Permission denied: '/var/run/secrets/eks.amazonaws.com/serviceaccount/token
-或者-
WebIdentityErr: failed fetching WebIdentity token: \ncaused by: WebIdentityErr: unable to read file at /var/run/secrets/eks.amazonaws.com/serviceaccount/token\ncaused by: open /var/run/secrets/eks.amazonaws.com/serviceaccount/token: permission denied
要提供适当的文件系统权限,请确保您的容器以根身份运行。对于 1.18 或更低版本的集群,请为清单中的容器提供以下安全环境:
apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: template: metadata: labels: app: my-app spec: serviceAccountName: my-app containers: - name: my-app image: my-app:latest securityContext: fsGroup: 1337 ...
**注意:**fsGroup ID 是任意值。您可以选择任何有效的组 ID。集群 1.19 或更高版本不需要上述安全环境设置。
重新创建 Pod
如果您在应用 IRSA 之前创建了容器组(pod),那么请重新创建容器组(pod)。
请参阅以下示例命令:
$ kubectl rollout restart deploy nginx
请参见以下示例输出:
deployment.apps/nginx restarted
对于进程守护程序集或有状态部署,可以使用以下命令:
$ kubectl rollout restart deploy DEPLOYMENT_NAME
如果仅创建了一个容器组(pod),那么必须删除该容器组(pod)并重新创建。
要删除该容器组(pod),请参阅以下示例命令:
$ kubectl delete pod POD_NAME
要重新创建容器组(pod),请参阅以下示例命令:
$ kubectl apply -f SPEC_FILE
**注意:**将 SPEC_FILE 替换为您的 Kubernetes 清单文件路径和文件名。
验证受众是否正确
如果您使用错误的受众创建了 OIDC 提供程序,则会收到以下错误:
Error - An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Incorrect token audience
检查您集群的 IAM 身份提供程序。您的 ClientIDList 是 sts.amazonaws.com:
$ 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
请参见以下示例输出:
{ "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": [] }
验证配置的指纹是否正确
如果在 IAM OIDC 中配置的指纹不正确,您可能会收到以下错误消息:
failed to retrieve credentials caused by: InvalidIdentityToken: OpenIDConnect provider's HTTPS certificate doesn't match configured thumbprint
要自动配置正确的指纹,请使用 eksctl 或 AWS 管理控制台创建 IAM 身份提供程序。有关获取指纹的其他方法,请参阅为 OpenID Connect 身份提供程序获取指纹。
对于 AWS 中国区域,请检查 AWS_DEFAULT_REGION 环境变量
如果您将 IRSA 用于部署到 AWS 中国区域中集群的 Pod 或守护进程,请在 Pod 规范中设置 AWS_DEFAULT_REGION 环境变量。如果未执行此操作,Pod 或守护进程可能会收到以下错误:
An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid
使用以下示例将 AWS_DEFAULT_REGION 环境变量添加到 Pod 或守护进程规范中:
apiVersion: apps/v1 kind: 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" ...
相关内容
- AWS 官方已更新 2 个月前
- AWS 官方已更新 1 年前