系统极客一直在努力
专注操作系统及软件使用技能

Docker Engine 29 发布:为未来容器生态奠定基础

Docker

Docker Engine 29 正式发布!虽然新版本并没有带来「一眼惊艳」的新功能,但它是一次扎实的底层基础工程升级——为 Docker 平台未来几年的技术演进打下了坚实基础。

本次更新的核心变化主要集中在架构优化、生态对齐和可维护性提升上:

  • 提升了最低 API 版本要求
  • Containerd 镜像存储在「新安」装时正式成为默认选项
  • Moby 项目全面迁移至 Go modules
  • 实验性支持 nftables

这些看似「偏底层」的改动,实际上直接影响着生态兼容性、长期可维护性、性能潜力,以及你未来能用上的新能力。

以下内容面向在 Linux 上直接运行 Docker Engine(社区版)的用户。如果你使用的是 Docker Desktop,这些更新也会在后续版本中自动集成,无需额外操作。

最低 API 版本上调:老版本正式退出历史舞台

随着 v25 之前 Docker 版本的「生命周期」正式结束,Docker Engine 29 将「最低支持 API 版本」提升到了 1.44(对应 Moby v25)。

如果你使用老旧的客户端连接新版 Docker Engine,可能会看到如下错误:

Error response from daemon: client version 1.43 is too old.
Minimum supported API version is 1.44, please upgrade your client to a newer version

简单来说,就是你的客户端太老,已经低于 Docker Engine 29 所要求的最低 API 版本。解决方法有两个方向:

  1. 升级客户端:把 Docker CLI 或其他使用 Docker API 的工具升级到支持 API v1.44+ 的版本。
  2. 临时下调引擎的最低 API 限制:可以显式覆盖「最小 API 版本」设置。
  • 在启动守护进程时指定:
DOCKER_MIN_API_VERSION=1.24 dockerd
  • /etc/docker/daemon.json中加入:
{
  "min-api-version": "1.24"
}

Containerd 镜像存储:从「选项」变成「默认」

背景:从内部组件到业界标准

  • Containerd 最初只是 Docker Engine 内部的核心组件,后来被拆分并捐赠给了 CNCF。如今,它已经成为事实上的「标准容器运行时」,被 Kubernetes 等主流平台广泛采用。
  • Docker 很早就开始使用 Containerd 来管理容器运行,但在「镜像层」和「内容存储」方面,一直沿用早期的 graph driver 机制。而在个这期间,Containerd 自身发展出了一套成熟的镜像内容存储与 snapshotter 框架,具备更强的模块化能力和更好的生态兼容性。

在过去一年中,Docker Desktop 已经将 Containerd 镜像存储作为默认选项,并经过了长时间的实际验证。到了 Docker Engine 29,这一策略正式下沉到 Moby 引擎层面:对于新安装的用户,Containerd 镜像存储已经成为默认选项

现实意义

这项变更就意味着从 v29 开始:

  • 全新安装的 Docker Engine 会默认使用 Containerd image store 作为镜像存储后端。
  • 旧的 graph driver 存储方式仍然可用,但已被标记为「弃用」。
  • 如果新环境有兼容性或特殊需求,仍可手动选择不启用 Containerd 镜像存储。

解锁新能力

  • 架构更简洁:容器运行和镜像存储统一基于 Containerd,减少了内部重复机制和系统复杂度。
  • 解锁一系列新能力
    • 更灵活的 snapshotter,比如提升 I/O 性能、支持按需加载等;
    • lazy pulling:按需拉取镜像内容,显著加快容器启动速度;
    • 远程内容存储;
    • P2P 分发等现代化镜像分发方案。
  • 生态对齐:与 Kubernetes 等基于 Containerd 的平台保持更高一致性,减少跨平台行为差异。
  • 面向未来:为镜像层处理、拉取/推送性能优化,以及分布式环境下的内容管理奠定基础。

本次默认变更只影响「新安装」的实例,已使用 graph driver 的现有环境不会被自动迁移。

Moby 全面迁移至 Go modules:清理技术债

从 2019 年起,Go modules 已经成为 Go 社区的事实标准。然而,Moby 项目此前仍沿用传统的 vendor 机制。这种「逆潮流而行」的做法带来了不少麻烦:

  • 主流工具链默认假设项目使用 Go modules,Moby 的例外需要不断打补丁、做适配;
  • 对贡献者而言,开发流程不够直观,无形中就抬高了参与门槛;
  • 与新版 Go 工具链及常规生态实践之间,存在微妙的兼容性问题。

继续抗拒 Go modules,本质上就是在给维护者和开发者「加戏」。

现在,Moby 代码库已全面迁移到 Go modules,通过go.mod统一管理依赖。这对整个生态来说都是一大利好:依赖 Moby/Docker Go 代码的工具现在能更轻松地集成和升级。依赖分析、安全扫描、CI/CD 构建流水线等环节,也能更自然地接入标准 Go 工作流。

实验性 nftables 支持

在 Linux 网络这一块,Docker Engine 29 带来了一个谨慎但重要的试探——实验性支持 nftables

  • 目前,Docker Engine 在 Linux 上为 bridge 和 overlay 网络创建防火墙规则时,主要依赖iptablesip6tables
  • 而在大多数现代 Linux 发行版中,这 2 个命令实际上已经指向iptables-nftip6tables-nft——系统会在后台将规则自动翻译成 nftables 格式。

这种兼容模式目前还能工作,但存在隐患:

  • 越来越多的发行版正在逐步淡化甚至弃用对「传统 iptables 接口」的原生支持;
  • Docker 不应该长期依赖一个「正在老化」的兼容层。

因此,是时候让 Docker 直接操作nftables了:

  • Docker Engine 29 新增了一个可选的实验性特性:启用后,Docker 将直接创建nftables规则,而不是通过 iptables 接口间接生成。
  • 如果你使用了DOCKER-USER链(这是 iptables 中供用户自定义规则的标准入口),需要特别注意规则迁移方式。
  • 在启用了 firewalld 的主机上,过去 Docker 会通过「direct」接口插入 iptables 规则——但该机制已经过时。在 nftables 模式下:
    • 规则将直接以原生 nftables 形式创建在对应的表和基础链中;
    • Docker 仍会为相关网络设备配置 firewalld 的 zone 和策略,但不再依赖已过时的 direct 接口;
    • 在未使用 firewalld 的主机上,同样会直接使用 nftables。

当前 nftables 支持仍然为「实验性」,不建议在关键生产环境中启用。此外,该功能目前不支持 Swarm:启用 Swarm 的节点无法同时开启 Docker Engine 的 nftables 模式。


总的来说,Docker Engine 29 更像是一次「内功心法」的升级——统一 Containerd 镜像存储、全面拥抱 Go modules、逐步摆脱对传统 iptables 的历史依赖,并通过提升最低 API 版本清理技术债。

这些底层变动,或许不会立马体现在某条新命令或炫目的功能上,但却会在未来几年时间里,转化为更稳定的生态、更快的迭代速度,以及你能真切感受到的容器体验提升。

赞(0)
分享到

评论 抢沙发