跳至内容

如何对 Amazon EKS 中的 Kubernetes 容器组问题进行故障排除?

4 分钟阅读
0

我的 Amazon Elastic Kubernetes Service (Amazon EKS) 集群中的 Kubernetes 容器组出现故障。我想确定容器组故障的根本原因。

解决方法

识别导致容器组出现问题的错误

  1. 要获取有关您的容器组的信息,请运行以下 kubectl describe 命令:

    kubectl describe pod YOUR_POD_NAME -n YOUR_NAMESPACE

    **注意:**请将 YOUR_POD_NAME 替换为您的容器组名称,将 YOUR_NAMESPACE 替换为您的命名空间。

  2. 识别命令输出的 Events(事件)部分中的错误消息。

    输出示例:

    Events:
      Type     Reason            Age                From               Message
      ----     ------            ----               ----               -------
      Warning  FailedScheduling  24s                default-scheduler  no nodes available to schedule pods
      Warning  FailedScheduling  19s (x2 over 22s)  default-scheduler  no nodes available to schedule pods

根据您收到的错误消息,使用以下故障排除方法来解决您的容器组问题。

EBS 卷挂载问题

以下示例输出来自 kubectl describe pod ebs-pod 命令。该输出显示了 Amazon Elastic Block Store (Amazon EBS) 卷挂载相关的卷节点关联性错误:

Name:         ebs-pod
...
Status:       Pending
...
Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning FailedScheduling 88s (x20 over 96m) default-scheduler 0/2 nodes are available 2 node(s) had volume node affinity conflict

当在多个可用区中为容器组调度持久性卷声明 (PVC) 时,将会出现上述错误。您将无法调度您的容器组,因为容器组无法从另一个可用区连接到卷。要解决此问题,必须在一个可用区中调度 PVC。

要对上述错误进行故障排除,请完成以下步骤:

  1. 要获取有关命名空间中所有 PVC 的信息,请运行以下 kubectl get pvc 命令:

    kubectl get pvc -n YOUR_NAMESPACE

    **注意:**请将 YOUR_NAMESPACE 替换为您的命名空间。

  2. 要获取有关您的持久性卷 (PV) 的信息,请运行以下 kubectl get pv 命令:

    kubectl get pv
  3. 要找到与您的 PVC 对应的 PV,请运行以下 kubectl describe pv 命令:

    kubectl describe pv your_PV

    **注意:**请将 your_PV 替换为您的 PV 名称。

  4. 确认您从上述命令中获取的卷 ID 是否与正确的可用区相关联。

  5. 检查该可用区所在的节点。

如果您遇到卷节点关联性冲突,请执行以下操作之一:

  • 使用污点和容忍度来确保挂载 Amazon EBS 卷的容器组被调度到正确的节点上。该节点必须位于 EBS 卷所在的可用区内。有关详细信息,请参阅 Kubernetes 网站上的污点和容忍度
  • 使用 StatefulSet 替代 Deployment,在同一可用区中为 StatefulSet 中的每个容器组创建一个唯一的 EBS 卷。有关详细信息,请参阅 Kubernetes 网站上的 StatefulSet

您的容器组或 StatefulSet 可能会卡滞在 Pending(待处理)状态。即使您的容器组或 StatefulSet 与 EBS 卷位于同一可用区内,也是如此。要解决此问题,请运行以下 kubectl logs 命令以检查 Amazon EBS CSI 驱动程序容器组的日志:

kubectl logs your-ebs-csi-controller -n your-kube-system -c your-csi-provisioner

**注意:**请将 your-ebs-csi-controller 替换为您的 Amazon EBS CSI 控制器。此外,请将 your-kube-system 替换为您的预定义命名空间,将 your-csi-provisioner 替换为您用于拉取日志的容器名称。

ContainerCreating 状态错误

当您的容器组卡滞在 ContainerCreating 状态,且 networkPlugin: cni 没有为容器组分配 IP 地址时,将会出现以下错误消息:

“Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "0fdf25254b1888afeda8bf89bc1dcb093d0661ae2c8c65a4736e473c73714c65" network for pod "test": networkPlugin cni failed to set up pod "test" network: add cmd: failed to assign an IP address to container.”

要对 ContainerCreating 状态错误进行故障排除,请执行以下操作:

  • 检查您的子网是否有可用的 IP 地址,以解决此问题。打开 Amazon Virtual Private Cloud (Amazon VPC) 控制台。在导航窗格中的 Virtual private cloud(虚拟私有云)下,选择 Subnets(子网)。
  • 验证 aws-node 的容器组是否处于 Running(正在运行)状态。此外,请确保您使用的是最新的受支持的 Amazon VPC CNI 版本
  • 检查实例上的容器组数量是否达到最大容器组数
  • 在调度容器组的节点中,查找 var/log/aws-routed-eni 路径下的 ipamd 日志和插件中是否存在错误消息。

CrashLoopBackOff 状态错误

您收到“Back-Off restarting failed container”错误消息。

出现上述错误消息是因为容器反复启动失败,随后进入 CrashLoopBackOff 状态并在容器组内持续重启。

以下问题可能会导致容器反复启动失败:

  • 内存不足
  • 资源过载
  • 部署错误
  • 外部依赖项问题,例如 DNS 错误
  • 第三方依赖项
  • 由端口冲突导致的容器级故障

要获取当前容器组日志中的错误,请运行以下 kubectl logs 命令:

kubectl logs YOUR_POD_NAME -n YOUR_NAMESPACE

**注意:**请将 YOUR_POD_NAME 替换为您的容器组名称,将 YOUR_NAMESPACE 替换为您的命名空间。

要获取上一个崩溃的容器组日志中的错误,请运行以下 kubectl logs --previous 命令:

kubectl logs --previous YOUR_POD_NAME -n YOUR_NAMESPACE

**注意:**请将 YOUR_POD_NAME 替换为您的容器组名称,将 YOUR_NAMESPACE 替换为您的命名空间。

探测失败错误

当某个容器组崩溃时,您会因为连接被拒绝或客户端超时而收到探测失败错误。

对连接被拒绝问题进行故障排除

如果由于连接被拒绝而导致探测失败,您可能会收到以下错误消息之一:

  • “Liveness probe failed: Get https://$POD_IP:8080/<healthcheck_path>: dial tcp POD_IP:8080: connect: connection refused.”
  • “Readiness probe failed: Get https://$POD_IP:8080/<healthcheck_path>: dial tcp POD_IP:8080: connect: connection refused.”

要对连接被拒绝问题进行故障排除,请完成以下步骤:

  1. 要从 Worker 节点手动获取容器组清单中定义的运行状况检查路径,请运行以下命令:

    [ec2-user@ip-10-5-1-12 ~]$ curl -ikv podIP:8080//your_healthcheck_path

    **注意:**请将 podIP 替换为您的容器组的 IP 地址,将 your_healthcheck_path 替换为您的路径名称。

  2. 检查在容器组清单中为未通过存活探测就绪探测的容器组定义的运行状况检查路径。要检查运行状况检查路径,请运行以下命令:

    local@bastion-host ~ % kubectl exec YOUR_POD_NAME -- curl -ikv "http://localhost:8080/your_healthcheck_path"

    **注意:**请将 YOUR_POD_NAME 替换为您的容器组名称。

  3. 在堡垒主机上运行相同的容器映像。

  4. 检查是否能够获取清单中探测所定义的运行状况检查路径。然后,检查容器日志中是否存在失败、超时或错误。

  5. 要检查运行容器组的 Worker 节点的 kubelet 日志中是否存在错误,请运行以下 journalctl 命令:

    [ec2-user@ip-10-5-1-12 ~]$ journalctl -u kubelet //optionally 'grep' with pod name

对客户端超时问题进行故障排除

如果由于客户端超时而导致探测失败,您可能会收到以下错误消息之一:

  • “Liveness probe failed: Get "http://podIP:8080/<healthcheck_path> ": context deadline exceeded (Client.Timeout exceeded while awaiting headers).”
  • “Readiness probe failed: Get "http://podIP:8080/<healthcheck_path> ": context deadline exceeded (Client.Timeout exceeded while awaiting headers).”

要对客户端超时问题进行故障排除,请检查应用程序容器组的存活探测和就绪探测的配置是否正确。

如果您为容器组使用安全组并启用了 ENABLE_POD_ENI=true,则必须关闭 TCP early demux。此操作允许 kubelet 连接到分支网络接口上使用 TCP 的容器组。

要关闭 TCP early demux,请运行以下 kubectl patch 命令:

kubectl patch daemonset aws-node -n kube-system \-p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'

ImagePullBackOff 错误

当在容器组中运行的某个容器无法从容器注册表中拉取所需的映像时,将会出现 ImagePullBackOff 错误。

以下问题可能会导致此错误:

  • 网络连接问题
  • 映像名称或标签不正确
  • 缺少凭证
  • 权限不足

要确定导致问题的原因,请完成以下步骤:

  1. 要获取您的容器组的状态,请运行以下命令:

    kubectl get pods -n YOUR_NAMESPACE

    **注意:**请将 YOUR_NAMESPACE 替换为您的命名空间。

  2. 要获取有关容器组故障的详细信息,请运行以下命令:

    kubectl describe pod YOUR_POD_NAME -n YOUR_NAMESPACE

    **注意:**请将 YOUR_POD_NAME 替换为您的容器组名称,将 YOUR_NAMESPACE 替换为您的命名空间。

    输出示例:

    Events:
    Type     Reason     Age                From                Message
    ----     ------     ----               ----                -------
    Normal   Scheduled  18m                default-scheduler   Successfully assigned kube-system/kube-proxy-h4np6 to XXX.XXX.eu-west-1.compute.internal
    Normal   Pulling    16m (x4 over 18m)  kubelet             Pulling image "<account-id>.dkr.ecr.eu-west-1.amazonaws.com/eks/kube-proxy:v1.21.5-eksbuild.2"
    Warning  Failed     16m (x4 over 18m)  kubelet             Failed to pull image "<account-d>.dkr.ecr.eu-west-1.amazonaws.com/eks/kube-proxy:v1.21.5-eksbuild.2": rpc error: code = Unknown desc = Error response from daemon: manifest for <account-id>.dkr.ecr.eu-west-1.amazonaws.com/eks/kube-proxy:v1.21.5-eksbuild.2 not found: manifest unknown: Requested image not found

要对 ImagePullBackOff 错误进行故障排除,请参阅如何解决 Amazon EKS 中的容器组状态 ErrImagePull 和 ImagePullBackoff 错误?

AWS 官方已更新 4 个月前