7.3. CRI-O 容器运行时问题故障排除

7.3.1. 关于 CRI-O 容器运行时引擎

CRI-O 是 Kubernetes 的原生容器运行时实现,可与操作系统紧密集成来提供高效和优化的 Kubernetes 体验。CRI-O,提供用于运行、停止和重启容器的工具。

CRI-O 容器运行时引擎由在每个 OpenShift Container Platform 集群节点上使用 systemd 服务进行管理。当出现容器运行时问题时,验证每个节点上的 crio systemd 服务的状态。从清单容器运行时问题的节点收集 CRI-O journald 单元日志。

7.3.2. 验证 CRI-O 运行时引擎状态

您可以在每个集群节点上验证 CRI-O 容器运行时引擎状态。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 已安装 OpenShift CLI(oc)。

流程

  1. 通过在节点上查询 debug pod 中的 crio systemd 服务来查看 CRI-O 状态。

    1. 为节点启动 debug pod:

      $ oc debug node/my-node
    2. /host 设为 debug shell 中的根目录。debug pod 在 pod 中的 /host 中挂载主机的 root 文件系统。将根目录改为 /host,您可以运行主机可执行路径中包含的二进制文件:

      # chroot /host
      注意

      运行 Red Hat Enterprise Linux CoreOS(RHCOS)的 OpenShift Container Platform 4.10 集群节点不可变,它依赖于 Operator 来应用集群更改。不建议使用 SSH 访问集群节点。但是,如果 OpenShift Container Platform API 不可用,或 kubelet 在目标节点上无法正常工作, oc 操作将会受到影响。在这种情况下,可以使用 ssh core@<node>.<cluster_name>.<base_domain> 来访问节点。

    3. 检查 crio systemd 服务在该节点上是否活跃:

      # systemctl is-active crio
    4. 输出更详细的 crio.service 状态概述:

      # systemctl status crio.service

7.3.3. 收集 CRI-O journald 单元日志

如果遇到 CRI-O 问题,您可以从节点获取 CRI-O journald 单元日志。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • API 服务仍然可以正常工作。
  • 已安装 OpenShift CLI(oc)。
  • 您有 control plane 或 control plane 机器的完全限定域名。

流程

  1. 收集 CRI-O journald 单元日志。以下示例从所有 control plane 节点(在集群中)收集日志:

    $ oc adm node-logs --role=master -u crio
  2. 从特定节点收集 CRI-O journald 单元日志:

    $ oc adm node-logs <node_name> -u crio
  3. 如果 API 无法正常工作,使用 SSH 来查看日志。将 <node>.<cluster_name>.<base_domain> 替换为适当的值:

    $ ssh core@<node>.<cluster_name>.<base_domain> journalctl -b -f -u crio.service
    注意

    运行 Red Hat Enterprise Linux CoreOS(RHCOS)的 OpenShift Container Platform 4.10 集群节点不可变,它依赖于 Operator 来应用集群更改。不建议使用 SSH 访问集群节点。在尝试通过 SSH 收集诊断数据前,请运行 oc adm must gather 和其他 oc 命令看它们是否可以提供足够的数据。但是,如果 OpenShift Container Platform API 不可用,或 kubelet 在目标节点上无法正常工作, oc 操作将会受到影响。在这种情况下,可以使用 ssh core@<node>.<cluster_name>.<base_domain> 来访问节点。

7.3.4. 清理 CRI-O 存储

如果遇到以下问题,您可以手动清除 CRI-O 临时存储:

  • 节点无法在任何 pod 上运行,并出现以下错误:

    Failed to create pod sandbox: rpc error: code = Unknown desc = failed to mount container XXX: error recreating the missing symlinks: error reading name of symlink for XXX: open /var/lib/containers/storage/overlay/XXX/link: no such file or directory
  • 您无法在工作节点上创建新容器,并出现 “can’t stat lower layer” 错误:

    can't stat lower layer ...  because it does not exist.  Going through storage to recreate the missing symlinks.
  • 在集群升级后或尝试重启节点时,您的节点处于 NotReady 状态。
  • 容器运行时实施 (crio) 无法正常工作。
  • 您无法使用 oc debug node/<nodename> 在节点上启动 debug shell,因为容器运行时实例 (crio) 无法正常工作。

按照以下步骤完全擦除 CRI-O 存储并解决错误。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 已安装 OpenShift CLI(oc)。

流程

  1. 在节点上使用 cordon。这是为了避免在节点处于 Ready 状态时调度任何工作负载。当您的 Status 部分中存在 SchedulingDisabled 时代表调度被禁用:

    $ oc adm cordon <nodename>
  2. 以 cluster-admin 用户身份排空节点:

    $ oc adm drain <nodename> --ignore-daemonsets --delete-emptydir-data
    注意

    pod 或 pod 模板的 terminationGracePeriodSeconds 属性控制安全终止的时间。此属性的默认值为 30 秒,但可以根据需要针对每个应用程序进行自定义。如果设置的值大于 90 秒,则 pod 可能会标记为 SIGKILL,且无法成功终止。

  3. 当节点返回时,通过 SSH 或控制台连接节点。然后连接到 root 用户:

    $ ssh core@node1.example.com
    $ sudo -i
  4. 手动停止 kubelet:

    # systemctl stop kubelet
  5. 停止容器和 pod:

    1. 使用以下命令停止 HostNetwork 中没有的 pod。必须首先删除它们,因为它们依赖于 HostNetwork 中的网络插件 pod。

      .. for pod in $(crictl pods -q); do if [[ "$(crictl inspectp $pod | jq -r .status.linux.namespaces.options.network)" != "NODE" ]]; then crictl rmp -f $pod; fi; done
    2. 停止所有其他 pod:

      # crictl rmp -fa
  6. 手动停止 crio 服务:

    # systemctl stop crio
  7. 运行这些命令后,您可以完全擦除临时存储:

    # crio wipe -f
  8. 启动 crio 和 kubelet 服务:

    # systemctl start crio
    # systemctl start kubelet
  9. 如果 crio 和 kubelet 服务启动,且节点处于 Ready 状态时,代表清理操作已正常工作:

    $ oc get nodes

    输出示例

    NAME				    STATUS	                ROLES    AGE    VERSION
    ci-ln-tkbxyft-f76d1-nvwhr-master-1  Ready, SchedulingDisabled   master	 133m   v1.23.0

  10. 将节点标记为可以调度。当状态中不再有 SchedulingDisabled 时代表启用了调度:

    $ oc adm uncordon <nodename>

    输出示例

    NAME				     STATUS	      ROLES    AGE    VERSION
    ci-ln-tkbxyft-f76d1-nvwhr-master-1   Ready            master   133m   v1.23.0