7.3. CRI-O 容器运行时问题故障排除
7.3.1. 关于 CRI-O 容器运行时引擎
CRI-O 是 Kubernetes 的原生容器引擎实现,可与操作系统紧密集成来提供高效和优化的 Kubernetes 体验。CRI-O 容器引擎作为 systemd 服务在每个 OpenShift Container Platform 集群节点上运行。
当出现容器运行时问题时,验证每个节点上的 crio
systemd 服务的状态。从具有容器运行时问题的节点收集 CRI-O journald 单元日志。
7.3.2. 验证 CRI-O 运行时引擎状态
您可以在每个集群节点上验证 CRI-O 容器运行时引擎状态。
先决条件
-
您可以使用具有
cluster-admin
角色的用户访问集群。 -
已安装 OpenShift CLI(
oc
)。
流程
通过在节点上查询 debug pod 中的
crio
systemd 服务来查看 CRI-O 状态。为节点启动 debug pod:
$ oc debug node/my-node
将
/host
设为 debug shell 中的根目录。debug pod 在 pod 中的/host
中挂载主机的 root 文件系统。将根目录改为/host
,您可以运行主机可执行路径中包含的二进制文件:# chroot /host
注意运行 Red Hat Enterprise Linux CoreOS(RHCOS)的 OpenShift Container Platform 4.16 集群节点不可变,它依赖于 Operator 来应用集群更改。不建议使用 SSH 访问集群节点。但是,如果 OpenShift Container Platform API 不可用,或 kubelet 在目标节点上无法正常工作,
oc
操作将会受到影响。在这种情况下,可以使用ssh core@<node>.<cluster_name>.<base_domain>
来访问节点。检查
crio
systemd 服务在该节点上是否活跃:# systemctl is-active crio
输出更详细的
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 机器的完全限定域名。
流程
收集 CRI-O journald 单元日志。以下示例从所有 control plane 节点(在集群中)收集日志:
$ oc adm node-logs --role=master -u crio
从特定节点收集 CRI-O journald 单元日志:
$ oc adm node-logs <node_name> -u crio
如果 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.16 集群节点不可变,它依赖于 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/<node_name>
在节点上启动 debug shell,因为容器运行时实例 (crio
) 无法正常工作。
按照以下步骤完全擦除 CRI-O 存储并解决错误。
先决条件
-
您可以使用具有
cluster-admin
角色的用户访问集群。 -
已安装 OpenShift CLI(
oc
)。
流程
在节点上使用
cordon
。这是为了避免在节点处于Ready
状态时调度任何工作负载。当您的 Status 部分中存在SchedulingDisabled
时代表调度被禁用:$ oc adm cordon <node_name>
以 cluster-admin 用户身份排空节点:
$ oc adm drain <node_name> --ignore-daemonsets --delete-emptydir-data
注意pod 或 pod 模板的
terminationGracePeriodSeconds
属性控制安全终止的时间。此属性的默认值为 30 秒,但可以根据需要针对每个应用程序进行自定义。如果设置的值大于 90 秒,则 pod 可能会标记为SIGKILL
,且无法成功终止。当节点返回时,通过 SSH 或控制台连接节点。然后连接到 root 用户:
$ ssh core@node1.example.com $ sudo -i
手动停止 kubelet:
# systemctl stop kubelet
停止容器和 pod:
使用以下命令停止
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
停止所有其他 pod:
# crictl rmp -fa
手动停止 crio 服务:
# systemctl stop crio
运行这些命令后,您可以完全擦除临时存储:
# crio wipe -f
启动 crio 和 kubelet 服务:
# systemctl start crio # systemctl start kubelet
如果 crio 和 kubelet 服务启动,且节点处于
Ready
状态时,代表清理操作已正常工作:$ oc get nodes
输出示例
NAME STATUS ROLES AGE VERSION ci-ln-tkbxyft-f76d1-nvwhr-master-1 Ready, SchedulingDisabled master 133m v1.29.4
将节点标记为可以调度。当状态中不再有
SchedulingDisabled
时代表启用了调度:$ oc adm uncordon <node_name>
输出示例
NAME STATUS ROLES AGE VERSION ci-ln-tkbxyft-f76d1-nvwhr-master-1 Ready master 133m v1.29.4