为什么我的 Amazon EKS 容器组(pod)停滞在 ContainerCreating 状态,并显示错误“failed to create pod sandbox(无法创建容器组(pod)沙盒)”?

6 分钟阅读
0

我的 Amazon Elastic Kubernetes Service (Amazon EKS) 容器组(pod)停滞在 ContainerCreating 状态,并显示错误“failed to create pod sandbox(无法创建容器组(pod)沙盒)”。

解决方法

由于多种原因,您的 Amazon EKS 容器组(pod)可能会停滞在 ContainerCreating 状态,并出现网络连接错误。根据收到的错误消息,使用以下故障排除步骤。

来自进程守护程序的错误响应:failed to start shim: fork/exec /usr/bin/containerd-shim: resource temporarily unavailable: unknown(无法启动 shim:fork/exec /usr/bin/containerd-shim:资源暂时不可用:未知)

出现此错误的原因是,为最大 PID 或最大文件数定义的内核设置导致操作系统受到限制。

运行以下命令以获取有关您的容器组(pod)的信息:

$ kubectl describe pod example_pod

示例输出:

kubelet, ip-xx-xx-xx-xx.xx-xxxxx-x.compute.internal  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to start sandbox container for pod "example_pod": Error response from daemon: failed to start shim: fork/exec /usr/bin/containerd-shim: resource temporarily unavailable: unknown

要暂时解决问题,请重新启动节点。

要排查此问题,请执行以下操作:

  • 收集节点日志。
  • 查看 Docker 日志中是否存在错误**“dockerd[4597]: runtime/cgo: pthread_create failed: Resource temporarily unavailable”**(dockerd[4597]:运行时/cgo:pthread_create 失败:资源暂时不可用)。
  • 查看 Kubelet 日志中是否有以下错误:
    • “kubelet[5267]: runtime: failed to create new OS thread (have 2 already; errno=11)(kubelet [5267]:运行时:无法创建新的操作系统线程(已经有 2 个;errno=11))”
    • “kubelet[5267]: runtime: may need to increase max user processes (ulimit -u)(kubelet [5267]:运行时:可能需要增加最大用户进程数(ulimit-u))”
  • 通过运行 ps 命令来标识僵尸进程。在输出中列出的 Z 状态的所有进程都是僵尸进程。

Network plugin cni failed to set up pod network: add cmd: failed to assign an IP address to container(网络插件 CNI 无法设置容器组(pod)网络:添加 cmd:无法为容器分配 IP 地址)

此错误表示容器网络接口 (CNI) 无法为新预置的容器组(pod)分配 IP 地址。

以下是 CNI 未能向新创建的容器组(pod)提供 IP 地址的原因:

  • 实例使用了允许的最大弹性网络接口和 IP 地址。
  • Amazon Virtual Private Cloud (Amazon VPC) 子网的 IP 地址计数为零。

以下是网络接口 IP 地址耗尽的示例:

Instance type    Maximum network interfaces    Private IPv4 addresses per interface    IPv6 addresses per interface
t3.medium        3                             6                                       6

在此示例中,实例 t3.medium 最多有 3 个网络接口,每个网络接口最多有 6 个 IP 地址。第一个 IP 地址用于节点,不可分配。剩下的 17 个 IP 地址可以分配给网络接口。

当网络接口用完 IP 地址时,本地 IP 地址管理进程守护程序 (iPamD) 日志将显示以下消息:

"ipamd/ipamd.go:1285","msg":"Total number of interfaces found: 3 "
"AssignIPv4Address: IP address pool stats: total: 17, assigned 17"
"AssignPodIPv4Address: ENI eni-abc123 does not have available addresses"

运行以下命令以获取有关您的容器组(pod)的信息:

$ kubectl describe pod example_pod

示例输出:

Warning FailedCreatePodSandBox 23m (x2203 over 113m) kubelet, ip-xx-xx-xx-xx.xx-xxxxx-x.compute.internal (combined from similar events): Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" network for pod "provisioning-XXXXXXXXXXXXXXX": networkPlugin cni failed to set up pod "provisioning-XXXXXXXXXXXXXXX" network: add cmd: failed to assign an IP address to container

查看子网以确定子网是否用完空闲 IP 地址。您可以在 Amazon VPC 控制台Subnets(子网)部分下查看每个子网的可用 IP 地址。

Subnet: XXXXXXXXXX
IPv4 CIDR Block 10.2.1.0/24   Number of allocated ips 254   Free address count 0

要解决此问题,请缩减部分工作负载以释放可用的 IP 地址。如果有额外的子网容量可用,则可以扩展节点。您还可以创建一个额外的子网。有关更多信息,请参阅我该如何通过 Amazon EKS 使用多个 CIDR 范围? 按照使用新的 CIDR 范围创建子网部分中的说明进行操作。

Error while dialing dial tcp 127.0.0.1:50051: connect: connection refused(拨号 dial tcp 127.0.0.1:50051 时出错:连接:连接被拒绝)

此错误表示 aws-node 容器组(pod)无法与 IPAM 通信,因为 aws-node 容器组(pod)无法在节点上运行。

运行以下命令以获取有关容器组(pod)的信息:

$ kubectl describe pod example_pod
$ kubectl describe pod/aws-node-XXXXX -n kube-system

示例输出:

Warning  FailedCreatePodSandBox  51s  kubelet, ip-xx-xx-xx-xx.ec2.internal  Failed create pod sandbox: rpc error: code = Unknown desc = [failed to set up sandbox container "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" network for pod "example_pod": NetworkPlugin cni failed to set up pod "example_pod" network: add cmd: Error received from AddNetwork gRPC call: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 127.0.0.1:50051: connect: connection refused", failed to clean up sandbox container
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" network for pod "example_pod": NetworkPlugin cni failed to teardown pod "example_pod" network: del cmd: error received from DelNetwork gRPC call: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 127.0.0.1:50051: connect: connection refused"]

要解决此问题,请验证 aws-node 容器组(pod)是否已部署并处于 Running(运行)状态:

kubectl get pods --selector=k8s-app=aws-node -n kube-system

注意: 请确保您运行的是集群版本 正确版本的 VPC CNI 插件

容器组(pod)可能由于 Liveness(存活)和 Readiness(就绪)探测错误而处于 Pending(待处理)状态。根据兼容性表,请确保您拥有最新推荐的 VPC CNI 附加组件版本。

运行以下命令以查看来自 aws-node 容器组(pod)的最后一条日志消息:

kubectl -n kube-system exec -it aws-node-XXX-- tail -f /host/var/log/aws-routed-eni/ipamd.log | tee ipamd.log

如果 Dockershim 挂载点无法挂载,也可能发生此问题。以下是发生此问题时可能收到的消息示例:

Getting running pod sandboxes from \"unix:///var/run/dockershim.sock\
Not able to get local pod sandboxes yet (attempt 1/5): rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: Error while dialing dial unix /var/run/dockershim.sock: connect: no such file or director

前面的消息表明容器组(pod)没有挂载 var/run/dockershim.sock

要解决此问题,请尝试以下操作:

  • 重新启动 aws-node 容器组(pod)以重新映射挂载点。
  • 封锁节点,并缩放节点组中的节点。
  • 将 Amazon VPC 网络接口升级到支持的最新集群版本。

如果您将 CNI 作为托管式插件添加到 AWS 管理控制台中,则 aws-node 会使探测失败。托管式插件会覆盖服务账户。但是,没有为服务账户配置所选角色。要解决此问题,请从 AWS 管理控制台关闭插件,然后使用清单文件创建服务账户。或者,编辑当前的 aws-node 服务账户,以添加在托管式插件上使用的角色。

Network plugin cni failed to set up pod "my-app-xxbz-zz" network: failed to parse Kubernetes args: pod does not have label vpc.amazonaws.com/PrivateIPv4Address(网络插件 cni 无法设置容器组(pod)“example pod”网络:无法解析 Kubernetes args:容器组(pod)没有标签 vpc.amazonaws.com/PrivateIPv4Address)

由于以下某种原因,您可能会收到此类错误:

  • 容器组(pod)运行不正常。
  • 未成功创建容器组(pod)使用的证书。

此错误与在 Amazon EKS 集群上运行 Windows 工作负载所需的 Amazon VPC 准入控制器 Webhook 相关。webhook 是在 kube-system 命名空间中运行容器组(pod)的插件。该组件在 Linux 节点上运行,并允许为 Windows 节点上的传入容器组(pod)启用网络连接。

运行以下命令以获取受影响的容器组(pod)列表:

kubectl get pods

示例输出:

my-app-xxx-zz        0/1     ContainerCreating   0          58m   <none>            ip-XXXXXXX.compute.internal   <none>
my-app-xxbz-zz       0/1     ContainerCreating   0          58m   <none>

运行以下命令以获取有关容器组(pod)的信息:

$ kubectl describe pod my-app-xxbz-zz

示例输出:

Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" network for pod "<POD_ANME>": networkPlugin cni failed to set up pod "example_pod" network: failed to parse Kubernetes args: pod does not have label vpc.amazonaws.com/PrivateIPv4Address
Reconciler worker 1 starting processing node ip-XXXXXXX.compute.internal.
Reconciler checking resource vpc.amazonaws.com/PrivateIPv4Address warmpool size 1 desired 3 on node ip-XXXXXXX.compute.internal.
Reconciler creating resource vpc.amazonaws.com/PrivateIPv4Address on node ip-XXXXXXX.compute.internal.
Reconciler failed to create resource vpc.amazonaws.com/PrivateIPv4Address on node ip-XXXXXXX.compute.internal: node has no open IP address slots.

Windows 节点支持每个节点一个网络接口。每个 Windows 节点可以运行的容器组(pod)数量比每个网络接口的可用 IP 地址数量少 1 个。要解决此问题,请纵向扩展 Windows 节点的数量。

如果 IP 地址不存在问题,请查看 Amazon VPC 准入控制器容器组(pod)事件和日志。

运行以下命令以确认已创建 Amazon VPC 准入控制器容器组(pod):

$ kubectl get pods -n kube-system  OR kubectl get pods -n kube-system | grep "vpc-admission"

示例输出:

vpc-admission-webhook-5bfd555984-fkj8z     1/1     Running   0          25m

运行以下命令以获取有关容器组(pod)的信息:

$ kubectl describe pod vpc-admission-webhook-5bfd555984-fkj8z -n kube-system

示例输出:

  Normal  Scheduled  27m   default-scheduler  Successfully assigned kube-system/vpc-admission-webhook-5bfd555984-fkj8z to ip-xx-xx-xx-xx.ec2.internal
  Normal  Pulling    27m   kubelet            Pulling image "xxxxxxx.dkr.ecr.xxxx.amazonaws.com/eks/vpc-admission-webhook:v0.2.7"
  Normal  Pulled     27m   kubelet            Successfully pulled image "xxxxxxx.dkr.ecr.xxxx.amazonaws.com/eks/vpc-admission-webhook:v0.2.7" in 1.299938222s
  Normal  Created    27m   kubelet            Created container vpc-admission-webhook
  Normal  Started    27m   kubelet            Started container vpc-admission-webhook

运行以下命令以检查容器组(pod)日志是否存在任何配置问题:

$ kubectl logs vpc-admission-webhook-5bfd555984-fkj8z -n kube-system

示例输出:

I1109 07:32:59.352298       1 main.go:72] Initializing vpc-admission-webhook version v0.2.7.
I1109 07:32:59.352866       1 webhook.go:145] Setting up webhook with OSLabelSelectorOverride: windows.
I1109 07:32:59.352908       1 main.go:105] Webhook Server started.
I1109 07:32:59.352933       1 main.go:96] Listening on :61800 for metrics and healthz
I1109 07:39:25.778144       1 webhook.go:289] Skip mutation for  as the target platform is .

前面的输出显示容器已成功启动。然后,该容器组(pod)会将 vpc.amazonaws.com/PrivateIPv4Address 标签添加到应用程序容器中。但是,应用程序容器组(pod)的清单必须包含节点选择器或关联,以便在 Windows 节点上调度容器组(pod)。

解决此问题的其他方式包括验证以下内容:

  • 您在 kube-system 命名空间中部署了 Amazon VPC 准入控制器容器组(pod)。
  • 日志或事件未指向过期证书。如果证书过期,并且 Windows 容器组(pod)处于 Container creating(容器创建中)状态,则必须删除并重新部署容器组(pod)。
  • 没有任何超时或 DNS 相关问题。

如果您没有创建 Amazon VPC 准入控制器,请为您的集群 启用 Windows 支持

重要提示: Amazon EKS 不要求您打开 Amazon VPC 准入控制器来支持 Windows 节点组。如果您打开了 Amazon VPC 准入控制器,请 从数据面板中删除旧的 Windows 支持


相关信息

Amazon EKS 联网

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