跳至內容

如何解決 CloudWatch 代理程式和 EKS Pod 身分識別代理程式 Pod 的 CrashLoopBackOff 狀態?

5 分的閱讀內容
0

我的 Amazon Elastic Kubernetes Service (Amazon EKS) 叢集的 Amazon CloudWatch 代理程式或 Amazon EKS Pod 身分識別代理程式 Pod 卡在 CrashLoopBackOff 狀態。

解決方法

**注意:**如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤訊息,請參閱對 AWS CLI 錯誤進行疑難排解。此外,請確定您使用的是最新的 AWS CLI 版本

檢查日誌

首先,請檢查 CloudWatch 代理程式和 EKS Pod 身分識別代理程式日誌,以收集有關該問題的資訊。

若要檢查 CloudWatch 代理程式日誌,請執行下列命令:

kubectl logs cloudwatch-agent-pod-name -n namespace

**注意:**將 cloudwatch-agent-pod-name 替換為您的 CloudWatch 代理程式 Pod 名稱,將 namespace 替換為您的命名空間名稱。

若要檢查 EKS Pod 身分識別代理程式日誌,請執行下列命令:

kubectl logs pod-identity-agent-pod-name -n namespace

**注意:**將 pod-identity-agent-pod-name 替換為您的 EKS Pod 身分識別代理程式 Pod 名稱,將 namespace 替換為您的命名空間名稱。

在命令輸出中,尋找導致 Pod 當機原因的錯誤訊息,例如權限問題、網路問題或設定問題。

對 CloudWatch 代理程式權限問題進行疑難排解

無法建立提供者錯誤

您必須使用 AWS Identity and Access Management (IAM) 服務 AWS 帳戶角色,才能讓 Amazon EKS 工作節點將指標和日誌傳送到 CloudWatch。如果 IAM 角色缺失,或在所需的 amazon-cloudwatch 命名空間中設定不正確,那麼您匯收到以下錯誤:

「Error: cannot create provider: failed to retrieve credentials: failed to assume role」

若要對此問題進行疑難排解,請使用 cloudwatch-agent 名稱建立服務帳戶角色

若要建立自訂服務帳戶角色,請執行下列命令:

eksctl create iamserviceaccount \
--cluster cluster-name \
--namespace amazon-cloudwatch \
--name service-account-name \
--attach-policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy \
--override-existing-serviceaccounts \
--approve

**注意:**將 cluster-name 替換為您的 Amazon EKS 叢集名稱,將 service-account-name 替換為自訂服務帳戶名稱。

然後,為 CloudWatch 代理程式建立 ConfigMap。如果您使用自訂服務帳戶角色,請將 cloudwatch-agent 替換為服務帳戶角色名稱。

Not authorized to perform: sts:AssumeRole 錯誤

如果 CloudWatch 代理程式使用的服務帳戶角色無法進行驗證,您將收到下列其中一個錯誤:

「Error: AccessDenied: User: arn:aws:sts::[Account-ID]:assumed-role/[Role-Name]/[Session-Name] is not authorized to perform: sts:AssumeRole on resource [Role-ARN]」

-或-

「Error: AccessDenied: Not authorized to perform sts:AssumeRole」

請確定您已將 CloudWatchAgentServerPolicy 政策附加到服務帳戶角色。若要識別驗證問題,請檢查 AWS CloudTrail 中的 PutLogEventsDescribeLogStreams 事件。請確定您在部署 YAML 檔案中使用 cloudwatch-agent 服務帳戶或正確的自訂服務帳戶名稱。

若要檢查服務帳戶組態,請執行下列命令:

kubectl get serviceaccount cloudwatch-agent -n amazon-cloudwatch -o yaml

在輸出中,請確定 eks.amazonaws.com/role-arn 中繼資料類似於下列範例:

metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::AWS_ACCOUNT_ID:role/role-name

CloudWatch 代理程式的服務帳戶必須具有下列規則:

rules:
  - apiGroups: [""]
    resources: ["pods", "nodes", "endpoints"]
    verbs: ["list", "watch"]
  - apiGroups: [ "" ]
    resources: [ "services" ]
    verbs: [ "list", "watch" ]
  - apiGroups: ["apps"]
    resources: ["replicasets", "daemonsets", "deployments", "statefulsets"]
    verbs: ["list", "watch"]
  - apiGroups: ["batch"]
    resources: ["jobs"]
    verbs: ["list", "watch"]
  - apiGroups: [""]
    resources: ["nodes/proxy"]
    verbs: ["get"]
  - apiGroups: [""]
    resources: ["nodes/stats", "configmaps", "events"]
    verbs: ["create", "get"]
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["cwagent-clusterleader"]
    verbs: ["get","update"]
  - nonResourceURLs: ["/metrics"]
    verbs: ["get", "list", "watch"]

若要檢查服務帳戶中的規則,請執行下列命令:

kubectl auth can-i --list --as=system:serviceaccount:amazon-cloudwatch:cloudwatch-agent

對 EKS Pod 身分識別代理程式權限問題進行疑難排解

Not authorized to perform: eks-auth:AssumeRoleForPodIdentity or Error fetching credentials 錯誤

如果 EKS Pod 身分識別代理程式無法承擔 Amazon EKS 節點 IAM 角色,您會收到下列其中一個錯誤:

「Error: AccessDenied: User: arn:aws:sts::[Account-ID]:assumed-role/[Role-Name]/[Session-Name] is not authorized to perform: eks-auth:AssumeRoleForPodIdentity on resource [Cluster]」

-或-

「Error: "error","msg":"Error fetching credentials: error getting credentials to cache: unable to fetch credentials from EKS Auth: operation error EKS Auth: AssumeRoleForPodIdentity, https response error StatusCode: 403, RequestID: fc66d1ec-33f1-43b0-a617-df1a52adcb63, AccessDeniedException: ","operation":"AssumeRoleForPodIdentity","request-id":"fc66d1ec-33f1-43b0-a617-df1a52adcb63","service":"EKS Auth"」

若要對此問題進行疑難排解,請確定您附加到角色的 IAM 政策允許 AssumeRoleForPodIdentity 動作。最佳實務是使用 AmazonEKSWorkerNodePolicy AWS 受管政策。或者,您可以新增類似下列範例的自訂政策:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"eks-auth:AssumeRoleForPodIdentity"
],
"Resource": "*"
}
]
}

此外,請確認組織的服務控制政策 (SCP) 不會封鎖 AssumeRoleForPodIdentity 動作。

**重要:**如果您在建立 Pod 身分識別關聯的同時建立 Pod 和服務帳戶,那麼您可能會遇到問題。若要解決問題,請在建立角色後等待至少 10 秒鐘以將角色關聯到 Pod。

對 CloudWatch 代理程式網路問題進行疑難排解

傳送日誌失敗或 PutLogEvents 發生錯誤

如果 CloudWatch 代理程式無法連接到 CloudWatch Logs 端點,您會收到下列其中一個錯誤:

「2023-03-18T12:00:00Z E! [outputs.cloudwatchlogs] Failed to send logs: RequestError: send request failed caused by: Post "https://logs.us-west-2.amazonaws.com/": dial tcp 52.94.76.32:443: i/o timeout」

-或-

「2024-11-22T17:00:48Z E! {"caller":"cwlogs@v0.103.0/cwlog_client.go:135","msg":"cwlog_client: Error occurs in PutLogEvents","kind":"exporter","data_type":"metrics","name":"awsemf/containerinsights","error":"RequestError: send request failed\ncaused by: Post \"https://logs.us-east-1.amazonaws.com/\"」

這個問題通常是由於網路限制或安全群組設定錯誤而發生。若要進行疑難排解,請確定節點可以透過網際網路閘道存取傳出網際網路。對於私有子網路,請確認您已正確設定 NAT 閘道。為 CloudWatch 服務設定虛擬私有雲端 (VPC) 端點。VPC 端點必須使用 com.amazonaws.region.logs 命名慣例,而端點的安全群組必須允許來自節點安全群組的傳入流量。

若要確認節點安全群組是否允許輸出 HTTPS 流量,請檢查下列組態:

  • 類型: HTTPS
  • 通訊協定: TCP
  • 連接埠: 443
  • 範圍目的地: 0.0.0.0/0

對 EKS Pod 身分識別代理程式網路問題進行疑難排解

擷取服務帳戶權杖時發生錯誤

Pod 安全群組必須允許 TCP 連接埠 80 上的傳出 HTTP 流量到執行個體中繼資料服務 IP 位址 (169.254.169.254)。如果沒有,那麼您會收到下列錯誤:

「Error retrieving service account token: Get "http://169.254.169.254/latest/meta-data/iam/security-credentials/": dial tcp 169.254.169.254:80: connect: connection timed out」

若要對此問題進行疑難排解,請確定 Pod 安全群組使用下列組態:

  • 類型: HTTPS
  • 通訊協定: TCP
  • 連接埠: 80
  • 範圍目的地: 169.254.169.254/32

如果您的 Pod 使用代理伺服器,則必須為 IPv4 新增 169.254.170.23,並為 IPv6 新增 [fd00:ec2::23]。更新 Pod 部署 YAML 檔案中的 no_proxyNO_PROXY 環境變數 (env)。

範例 Pod 部署 YAML 檔案:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: my-namespace
spec:
  template:
    spec:
      containers:
        - name: my-container
          image: my-app-image
          env:
            - name: HTTP_PROXY
              value: "http://proxy.example.com:3128"
            - name: HTTPS_PROXY
              value: "http://proxy.example.com:3128"
            - name: NO_PROXY
              value: "localhost,127.0.0.1,169.254.170.23,[fd00:ec2::23]"

然後,若要實作變更,請執行下列命令:

kubectl apply -f deployment.yaml

若要檢查 NO_PROXY 設定,請執行下列命令:

kubectl exec -it pod-name -n namespace -- env | grep -i no_proxy

**注意:**將 pod-name 替換為 Pod 名稱,將 namespace 替換為命名空間名稱。

請確定輸出類似下列範例:

NO_PROXY=localhost,127.0.0.1,169.254.170.23,[fd00:ec2::23]

對 CloudWatch 代理程式組態問題進行疑難排解

若要識別 Pod 的組態或資源相關問題,請執行下列命令來檢查 Pod 的詳細狀態:

kubectl describe pod pod-name -n namespace

然後,根據您收到的錯誤,執行下列疑難排解步驟。

Amazon/cloud-watch-agent:1 247345.36b249270" already present on machine 錯誤

如果您未正確設定 cloudwatch-agent,那麼您會收到以下錯誤:

「Normal Pulled 14m (x307 over 26h) kubelet Container image "amazon/cloudwatch-agent:1.247345.36b249270" already present on machine Warning BackOff 4m10s (x7130 over 26h) kubelet Back-off restarting failed container aws-cloudwatch-metrics in pod aws-cloudwatch-metrics-4jz88_kube-system(ad6f68f0-7df0-435f-b101-2be05df84eb2)」

若要對此問題進行疑難排解,請確認您已使用正確的 AWS 區域、日誌和指標設定 cloudwatch-agent 組態檔。此外,請檢查是否有無效的欄位或缺少參數的欄位。

若要檢查您是否使用了正確的影像版本,請完成下列步驟:

  1. 若要列出所有執行 CloudWatch 代理程式的 Pod,請執行下列命令:

    kubectl get pods -n amazon-cloudwatch

    **注意:**如果您使用自訂命名空間,請將 amazon-cloudwatch 替換為命名空間名稱。

  2. 若要檢查映像檔版本,請執行下列命令:

    kubectl describe pod pod-name -n amazon-cloudwatch

    **注意:**將 pod-name 替換為您的 Pod 名稱。如果您使用自訂命名空間,請將 amazon-cloudwatch 替換為命名空間名稱。

  3. 在輸出中,檢查 Image 值的版本號碼:

    Containers:
      cloudwatch-agent:
        Image: public.ecr.aws/cloudwatch-agent/cloudwatch-agent:1.300017.0b337

    若要查看 CloudWatch 代理程式的最新版本,請參閱 GitHub 網站上的版本

  4. 如果您使用早期版本,請執行以下命令來更新映像檔版本:

    kubectl set image daemonset/aws-cloudwatch-agent \
     -n amazon-cloudwatch \
     cloudwatch-agent=public.ecr.aws/cloudwatch-agent/cloudwatch-agent:latest-version

    **注意:**將 latest-version 替換為最新的映像檔版本。

  5. 若要重新啟動部署,請執行下列命令:

    kubectl rollout restart daemonset aws-cloudwatch-agent -n amazon-cloudwatch

如果您使用 Amazon CloudWatch Observability EKS 附加元件,請將該附加元件更新至最新版本

OOM 錯誤

如果您的容器沒有更多可用的記憶體,那麼您會收到以下錯誤:

「Warning OOMKilled kubelet Container was killed due to OOM

Warning Failed kubelet Container failed to start: Back-off restarting failed container」

若要對此問題進行疑難排解,請檢查您在 Pod 部署檔案中定義的資源請求和配額 (限制)。

Pod 部署檔案範例:

kubectl get pod cloudwatch-agent-xyz123 -n amazon-cloudwatch -o yaml | grep -A10 'resources:'
If limits are too low, update them in the DaemonSet:
resources:
  requests:
    cpu: 100m
    memory: 200Mi
  limits:
    cpu: 200m
    memory: 400Mi
Apply the changes:
kubectl apply -f cloudwatch-agent-daemonset.yaml

若要更新請求和配額,請執行下列命令:

kubectl edit daemonset aws-cloudwatch-agent -n amazon-cloudwatch
resources:
  requests:
    cpu: 100m
    memory: 200Mi
  limits:
    cpu: 200m
    memory: 400Mi

若要實作變更,請執行下列命令:

kubectl rollout restart daemonset aws-cloudwatch-agent -n amazon-cloudwatch

若要確保節點擁有足夠的資源,請執行下列命令:

kubectl top nodes

如果 CPU 或記憶體使用率較高,請執行下列命令來擴展叢集:

kubectl scale nodegroup --name nodegroup-name --replicas=new-size

**注意:**將 nodegroup-name 替換為您的節點群組名稱,將 new-size 替換為新的節點群組大小。

對 EKS Pod 身分識別代理程式組態問題進行疑難排解

無法啟動伺服器錯誤

如果您沒有正確設定 EKS Pod 身分識別代理程式,那麼您可能會收到以下錯誤:

「{"bind-addr":"[fd00:ec2::23]:80","level":"info","msg":"Starting server...","time":"2024-02-05T17:52:40Z"}{"bind-addr":"[fd00:ec2::23]:80","level":"fatal","msg":"Unable to start server: listen tcp [fd00:ec2::23]:80: socket: address family not supported by protocol","time":"2024-02-05T17:52:40Z"}2024/02/05 17:52:40 running command: exit status 1」

若要對此問題進行疑難排解,請確定您遵守 Amazon EKS Pod 身分識別代理程式的要求

請確認您使用最新的附加元件版本,以減少版本相容性問題。若要檢查最新的可用版本,請執行以下 describe-addon-versions AWS CLI 命令:

aws eks describe-addon-versions --kubernetes-version 1.31 --addon-name eks-pod-identity-agent

**注意:**將 1.31 替換為您的叢集版本。

若要更新附加元件,請執行以下 update-addon 命令:

aws eks update-addon --cluster-name my-cluster --addon-name eks-pod-identity-agent --addon-version version-number --resolve-conflicts PRESERVE

**注意:**將 my-cluster 替換為您的叢集名稱,將 version-number 替換為您的附加元件版本。

AWS 官方已更新 1 年前