跳至内容

如何解决 CloudWatch 代理和 EKS 容器组身份代理容器组的 CrashLoopBackOff 状态?

5 分钟阅读
0

我的 Amazon Elastic Kubernetes Service (Amazon EKS) 集群的 Amazon CloudWatch 代理或 Amazon EKS 容器组身份代理容器组卡滞在 CrashLoopBackOff 状态。

解决方法

**注意:**如果您在运行 AWS 命令行界面 (AWS CLI) 命令时收到错误,请参阅 AWS CLI 错误故障排除。此外,请确保您使用的是最新版本的 AWS CLI

检查日志

首先,检查 CloudWatch 代理和 EKS 容器组身份代理日志,以收集有关该问题的信息。

要检查 CloudWatch 代理日志,请运行以下命令:

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

**注意:**请将 cloudwatch-agent-pod-name 替换为您的 CloudWatch 代理容器组名称,并将 namespace 替换为您的命名空间名称。

要检查 EKS 容器组身份代理日志,请运行以下命令:

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

**注意:**请将 pod-identity-agent-pod-name 替换为您的 EKS 容器组身份代理容器组名称,并将 namespace 替换为您的命名空间名称。

在命令输出中,查找显示容器组崩溃原因的错误消息,例如权限问题、网络问题或配置问题。

对 CloudWatch 代理权限问题进行故障排除

无法创建提供商错误

您必须使用 AWS Identity and Access Management (IAM) 服务 AWS 账户角色来允许 Amazon EKS Worker 节点向 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 替换为服务账户角色名称。

无权执行: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]"

-or-

"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 容器组身份代理权限问题进行故障排除

无权执行:eks-auth:AssumeRoleForPodIdentity 或获取凭证时出错

如果 EKS 容器组身份代理无法代入 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]"

-or-

"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 操作。

**重要事项:**如果您同时创建容器组和服务账户与容器组身份关联,则可能会遇到问题。要解决这些问题,请在创建角色后至少等待 10 秒钟以将该角色关联到容器组。

对 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"

-or-

"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 容器组身份代理网络问题进行故障排除

“检索服务账户令牌时出错”错误

容器组安全组必须允许通过 TCP 端口 80 向实例元数据服务 IP 地址 (169.254.169.254) 发送出站 HTTP 流量。否则,您会收到以下错误:

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

要解决此问题,请确保容器组安全组使用以下配置:

  • 类型: HTTPS
  • 协议: TCP
  • 端口: 80
  • 范围目标: 169.254.169.254/32

如果您的容器组使用代理,则必须为 IPv4 添加 169.254.170.23,为 IPv6 添加 [fd00:ec2::23]。在容器组部署 YAML 文件中更新 no_proxyNO_PROXY 环境变量 (env)。

容器组部署 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 替换为容器组名称,并将 namespace 替换为命名空间名称。

确保输出类似于以下示例:

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

对 CloudWatch 代理配置问题进行故障排除

要识别容器组的配置或资源相关问题,请运行以下命令来检查容器组的详细状态:

kubectl describe pod pod-name -n namespace

然后,根据您收到的错误执行以下故障排除步骤。

“Amazon/cloud-watch-agent:1 247345.36b249270" 已存在于计算机上”错误

如果您错误地配置了 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 代理的容器组,请运行以下命令:

    kubectl get pods -n amazon-cloudwatch

    **注意:**如果您使用自定义命名空间,请将 amazon-cloudwatch 替换为命名空间名称。

  2. 要检查映像版本,请运行以下命令:

    kubectl describe pod pod-name -n amazon-cloudwatch

    **注意:**请将 pod-name 替换为您的容器组名称。如果您使用自定义命名空间,请将 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"

要解决此问题,请检查您在容器组部署文件中定义的资源请求和配额(限制)。

容器组部署文件示例:

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 容器组身份代理配置问题进行故障排除

无法启动服务器错误

如果您没有正确配置 EKS 容器组身份代理,则可能会收到以下错误:

"{"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 容器组身份代理要求

确保使用最新的附加组件版本来减少版本兼容性问题。要查看最新的可用版本,请运行以下 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 年前