
Containerd 的 Bug 导致容器被重建!如何避免?
最近我们关注到一个关于 containerd 运行时的 issue
(https://github.com/containerd/containerd/issues/7843),该问题在 containerd v1.6.9/v1.5.15 被引入。出现的问题是,当 containerd 重启后,在其中运行的 Pod 元数据中关于网络相关的数据(如 pod ip)丢失,核心原因在于部分数据没有落盘。
受影响的版本:
- v1.6.9 ~ v1.6.14,问题在 v1.6.15 版本中被修复。
- v1.5.15 ~ v1.5.16,问题在 v1.5.17 版本中被修复。
通过以下步骤,可以快速重现该问题,并验证该问题的修复情况。
本文使用 rke2 为例进行演示,版本为 rke2 v1.24.9+rke2r1,该版本使用了 k3s-containerd v1.6.12-k3s1,受该 containerd 问题影响。
在 containerd 的默认行为中,重启 containerd 服务不会影响正在运行的业务容器,并在启动容器时,通过将容器父进程绑定 Pid 1 的方式进行体现。即使使用 systemctl 对服务进行重启,也不会影响到已经在运行的容器状态。
—— 问题重现 ——
至此,rke2 单节点服务启动完成,但我们的目标是 containerd,接下来继续操作:
我们以 metrics-server 的 pod 为例,查询 pod 详情中的网络部分内容,并对 containerd 进行重启,对问题进行重现:
通过新的 terminal,使用 crictl 查询 containerd 运行状态
从最后的返回结果可以看出,containerd 重启后容器的 IP 丢失。
—— 问题影响 ——
通过在上述例子中重启 rke2-server 可以看到,由于 ip 信息丢失,导致了业务容器被重建,带来了业务中断的风险。
可以看到,在 rke2-server 重启后,使用了 cni 的 pod 发生了重启,在 crictl pods 返回中可以看到重新创建的 pods。
—— 问题修复验证 ——
下载新版本 containerd,这次验证使用 k3s-containerd v1.6.14+k3s1。该版本为 Rancher 在 containerd v1.6.15 发布前紧急发布的修复补丁版本。
通过新的 terminal,使用 crictl 查询 containerd 运行状态
可以看到 containerd 重启后,pod ip 没有丢失。
—— RKE2 与 RFO ——
RKE2 以下版本受该 issue 影响:
- v1.23.15+rke2r1
- v1.24.9+rke2r1
- v1.25.5+rke2r1
- v1.26.0+rke2r1
该 issue 在 2022 年 12 月 20 日被提交,RKE2 团队在 2023 年 1 月 6 日紧急合并了 containerd 中修复该 issue 的 commit,发布了 k3s-containerd v1.6.14+k3s1 版本,并发布了新的 rke2 rc 版本进行测试验证。
最终在 1 月 11 日,RKE2 团队发布以下已经修复 containerd 问题的版本:
- v1.23.16+rke2r1
- v1.24.9+rke2r2
- v1.25.5+rke2r2
- v1.26.0+rke2r2
RFO 是 Rancher For openEuler 的缩写,顾名思义,目的在于面向 openEuler 打造 Rancher 基础平台。
由于 RFO 版本发布周期在 RKE2 之后,RFO 并没有受到该 issue 影响,并在近期发布了以下版本:
- v1.23.16+rfor1
- v1.24.9+rfor1
- v1.24.10+rfor1
- v1.25.5+rfor1
- v1.25.6+rfor1
- v1.26.0+rfor1
- v1.26.1+rfor1
—— 写在最后 ——
由于操作系统的软件包发布存在一定的时间延后性,在大部分情况下都无法及时修复软件出现的问题。像 CVE、功能缺陷等问题都比较紧急,等待操作系统供应商提供修复版本将是一个漫长的过程,甚至有时候由于一些限制,操作系统提供商无法提供新版本的软件包,这会给系统运行带来不确定因素。
在这种情况下,将软件自身依赖的组件打包到自己的 rootfs 中进行分发,能更好地对其进行管理和升级,避免给系统运行带来风险以及潜在的损失。
关于 RFO 的项目说明和部署使用,请点击《Rancher RFO 正式 GA》。
文章转载自公众号:openEuler
