IBM Cloud Docs
为什么我的容器不启动?

为什么我的容器不启动?

您注意到以下一个或多个问题:

  • 工作程序节点无法创建新的 pod。 Pod 成功部署到工作程序节点,但容器处于 ContainerCreating 状态。

  • 对处于 ContainerCreating 状态的 pod 运行 oc describe pod <pod> 时,您会看到类似于以下某个事件的事件。

    Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "XXX": failed to request 1 IPv4 addresses. IPAM allocated only 0
    
    desc = failed to create pod network sandbox ... error adding container to network "k8s-pod-network": cannot allocate new block due to per host block limit
    
  • 运行以下命令时,一个或多个 calico-node pod 无法在工作程序节点上启动,并且处于 CrashLoopBackOff 状态。

    oc logs -n calico-system <calico-node_pod>
    

    日志的最后一行包含以下消息:

    Unable to autoassign an address - pools are likely exhausted. type="ipipTunnelAddress"
    

如果未看到症状中列出的任何与 IP 地址相关的消息,那么容器可能无法启动,因为已达到注册表配额。

如果您看到症状中列出的任一与 IP 地址相关的消息,那么容器可能无法启动,因为 Calico 插件的 IP 地址管理器 (IPAM) 错误地检测到集群中的所有 pod IP 地址都在使用中。 因为 Calico IPAM 检测到没有可用的 IP 地址,所以它不会将 IP 地址分配给集群中的新 pod,并且 pod 无法启动。

修正注册表配额问题

虚拟私有云 经典基础架构

要解决注册表配额问题,请 在 IBM Cloud Container Registry 中释放存储器。

解决 IP 地址问题

虚拟私有云 经典基础架构

要解决 IP 地址问题,请释放未从 Calico IPAM 记录中完全除去的个别 IP 地址和 IP 地址块,以便可供集群中的 pod 复用。

集群必须运行 受支持的版本。 如果集群运行不推荐或不受支持的版本,请首先 更新集群

步骤 1: 释放单个 IP 地址

首先,检查并释放未从 Calico IPAM 记录中完全除去的个别 IP 地址,以便集群中的 pod 可以复用这些 IP 地址。

  1. 遵循 安装和配置 Calico CLI 中的步骤以下载 calicoctl 客户机的 V 3.18 或更高版本,对集群使用正确的 Calico 配置,并验证 Calico 配置是否对目标集群正常工作。 请注意,即使集群运行较旧版本的 Calico,您仍可以使用 calicoctl V 3.18 来运行以下步骤中的命令。

  2. 检查未正确检测到由 Calico IPAM 使用的任何 IP 地址。

    calicoctl ipam check
    
  3. 在输出中,查找包含行 Scanning for IPs that are allocated but not actually in use... 的部分。 如果 IP 地址是在 IPAM 中分配的,但实际上未在使用,请继续执行下一步以释放这些 IP 地址。 在此示例输出中,可以释放 181 个 IP 地址。

    ...
    Scanning for IPs that are allocated but not actually in use...
    Found 181 IPs that are allocated in IPAM but not actually in use.
    Scanning for IPs that are in use by a workload or node but not allocated in IPAM...
    Found 0 in-use IPs that are not in active IP pools.
    Found 0 in-use IPs that are in active IP pools but have no corresponding IPAM allocation.
    
    Check complete; found 181 problems.
    
  4. 释放先前分配给 pod 端点的 Calico IPAM 中的 IP 地址。 请注意,在以下步骤中锁定数据存储器后,现有 pod 将继续运行,但创建的任何 pod 仍处于 ContainerCreating 状态,直到解锁数据存储器后才能启动。 此数据存储器锁定可确保在发布 IP 地址时不会修改 IPAM 记录。 有关更多信息,请参阅 Calico 开放式源代码文档

    1. 锁定 Calico IPAM 记录的数据存储器。

      calicoctl datastore migrate lock
      
    2. 保存 IPAM 检查结果。

      calicoctl ipam check -o report.json
      
    3. 释放未使用的 IP 地址。 此进程最多可运行 20 分钟,具体取决于必须释放的 IP 地址数。

      calicoctl ipam release --from-report=report.json
      
    4. 解锁数据存储器。

      calicoctl datastore migrate unlock
      
    5. 验证是否释放了所有未使用的 IP 地址。

      calicoctl ipam check
      

      示例输出

      Check complete; found 0 problems.
      
  5. 可选: 要验证数据存储器是否已成功解锁并且 IP 地址现在可供分配,请创建 pod 并检查其是否正确启动。

    1. 例如,创建简单的 NGINX pod。
      oc run test --image=nginx --generator=run-pod/v1
      
    2. 验证 pod 是否具有 IP 地址并正在成功运行。
      oc get po test
      
    3. 删除测试 pod。
      oc delete pod test
      
  6. 继续下一节以检查未使用的 IP 地址块。

步骤 2: 释放 IP 地址块

接下来,检查并清除分配给工作程序节点但该工作程序节点未使用的整个 IP 地址块。

有时,当为工作程序节点分配第二个或第三个 IP 地址块时,工作程序节点先前使用的整个 IP 地址块稍后可能完全未使用。 此外,当您除去或更换工作程序节点时,Calico IPAM 对 IP 地址块的清除可能会失败,因为缺少工作程序节点可供 calico-kube-controllers 临时运行,或者由于在除去或更换工作程序节点时 CNI 插件或 containerd 运行时出现问题。

确保 IP 块可用对于运行 Kubernetes V 1.19 或更高版本的所有经典集群以及所有 VPC 集群都特别重要。 在这些集群中,strictAffinity Calico 设置设置为 true,这将强制工作程序节点仅使用其分配的 IP 块中的 IP 地址,而不是使用分配给其他工作程序节点的块中的 IP 地址。 随着时间的推移,分配给节点但未使用的块可能会累积,直到无法将更多 IP 地址块分配给工作程序节点为止。

  1. 执行以下步骤以 释放个别 IP 地址

  2. 选择是否锁定 Calico IPAM 记录的数据存储器。

    • 如果锁定数据存储器,那么现有 pod 将继续运行,但创建的任何 pod 仍处于 ContainerCreating 状态,直到解锁数据存储器后才能启动。 此数据存储器锁定可确保在检查未使用的块之后,但在释放这些块之前,无法创建 Pod。
    • 如果未锁定数据存储器,那么必须立即验证是否没有新 pod 使用了已删除的已发布块中的 IP 地址。
    calicoctl datastore migrate lock
    
  3. 列出 Calico IPAM 记录。 在输出中,查找具有 0 IPS IN USE 的块,这指示该块未由其分配的工作程序节点使用。

    calicoctl ipam show --show-blocks
    

    在此示例输出中,172.24.10.64/26 块没有正在使用的 IP 地址。

    ...
    Block    | 172.24.10.64/26  |        64 | 0 (0%)     | 64 (100%)  |
    ...
    
  4. 对于其中每个块,请完成以下步骤以释放该块。

    1. 验证当前没有任何 pod 使用块中的 IP 地址。
      oc get pods -A
      
    2. 获取块的 BlockAffinity。 将块中的句点和正斜杠替换为连字符 (-)。例如,对于块 172.24.10.64/26,以下命令的格式为 172-24-10-64-26
      oc get blockaffinity | grep <block>
      
    3. 删除 BlockAffinity
      oc delete blockaffinity <block_affinity>
      
    4. 获取块的 IPAMBlock。 将块中的句点和正斜杠替换为连字符 (-)。例如,对于块 172.24.10.64/26,以下命令的格式为 172-24-10-64-26
      oc get ipamblock | grep <block>
      
    5. 删除 IPAMBlock
      oc delete ipamblock <ipam_block>
      
    6. 如果在步骤 2 中未锁定数据存储器: 请检查在删除 BlockAffinityIPAMBlock 之前未直接创建任何 pod。 如果已创建 pod,那么必须再次删除此块的 BlockAffinityIPAMBlock。 然后,通过运行 oc delete pod <pod> 来删除在此块中使用 IP 地址的任何 pod,以便使用另一块中的 IP 地址重新创建 pod。
      oc get pods -A
      
    7. 对具有 0 IPS IN USE 的任何其他块重复这些步骤。
  5. 如果在步骤 2 中锁定了数据存储器: 请解锁数据存储器。

    calicoctl datastore migrate unlock