如何對 Amazon EKS 中的 OIDC 提供者和 IRSA 進行疑難排解?
我的 Pod 無法使用 Amazon Elastic Kubernetes Service (Amazon EKS) 帳戶字符的 AWS Identity and Access Management (IAM) 角色許可。
簡短說明
若要對 Amazon EKS 中的 OpenID Connect (OIDC) 提供者和服務帳戶的 IAM 角色 (IRSA) 進行疑難排解,請完成下列其中一個章節中的步驟:
- 檢查叢集是否擁有現有的 IAM OIDC 提供者
- 檢查您的 IAM 角色有否連接必要的 IAM 政策和所需許可
- 確認已正確設定 IAM 角色信任關係
- 檢查您是否已建立服務帳戶
- 確認服務帳戶具有正確的 IAM 角色註解
- 確認您已在 Pod 中正確指定 serviceAccountName
- 檢查環境變數和許可
- 確認應用程式使用支援的 AWS SDK
- 檢查 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:在您的帳戶中找不到開放式連接提供者 https://oidc.eks.eu-west-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E\n\tstatus 程式碼: 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 政策和所需許可
1. 開啟 IAM 主控台。
2. 在導覽窗格中,選擇 Roles (角色)。
3. 選擇您要驗證的角色。
4. 在 Permissions (許可) 標籤下,確認此角色是否已連接必要的政策。
確認已正確設定 IAM 角色信任關係
使用 AWS 管理主控台:
1. 開啟 IAM 主控台。
2. 在導覽窗格中,選擇 Roles (角色)。
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 Command Line Interface (AWS CLI)使用您的角色名稱執行以下命令:
$ aws iam get-role --role-name EKS-IRSA
**注意:**請以您的 IAM 角色名稱取代 EKS-IRSA。
在輸出 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
**注意:**請以您的 Kubernetes 命名空間取代 YOUR_NAMESPACE。
請參閱以下範例輸出:
NAME SECRETS AGE default 1 28d irsa 1 66m
如果您沒有服務帳戶,請參閱設定 Pod 的服務帳戶 (來自 Kubernetes 網站)。
確認服務帳戶具有正確的 IAM 角色註解
執行以下命令:
$ kubectl describe sa irsa -n YOUR_NAMESPACE
**注意:**請以您的 Kubernetes 服務帳戶名稱取代 irsa。以您的 Kubernetes 命名空間取代 YOUR_NAMESPACE。
請參閱以下範例輸出:
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:
**注意:**請以您的 Kubernetes Pod 和命名空間取代 POD_NAME 和 YOUR_NAMESPACE。
請參閱以下範例輸出:
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
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
若要檢查支援的最新 SDK 版本,請參閱使用支援的 AWS SDK。
檢查 Pod 使用者和群組
執行以下命令:
$ kubectl exec -it POD_NAME -- id uid=0(root) gid=0(root) groups=0(root)
**注意:**根據預設,只有以 root 身分運行的容器具有適當的檔案系統許可,可以讀取 Web 身分字符檔案。
如果您的容器並非以 root 身分運行,您可能會收到以下錯誤訊息:
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
若要提供適當的檔案系統許可,請確定您的容器是以 root 身分運行。如果使用叢集 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
針對 DaemonSet 或 StatefulSet 部署,您可以使用以下命令:
$ kubectl rollout restart deploy DEPLOYMENT_NAME
如果您只建立了一個 Pod,您必須刪除和重新建立 Pod。
請參閱下列範例命令以刪除 Pod:
$ kubectl delete pod POD_NAME
請參閱下列範例命令以重新建立 Pod:
$ kubectl apply -f SPEC_FILE
**注意:**請以您的 Kubernetes 清單檔案的檔案路徑及檔案名稱取代 SPEC_FILE。
確認對象是否正確
如果您建立 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 或 DaemonSet,請在 Pod 規格中設定 AWS_DEFAULT_REGION 的環境變數。否則,Pod 或 DaemonSet 可能會收到下列錯誤訊息:
An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid
使用下列範例,將 AWS_DEFAULT_REGION 的環境變數新增至 Pod 或 DaemonSet 規格:
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" ...
相關內容
- 已提問 1 年前lg...
- 已提問 8 個月前lg...
- 已提問 8 個月前lg...
- 已提問 1 年前lg...
- 已提問 8 個月前lg...
- AWS 官方已更新 2 個月前
- AWS 官方已更新 1 年前
- AWS 官方已更新 1 年前