Docker Engine 29 升级:API 1.52 抬高最低版本,网络与 Go SDK 也要跟着改
Docker Engine 29 的变更集中在三块:API 版本门槛、网络默认行为、Go SDK 接口。对运维来说,影响最大的是旧客户端直接连不上;对写 Docker API 或 Go SDK 的人来说,则是一次成规模的签名重构。发布说明见 Docker Engine 29 release notes,代码与发行包在 moby/moby docker-v29.0.0。
API 版本:1.52,最低支持 v1.44
Engine 29 的 API 版本升到 1.52,同时 daemon 的最低支持 API 版本抬到 v1.44(对应 Docker 25.0)。客户端也不再协商低于 v1.44 的版本。
这意味着 API v1.24 及更老的客户端无法与 Docker 29 daemon 通信,报错通常是:
client is too old
Error response from daemon: unsupported API version
典型例子是 Portainer:2.33.5 之前的版本把 API 版本硬编码到 1.41,Docker 29 会直接拒绝这些连接,表现为环境加载失败、请求全部报错。升级 Docker 前,先把这类管理面板升到 2.33.5 或更高。
新安装默认使用 containerd image store
从 v29 起,新安装默认用 containerd image store 管理镜像层与内容。legacy graph driver 仍然保留,遇到问题时新安装也可以显式退回。已有环境不受这条默认值影响,但新机器上的镜像存储路径、内容寻址方式会和旧文档描述不一致。
网络行为变化
nftables 与 IP forwarding
Docker 不再自动开启主机 IP forwarding。bridge 网络需要转发但主机未开启时,daemon 启动或网络创建会直接失败。
两种处理方式:
- 开启转发,并确保防火墙规则到位;
- 或者给 daemon 加
--ip-forward=false跳过这项检查,但端口转发等 bridge 网络功能可能失效。
另外,daemon 动态链接时现在依赖 libnftables;新增 daemon 选项 --bridge-accept-fwmark;docker info 在可用时会报告 firewall backend。firewalld 在 bridge 驱动启动、创建网络或端口映射期间 reload 导致的死锁也已修复。
legacy links 环境变量
通过 legacy links 注入到容器的环境变量默认不再自动添加。需要临时恢复时,启动 daemon 时带上:
DOCKER_KEEP_DEPRECATED_LEGACY_LINKS_ENV_VARS=1
这个开关是临时逃生口,后续版本会移除。
iptables 与 macvlan/IPvlan
- bridge 网络的 iptables 规则有更新,
DOCKER-ISOLATION-STAGE-1和DOCKER-ISOLATION-STAGE-2链被移除。自定义规则如果引用这两条链,需要同步调整。 - macvlan 和 IPvlan-l2 网络不再默认配置网关,除非 IPAM 配置里显式给出
--gateway。 - 用于 SCTP checksum 的 mangle 规则移除,环境变量
DOCKER_IPTABLES_SCTP_CHECKSUM不再生效。 - 关闭 userland-proxy 时,容器可以访问其他网络容器发布到主机地址的端口;gateway mode 为
nat-unprotected时,容器可以访问其他网络容器地址上的端口。 - gateway mode 为
routed的网络中,published ports 始终可访问。
HTTP API 变更
GET /events的 content-type 变为application/x-ndjson;API 1.52+ 下不再返回已弃用的status、id、from字段。GET /images/{name}/get与POST /images/load接受多个platform查询参数。GET /images/{name}/json省略为空的Parent、Comment、DockerVersion、Author,以及为空的Config字段。POST /images/{name}/push移除了对请求体中 API v1.4 auth-config 的兼容。api/types/container中MacAddress在 v1.52+ 已废弃,改用 network endpoint settings。api/types/swarm的PortConfigProtocol弃用并移除,改用network.IPProtocol。- 启动容器时自动用空
HostIP/HostPort回填PortBindings的行为在 API 1.52 弃用,1.53 移除。 - API 1.52+ inspect 网络会返回 IPAM 分配统计。
- MAC 地址字段改为与
net.HardwareAddr兼容的 byte slice。 - Swarm 服务与任务新增
SwapBytes、MemorySwappiness。
Go SDK:参数改 option struct,返回值改结果类型
这是升级时改动量最大的部分:
- 最低 Go 版本提高到 1.24;
moby/moby的 api 模块成为公开 API。 - 大量方法从位置参数改成 option struct,并返回专门的结果类型,涉及
Client.ConfigCreate/List/InspectWithRaw/Update/Remove,以及ImageBuild/BuildCancel/ImageList/ImageRemove/ImageTag/ImageSearch。 ContainerExec...系列方法改名为Exec...。ImageInspect、ImageHistory、ImageLoad、ImageSave的返回值包进 struct。ImagePull/ImagePush返回带JSONMessages方法的对象,该方法返回迭代器。- IP 地址与子网类型改为
netip.Addr、netip.Prefix。 - client 使用自己的
client.Filters类型,原先用api/types/filters的代码需要重构。 - 移除
NetworkSettingsBase、DefaultNetworkSettings;network.Summary/Inspect不再 alias,字段移入嵌入 struct。 - 移除
api/pkg/progress、api/pkg/streamformatter;client.ImageCreate移除,改用ImagePull或ImageImport;api/types/plugin的Config.DockerVersion、api/types/registry的AuthConfig.Email移除。
弃用项
cgroup v1 弃用。docker commit 的 --pause 标志弃用,改用 --no-pause。
升级前检查清单
先确认 daemon 与客户端各自的 API 版本:
docker version
docker version --format '{{.Server.APIVersion}}'
curl -s --unix-socket /var/run/docker.sock http://localhost/version | jq .ApiVersion
确认网络前提:
docker info | grep -i firewall
sysctl net.ipv4.ip_forward
逐项核对:
- 所有调用方(Portainer、自研面板、SDK 客户端)使用的 API 版本不低于 v1.44;Portainer 升到 2.33.5+。
- 主机
net.ipv4.ip_forward已开启,防火墙规则与 nftables 后端匹配;否则准备好--ip-forward=false的取舍。 - 是否依赖 legacy links 注入的环境变量;如果是,先加
DOCKER_KEEP_DEPRECATED_LEGACY_LINKS_ENV_VARS=1,并排期改造。 - 自定义 iptables 规则是否引用
DOCKER-ISOLATION-STAGE-1/2。 - macvlan/IPvlan-l2 网络的 IPAM 配置是否显式写了
--gateway。 - Go 项目升到 1.24,按 option struct、
Exec...、netip、client.Filters逐项适配。 - 确认主机运行在 cgroup v2 上。