×

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

CRI-O 是一个 Kubernetes 原生容器引擎实现,它与操作系统紧密集成,以提供高效且优化的 Kubernetes 体验。CRI-O 容器引擎在每个 OpenShift Container Platform 集群节点上作为 systemd 服务运行。

当出现容器运行时问题时,请验证每个节点上 crio systemd 服务的状态。从出现容器运行时问题的节点收集 CRI-O journald 单元日志。

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

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

先决条件
  • 您可以作为具有 cluster-admin 角色的用户访问集群。

  • 您已安装 OpenShift CLI (oc)。

步骤
  1. 通过查询节点上调试 Pod 中的 crio systemd 服务来查看 CRI-O 状态。

    1. 为节点启动调试 Pod

      $ oc debug node/my-node
    2. /host 设置为调试 shell 中的根目录。调试 Pod 将主机的根文件系统挂载到 Pod 内的 /host 中。通过将根目录更改为 /host,您可以运行主机可执行路径中包含的二进制文件

      # chroot /host

      运行 Red Hat Enterprise Linux CoreOS (RHCOS) 的 OpenShift Container Platform 4.17 集群节点是不可变的,并依赖于 Operators 来应用集群更改。不建议使用 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

收集 CRI-O journald 单元日志

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

先决条件
  • 您可以作为具有 cluster-admin 角色的用户访问集群。

  • 您的 API 服务仍在运行。

  • 您已安装 OpenShift CLI (oc)。

  • 您拥有控制平面或控制平面机器的完全限定域名。

步骤
  1. 收集 CRI-O journald 单元日志。以下示例从所有控制平面节点(在集群内)收集日志

    $ 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.17 集群节点是不可变的,并依赖于 Operators 来应用集群更改。不建议使用 SSH 访问集群节点。在尝试通过 SSH 收集诊断数据之前,请先查看运行oc adm must gather和其他oc命令收集的数据是否足够。但是,如果 OpenShift Container Platform API不可用,或者目标节点上的 kubelet 运行不正常,则oc操作将受到影响。在这种情况下,可以使用ssh core@<node>.<cluster_name>.<base_domain>访问节点。

清理 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/<node_name>在节点上启动调试 shell,因为容器运行时实例 (crio) 运行不正常。

请按照此流程完全清除 CRI-O 存储并解决错误。

先决条件
  • 您可以作为具有 cluster-admin 角色的用户访问集群。

  • 您已安装 OpenShift CLI (oc)。

步骤
  1. 对节点使用cordon。这样做是为了避免在节点进入Ready状态时调度任何工作负载。当您的状态部分显示SchedulingDisabled时,您就知道调度已禁用。

    $ oc adm cordon <node_name>
  2. 以集群管理员用户身份驱逐节点

    $ oc adm drain <node_name> --ignore-daemonsets --delete-emptydir-data

    Pod 或 Pod 模板的terminationGracePeriodSeconds属性控制优雅终止周期。此属性默认为 30 秒,但可以根据需要为每个应用程序自定义。如果设置为超过 90 秒,则 Pod 可能会被标记为SIGKILLed并且无法成功终止。

  3. 节点恢复后,通过 SSH 或控制台重新连接到节点。然后连接到 root 用户。

    $ ssh [email protected]
    $ 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.30.3
  10. 标记节点可调度。当SchedulingDisabled不再显示在状态中时,您就知道调度已启用。

    $ oc adm uncordon <node_name>
    示例输出
    NAME				     STATUS	      ROLES    AGE    VERSION
    ci-ln-tkbxyft-f76d1-nvwhr-master-1   Ready            master   133m   v1.30.3