跳至内容

为什么我的 Amazon EKS 容器组卡在 ContainerCreating 状态并显示“Failed to create pod sandbox”错误?

4 分钟阅读
0

我的 Amazon Elastic Kubernetes Service (Amazon EKS) 容器组卡在 ContainerCreating 状态并显示“failed to create pod sandbox”错误。

解决方案

先决条件

确定有问题的容器组。完成以下步骤:

  1. 运行以下命令列出集群中的容器组,以识别处于 ContainerCreating 状态的容器组:

    kubectl get pods --all-namespaces -o wide
  2. 运行以下命令,以检索处于 ContainerCreating 状态的每个容器组的相关详细信息:

    kubectl describe pod pod-name -n pod-namespace

    **注意:**请将 pod-name 替换为您的容器组名称,将 pod-namespace 替换为您的容器组所在的命名空间。

  3. 查看 Events(事件)中的输出以识别相关容器组,然后使用以下部分对您的问题进行故障排除。

“Resource temporarily unavailable”错误

如果您为 PID 或文件定义的内核设置超过操作系统 (OS) 的最大限制,则会收到类似于以下内容的错误消息:

“kubelet, ip-192-168-0-1.us-east-1.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”

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

要对此问题进行故障排除,请完成以下步骤:

  1. 收集 ContainerdKubelet 的节点日志。
    对于 Windows,连接到您的实例。打开 PowerShell 命令提示符,然后使用 Windows EKS 日志收集器脚本收集 Worker 节点日志。有关详细信息,请参阅 GitHub 网站上的 EKS Logs Collector (Windows)(EKS 日志收集器 (Windows))。运行以下命令:

    Invoke-WebRequest -OutFile eks-log-collector.ps1 https://raw.githubusercontent.com/awslabs/amazon-eks-ami/main/log-collector-script/windows/eks-log-collector.ps1
    .\eks-log-collector.ps1

    对于 Linux,连接到您的实例。然后,使用 Linux EKS 日志收集器脚本收集 Worker 节点日志。有关详细信息,请参阅 GitHub 网站上的 EKS Logs Collector (Linux)(EKS 日志收集器 (Linux))。运行以下命令以下载日志收集器脚本:

    curl -O https://raw.githubusercontent.com/awslabs/amazon-eks-ami/master/log-collector-script/linux/eks-log-collector.sh
  2. 然后,运行下载的脚本:

    sudo bash eks-log-collector.sh
  3. 查看 Kubelet 日志中是否有以下错误响应:
    “kubelet[5267]: runtime: failed to create new OS thread (have 2 already; errno=11)""kubelet[5267]: runtime: may need to increase max user processes (ulimit -u)”

  4. 识别僵尸进程,然后停止不必要的进程。
    对于 Windows,打开“任务管理器”,然后选择 Details(详细信息)选项卡。检查状态显示为 Not responding(无响应)的进程,以识别僵尸进程。
    对于 Linux,运行以下 ps 命令,以检查列出的处于 Z 状态的僵尸进程:

    ps aux | egrep "Z|defunct"

    有关详细信息,请参阅 Linux Journal 网站上的 How to kill Zombie processes on Linux(如何在 Linux 上终止僵尸进程)

“Network plugin cni failed to set up pod network”错误

如果容器网络接口 (CNI) 无法为您新创建的容器组分配 IP 地址,您可能会收到以下错误消息:

“Network plugin cni failed to set up pod network: add cmd: failed to assign an IP address to container”

出现此错误的原因可能有多种,主要分为三类:

资源限制:

  • 子网 IP 已耗尽
  • 已达到最大 ENI 连接限制

配置问题:

  • Worker 节点上缺少 IAM CNI 策略
  • VPC CNI (aws-node) 容器组未处于 Running(正在运行)状态
  • VPC CNI、kube-proxy 或 CoreDNS 的版本已过时
  • 安全组或访问控制列表配置不正确

架构特定挑战:

  • VPC CNI 配置与您的使用案例不一致
  • 缺少 OpenID Connect (OIDC) 配置
  • 使用的是自行管理的插件,而非 EKS 托管的插件

有关详细的故障排除步骤,请参阅我如何解决 Amazon EKS 的 kubelet 或 CNI 插件问题?

最佳做法是执行以下操作:

**注意:**如果您对 CNI 配置进行了任何更改,则必须重启受影响的节点才能使更改生效。

“Error while dialing”错误

如果 aws-node 容器组无法与 IPAM 通信(因为 aws-node 容器组无法在该节点上运行),您将会收到类似于以下内容的错误:

“Error while dialing dial tcp 127.0.0.1:50051: connect: connection refused”

此错误会在以下情况下出现:

VPC CNI 处于“待处理”状态

存活和就绪探测失败可能由于安全规则配置或应用程序错误而导致。资源耗尽也可能会导致延迟。通常,如果在 POD_SECURITY_GROUP_ENFORCING_MODE 设为严格模式的情况下将 DISABLE_TCP_EARLY_DEMUX 设置为 false,则可能会出现失败。

如果您使用容器组的安全组以及存活或就绪探测,请在严格模式下将 DISABLE_TCP_EARLY_DEMUX 设置为 true。这使得 kubelet 能够使用 TCP 连接到分支网络接口上的容器组。

CNI 托管插件问题

当在 AWS 管理控制台中被添加为托管插件时,aws-node 会导致探测失败。发生此情况是因为托管插件会覆盖服务账户。

要解决此问题,请执行以下操作之一:

  • 从 AWS 管理控制台中移除托管插件。然后,使用提供所需的 AmazonEKS_CNI_Policy IAM 策略的正确 IAM 角色重新创建此插件。
  • 编辑现有的 aws-node 服务账户,将其与具备所需 CNI 权限的正确 IAM 角色相关联。
  • 如果您在集群上使用容器组身份,请创建必要的容器组身份关联,以将 aws-node 服务账户与 VPC CNI 要使用的 IAM 角色绑定。

其他建议:

“Failed to setup network for sandbox”错误

如果您在 VPC-CNI (aws-node) 容器组中使用“启用前缀委派”,则可能会收到以下错误消息:

“Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox”

要获取有关此问题的更多详细信息,请查看 Worker 节点中 /var/log/aws-routed-eni/ipamd.log 处的 IP 地址管理进程守护程序 (IPAMD) 日志。

即使您的子网拥有可用 IP 地址,但如果该子网内没有任何连续的 /28 IP 块可用,也会出现此错误。当现有辅助 IP 地址的分段分布在子网中时,将会出现此错误。该错误会出现在 Kubernetes 的 Amazon VPC CNI 插件日志中,或受影响 Worker 节点的 CloudTrail 事件中。您可能会收到以下错误消息:

“InsufficientCidrBlocks: The specified subnet does not have enough free cidr blocks to satisfy the request”

要解决此错误,请完成以下选项之一:

创建一个新子网,然后在其中启动容器组。

-或-

使用 Amazon EC2 子网的 CIDR 预留功能在子网内预留空间,以用于前缀分配。

如果要从 IP 地址分配转换为 IP 前缀分配,请创建新的节点组。然后,您可以增加可用 IP 地址的数量,而不是滚动替换现有节点。

如果您在同时分配了 IP 地址和前缀的节点上运行容器组,则可能会导致播发的 IP 地址容量出现不一致。这种情况可能会影响节点上未来的工作负载。要解决此问题,请按照为带前缀的 Amazon EKS 节点分配更多 IP 地址中的步骤进行操作。

Windows 节点上的“Pod does not have label”错误

如果容器组未在 Windows 节点上配置计划的 nodeSelector,您可能会收到类似于以下的错误消息:

“Failed to parse Kubernetes args: pod does not have label vpc.amazonaws.com/PrivateIPv4Address" or "Pod does not have label vpc.amazonaws.com/PrivateIPv4Address”

要解决此问题,请确保在 PodSpec 中为 nodeSelector 参数包含以下标签:

nodeSelector:
    kubernetes.io/os: windows
    kubernetes.io/arch: amd64

确认在 amazon-vpc-cni 中将 enable-windows-ipam 参数设置为 true

如果您没有 amazon-vpc-cni configmap,请使用以下模板并上传到您的集群:

apiVersion: v1
kind: ConfigMap
metadata:
  name: amazon-vpc-cni
  namespace: kube-system
data:
  enable-windows-ipam: "true"

重启 aws-nodenode-windows 容器组。

有关如何在 Amazon EKS 集群上部署 Windows 节点的详细信息,请参阅在 EKS 集群上部署 Windows 节点

安全组错误

如果您遇到安全组问题,则会收到与以下内容类似的错误:

"Plugin type="aws-cni" name="aws-cni" failed (add): add cmd: failed to assign an IP address to container
Vpc-resource-controller failed to allocate branch ENI to pod: creating network interface, NoCredentialProviders: no valid providers in chain.Deprecated."

此错误响应可能表明 health.kubernetes 控制面板存在问题。要解决此问题,请联系 AWS Support

相关信息

我如何解决 Amazon EKS 的 kubelet 或 CNI 插件问题?

如何对 Amazon EKS 中的 OIDC 提供商和 IRSA 问题进行故障排除?

如何排查 Amazon EKS 中的 IRSA 错误?

配置 Amazon VPC CNI 插件以使用 IRSA - Amazon EKS

服务账户的 IAM 角色

2评论

在eks(v1.30)node 上部署deployment报错:Failed to create pod sandbox: rpc error: code = Unknown desc = failed to get sandbox image ".dkr.ecr.us-west-1.amazonaws.com/eks/pause:3.5": failed to pull image ".dkr.ecr.us-west-1.amazonaws.com/eks/pause:3.5": failed to pull and unpack image ".dkr.ecr.us-west-1.amazonaws.com/eks/pause:3.5": failed to resolve reference ".dkr.ecr.us-west-1.amazonaws.com/eks/pause:3.5": pull access denied, repository does not exist or may require authorization: authorization failed: no basic auth credentials


解决方案: 因为 containerd 无法获取 ECR 凭证来拉取沙箱容器映像。您可以 systemctl restart sandbox-image 来触发拉取,但仍然需要调查为什么image被删除。 比如可能的原因: 1.使用在每个节点上运行的自定义脚本来清理节点上未使用的图像并退出容器,这也将删除节点上的pause image。可以修改脚本,排除节点上的一些image。 2.使用类似 crictl rmi --prune命令手动删除了image,应避免类似操作,交由kubelet进行image回收。

kubelet 会每两分钟对未使用的镜像执行一次垃圾收集, 每分钟对未使用的容器执行一次垃圾收集。 你应该避免使用外部的垃圾收集工具,因为外部工具可能会破坏 kubelet 的行为,移除应该保留的容器。

AWS
支持工程师
已回复 1 年前

感谢您的评论。我们将会根据需要审核和更新知识中心文章。

AWS
审核人员
已回复 1 年前