如何對 Amazon EKS 中的 OIDC 提供者和 IRSA 進行疑難排解?

上次更新日期:2021 年 11 月 15 日

我的 Pod 無法使用 Amazon Elastic Kubernetes Service (Amazon EKS) 帳戶字符的 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

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 OIDC 提供者

檢查您的 IAM 角色有否連接必要的 IAM 政策和所需許可

1.    開啟 IAM 主控台

2.    在導覽窗格中,選擇 Roles (角色)

3.    選擇您要驗證的角色

4.    在 Permissions (許可) 標籤下,確認此角色是否已連接必要的政策。

確認已正確設定 IAM 角色信任關係

使用 AWS Management Console:

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 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_NAMEYOUR_NAMESPACE

範例輸出:

serviceAccountName: irsa

檢查環境變數和許可

在 Pod 的環境變數中尋找 AWS_ROLE_ARNAWS_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 Management Console,以建立 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"
...

此文章是否有幫助?


您是否需要帳單或技術支援?