如何對 Amazon EKS 中的 AWS SDK 工作負載的常見問題進行疑難排解?

3 分的閱讀內容
0

我使用了 AWS SDK 來開發 Amazon Elastic Kubernetes Service (Amazon EKS) 的容器應用程式。我嘗試呼叫 AWS 服務時,收到錯誤訊息。

解決方法

將使用 AWS SDK 的容器應用程式部署到 Amazon EKS 叢集時,您可能會收到下列其中一個錯誤訊息:

  • NoCredentialsError: 無法找到憑證
  • EndpointConnectionError
  • ClientError: 發生錯誤 (AccessDenied)
  • ClientError: 發生錯誤 (UnauthorizedOperation)

特定的錯誤訊息取決於您的應用程式使用的 AWS SDK 程式設計語言。請參閱下列疑難排解步驟,了解您的錯誤。

無法找到憑證

如果 Amazon EKS 無法找到 Pod 的憑證,則您會看到類似下列訊息的錯誤:

"File "/usr/local/lib/python2.7/site-packages/botocore/auth.py", line 315, in add_auth
raise NoCredentialsError
botocore.exceptions.NoCredentialsError: Unable to locate credentials"

您未設定 Pod 的憑證、未正確設定憑證或不支援 AWS SDK 版本時,就會發生此錯誤。

要解決此錯誤,請使用 AWS Identity and Access Management (IAM) 角色。一般而言,您可以在應用程式或使用 Amazon EC2 執行個體的角色,建立和分配 SDK 用戶端的 AWS 憑證。反之,將您的 Pod 設定為使用服務帳戶的 IAM 角色。建立 IAM 角色與 Kubernetes 服務帳戶的關聯,然後將 Pod 設定為使用服務帳戶。

**重要事項:**您的 Pod 容器必須使用透過 OpenID Connect Web 身分字符檔案支援擔任 IAM 角色的 AWS SDK 版本

無法連線至端點網址

如果您的 Pod 無法與 AWS 服務端點通訊,則您會看到類似下列訊息的錯誤:

"File "/usr/local/lib/python2.7/site-packages/botocore/retryhandler.py", line 359, in _check_caught_exception
raise caught_exception
botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL: "https://ec2.eu-west-1.amazonaws.com/"
botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL: "https://sts.eu-west-1.amazonaws.com/""

要解決此錯誤,對 DNS 問題進行疑難排解並確認以下幾點:

檢查 CoreDNS Pod 是否在叢集中執行

執行下列命令:

kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o wide

您將看到類似下列範例的輸出:

NAME                       READY   STATUS    RESTARTS   AGE   IP                NODE                                            NOMINATED NODE   READINESS GATES  
coredns-7f85bf9964-kz8lp   1/1     Running   0          15d   192.168.100.36    ip-192-168-101-156.eu-west-1.compute.internal   <none>           <none>  
coredns-7f85bf9964-wjxvb   1/1     Running   0          15d   192.168.135.215   ip-192-168-143-137.eu-west-1.compute.internal   <none>           <none>

請務必在 Amazon EKS 叢集執行有足夠容量的工作節點,以成功執行 CoreDNS Pod。

測試端點解析

確認您的 CoreDNS Pod 和應用程式 Pod 可以解析您要 Pod 呼叫的 AWS 服務端點。執行下列命令:

nslookup SERVICE_ENDPOINT  

nslookup ec2.eu-west-1.amazonaws.com  

nslookup ec2.amazonaws.com

**注意:**將 SERVICE_ENDPOINT 取代為錯誤訊息中列印的端點。

呼叫 AssumeRoleWithWebIdentity 作業時,發生錯誤 (AccessDenied)

如果您的 Pod 無法請求臨時安全憑證,則您會看到類似下列訊息的錯誤:

"File "/usr/local/lib/python3.11/site-packages/botocore/client.py", line 960, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation: Not authorized to perform sts:AssumeRoleWithWebIdentity"

要解決此錯誤,請完成下列步驟:

確認擔任的 IAM 角色

確認 Pod 擔任與叢集中存在的 Kubernetes 服務帳戶相關聯的 IAM 角色。否則,Pod 會擔任 Amazon EKS 節點 IAM 角色。要取得服務帳戶的 IAM 角色 ARN,請執行下列命令:

kubectl get serviceaccount -A  

kubectl describe serviceaccount serviceaccount_name -n namespace_name | grep -i arn

**注意:**將 serviceaccount_namenamespace_name 取代為您自己的值。

您將看到類似下列範例的輸出:

Annotations: eks.amazonaws.com/role-arn: arn:aws:iam::11112222333:role/AccessEC2role

簡化擦 CloudTrail 事件

確認哪個 IAM 身分被拒絕存取,以執行AssumeRoleWithWebIdentity actionView。為此,在 CloudTrail 主控台檢查 AWS CloudTrail 事件。

  1. 登入 CloudTrail 主控台
  2. 在導覽窗格中,選擇事件歷史記錄
  3. 查詢屬性下拉式功能表中,將唯讀選項變更為事件名稱
  4. 輸入事件名稱搜尋列中,輸入 AssumeRoleWithWebIdentity。檢查在內容窗格中顯示的事件清單。請參閱下列遭拒事件的範例:
{  
    "eventVersion": "1.08",  
    "userIdentity": {  
        "type": "WebIdentityUser",  
        "userName": "system:serviceaccount:serverless:aws-sdk"  
    },  
    "eventName": "AssumeRoleWithWebIdentity",  
    "errorCode": "AccessDenied",  
    "errorMessage": "An unknown error occurred",  
    "requestParameters": {  
        "roleArn": "arn:aws:iam::11112222333:role/AccessEC2role",  
        "roleSessionName": "botocore-session-1675698641"  
    }  
}

在此輸出中,roleArn 必須與您為 Pod 服務帳戶設定的 IAM 角色相同。
userName (system:serviceaccount:serverless:aws-sdk) 必須符合服務帳戶名稱及其命名空間。此名稱格式為 system:serviceaccount:namespace:serviceaccount_name

設定 Pod 的服務帳戶 IAM 角色

IAM 主控台中,使用正確的 IAM 信任政策聲明,設定 Pod 的服務帳戶 IAM 角色:

     {  
            "Effect": "Allow",  
            "Principal": {  
                "Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/oidc.eks.region_code.amazonaws.com/id/EXAMPLE11111122222333334444ABCD"  
            },  
            "Action": "sts:AssumeRoleWithWebIdentity",  
            "Condition": {  
                "StringEquals": {  
                    "oidc.eks.region_code.amazonaws.com/id/EXAMPLE11111122222333334444ABCD:sub": "system:serviceaccount:namespace_name:serviceaccount_name",  
                    "oidc.eks.region_code.amazonaws.com/id/EXAMPLE11111122222333334444ABCD:aud": "sts.amazonaws.com"  
                }  
            }  
    }     

**注意:**將 region_codeACCOUNT_IDEXAMPLE11111122222333334444ABCDserviceaccount_namenamespace_name 取代為您自己的值。

發生錯誤 (UnauthorizedOperation)

您為 Pod 的服務帳戶設定的 IAM 角色可能無權呼叫其他 AWS 服務。在此案例,您會看到類似下列訊息的錯誤:

File "/usr/local/lib/python3.11/site-packages/botocore/client.py", line 960, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation."

要解決此錯誤,請完成下列步驟:

  1. 確認 Pod 擔任與 Kubernetes 服務帳戶相關聯的 IAM 角色。為此,請參閱上一節的確認擔任的 IAM 角色。注意此步驟傳回的角色 ARN。
  2. 開啟 IAM 主控台。在導覽窗格中,選擇角色。然後,搜尋並選取步驟 1 的角色 ARN。
  3. 權限標籤下,將必要的 IAM 政策權限附加至 IAM 角色。

如需 Pod 範例,請參閱 GitHub 上的執行 AWS Python SDK 的範例 Pod 使用 Web 聯合身分供應商作為憑證供應商

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