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

5 分的閱讀內容
0

我的 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_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 管理主控台,以建立 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"
...

AWS 官方
AWS 官方已更新 2 年前