本文用于分析 containerd 如何升级到 2.0 版本。
containerd v2.0 在 2024.11.6 出了正式版本,也表明了该版本的主要目的。
containerd 2.x 的首个重要版本重点关注 containerd 核心功能集的持续稳定性,以及从 containerd 1.x 的轻松升级。该版本包括稳定上一个 1.x 版本中添加的新功能,以及删除 1.x 版本中废弃的功能。
通过 containerd-2.0.md 文档可以看到在这个新版本中存在大量的变更。下面重点关注一下平滑升级,以及我感兴趣的变化。
升级前检测
弃用警告已添加到自省服务的 ServerResponse
中 (/containerd.services.introspection.v1.Introspection/Server
) 和 ctr
工具中,通过 ctr deprecation list
命令可查看。
为了帮助用户过渡到 containerd 2.0,社区已决定将此功能回移植到 containerd 1.6 和 1.7 发布分支,以提供用户识别迁移 containerd 版本的障碍的工具。
在 containerd 版本 >= 1.6.27 和 >= 1.7.12 上运行的工作负载的管理员,可以查询其 containerd 服务器,以接收已标记为弃用并在关键路径上的功能的警告。使用 ctr
客户端,用户可以运行 ctr deprecations list
(并可选择传递 --format json
以获取机器可读的输出)。
例如 #9772 中标注的
# ctr deprecations list
ID LAST OCCURRENCE MESSAGE
io.containerd.deprecation/pull-schema-1-image 2024-02-06T11:28:37.765563957Z Schema 1 images are deprecated since containerd v1.7 and removed in containerd v2.0. Since containerd v1.7.8, schema 1 images are identified by the "io.containerd.image/converted-docker-schema1" label.
同样,在该 issue 中也说明了 ctr deprecations list
获取的列表不是持久化的,而是在 containerd 本次启动后的启用告警。因此这个命令最好在特定低版本(>= 1.6.27 和 >= 1.7.12)上运行一段时间后再进行检测。
一些配置中的告警必然每次都会报,但像 cri v1alaph2 API
和 Docker Schema 1
,本次containerd启动后没有使用就不会被检测到 ,需要特别注意。
需重点关注变更
守护进程配置版本 3
此版本增加了对 containerd 守护进程配置 version = 3
的支持。守护进程配置在启动时会自动迁移到最新版本。这确保以前的配置在未来的守护进程上继续工作;但是,建议迁移到最新版本以避免迁移并优化守护进程启动时间。有关更多详细信息,请参见发布文档中的 “守护进程配置”。
问题不大。自动升级
CRI 注册表属性已弃用
以下 [plugins."io.containerd.grpc.v1.cri".registry]
属性的支持已弃用,并将在未来的版本中移除。
- CRIRegistryMirrors(
mirrors
)属性。用户应迁移至使用 config_path。 - CRIRegistryAuths(
auths
)属性。用户应迁移至使用 ImagePullSecrets。 - CRIRegistryConfigs(
configs
)属性。用户应迁移至使用 config_path。
registry 配置是常用配置,需要特别关注。一般在配置 register mirror 和 私有镜像仓 都会大量用到本配置。实际移除将会在 containerd v2.1 (已经一推再推了) 。
CRI v1alpha2 API 已被移除
在 containerd v1.7 中已弃用,CRI v1alpha2 API 的支持已被移除。用户应迁移至使用 CRI v1。
这一条变更的重灾区是 kubernetes 用户。官方建议参考 “Kubernetes 支持” 矩阵,以验证其 Kubernetes 版本的支持情况。
从支持矩阵可以看到,v1alpha2
在 kubernetes 1.26 弃用,见Kubernetes v1.26: Electrifying | Kubernetes,v1
在 1.23版本开始支持,见 cri-api/README.md。
对 Kubernetes v1.31,kubelet 偏向于使用 CRI v1
版本。 如果容器运行时不支持 CRI 的 v1
版本,那么 kubelet 会尝试协商较老的、仍被支持的所有版本。 v1.31 版本的 kubelet 也可协商 CRI v1alpha2
版本,但该版本被视为已弃用。 如果 kubelet 无法协商出可支持的 CRI 版本,则 kubelet 放弃并且不会注册为节点。
所以不是 1.23 版本之前的 kubernetes,这一变更无须太过关心。(k8s都不升级,还会升级containerd???)
使用 ctr deprecations list
前下发个容器就能检测到。
Docker Schema 1 图像支持默认禁用
默认情况下,拉取 Docker Schema 1 (application/vnd.docker.distribution.manifest.v1+json
或 application/vnd.docker.distribution.manifest.v1+prettyjws
) 图像被禁用。用户应通过使用最新的 Docker 或 nerdctl+Buildkit 工具重建/推送其容器镜像进行迁移。可以通过为 containerd
(在 CRI 的情况下)和 ctr
设置环境变量 CONTAINERD_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE=1
重新启用以前的行为;但是,强烈建议用户迁移到 Docker Schema 2 或 OCI 镜像。未来的版本将完全移除对 Docker Schema 1 图像的支持。
老版本镜像就别用了。这个在上文说过,ctr deprecations list
不一定检测得到。建议删除所有镜像重新拉取后再检测 deprecations。
io_uring_*
系统调用默认被禁止
以下系统调用 (io_uring_enter
, io_uring_register
, 和 io_uring_setup
) 已从默认的 Seccomp 配置文件允许列表中移除。许多报告的 Linux 内核漏洞与 io_uring
有关,使用它无法推荐为默认允许列表的一部分。
找了一下 kubernetes 使用 Seccomp 的方法,如果还想使用,可以使用自定义列表:使用 seccomp 限制容器的系统调用 | Kubernetes
LimitNOFILE
配置已被移除
containerd 的资源限制(rlimits)由容器继承,因此守护进程的 LimitNOFILE
会影响容器内的 RLIMIT_NOFILE
。建议使用默认的 systemd LimitNOFILE
配置。
功能
参考资料
- Release containerd 2.0.0 · containerd/containerd · GitHub
- containerd/docs/containerd-2.0.md at release/2.0 · containerd/containerd · GitHub
- containerd/RELEASES.md at release/2.0 · containerd/containerd · GitHub
- deprecations list: `io.containerd.deprecation/pull-schema-1-image` is lost on restarting the daemon · Issue #9772 · containerd/containerd
- Deprecation warnings · Issue #9312 · containerd/containerd
- kubernetes/staging/src/k8s.io/cri-api/README.md at release-1.31 · kubernetes/kubernetes · GitHub
- Kubernetes v1.26: Electrifying | Kubernetes
- 使用 seccomp 限制容器的系统调用 | Kubernetes
- containerd 中的弃用警告 - 为 2.0 做好准备!-liangyuanpeng 的博客 | liangyuanpeng’s Blog