Docker Engine 29.9.x 运维笔记:--link-local-ip 开始校验、firewalld 桥接恢复与 lazy-pull 开关
版本说明来源:Docker Engine 29 release notes
29.9.1 和 29.9.0 这两个版本改动不少,以下只挑上线后会直接碰到的几处:容器创建参数被新校验拦住、firewalld 自定义 zone 下桥接网络起不来、fluentd 异步日志把 daemon 打崩、containerd image store 的拉取行为变化,以及 overlay 加密的 SA 泄漏。
29.9.1(2026-10-14)
内置 containerd 更新到 v2.4.2,涉及三处拉取路径的问题:transfer service 在子 descriptor 带 io.containerd.manifest.subject 注解且 digest 畸形时崩溃(CVE-2026-95839);开启 concurrent_layer_fetch_buffer 并发拉层时,恶意 registry 返回伪造 Content-Length 可导致崩溃(GHSA-8647-2jxj-p2rc);入站层数据在校验前未按声明大小限流,可被打满宿主磁盘(GHSA-hc94-p972-ch66)。升级后用 docker info 确认 containerd 版本落在 2.4.2。
--link-local-ip 不再接受任意地址
之前 docker create 或 docker network connect 传 --link-local-ip 时不做地址归属校验,随手写一个 10.0.0.5 也能创建成功,容器随后启动失败,报错点还不在参数上。现在创建容器或接入网络时就会校验:地址必须属于 169.254.0.0/16 或 fe80::/10(moby/moby#53923)。
# 合法
docker run --rm --link-local-ip 169.254.10.10 alpine ip addr
docker run --rm --link-local-ip fe80::1 alpine ip addr
# 现在会在 create 阶段直接拒绝
docker run --rm --link-local-ip 10.0.0.5 alpine true
有脚本按模板批量传 --link-local-ip 的,升级前先扫一遍取值来源。
firewalld zone 不是 docker 时,桥接网络恢复失败
两个相关修复都在 moby/moby#53907:
- 桥接网络绑定的 firewalld zone 不是
docker时,daemon 重启后这些网络恢复失败。现场表现是 daemon 起来后部分 bridge 网络缺失,依赖它们的容器起不来。 iptables和ip6tables同时禁用时,不再把 bridge 接口塞进 firewalld 的dockerzone。
用了自定义 zone(比如 internal、trusted)接桥接网卡的机器,升级后先确认网络是否完整恢复:
firewall-cmd --get-active-zones
firewall-cmd --zone=docker --list-all
docker network ls
firewall-backend 是 29.0.0 引入的 daemon 选项,默认仍是 iptables,nftables 后端为实验性。它与上面这组 firewalld 行为直接相关,切换前先在非生产节点验证:
{
"firewall-backend": "nftables"
}
fluentd + TLS + fluentd-async 导致 daemon panic
日志驱动设为 fluentd、地址是 TLS 且连不上、同时开了 fluentd-async 时,daemon 会 panic(moby/moby#53922)。对应配置形态:
{
"log-driver": "fluentd",
"log-opts": {
"fluentd-address": "tls://fluentd.example.com:24224",
"fluentd-async": "true"
}
}
fluentd 侧证书过期或网络抖动时,这类配置会把问题从“日志投递失败”放大成“daemon 崩溃”。升级到 29.9.1 即可。
其他修复
- 经典 builder 在 userns-remap 开启时,
COPY --from对非 root 属主文件失败(moby/moby#53859)。 - 单个容器大小算不出来时,
docker ps -s和带 size 的容器列表整体失败(moby/moby#53921)。 - graph-driver image store 下,镜像内同一层出现多次时,
docker save在镜像删除后仍把层留在磁盘(moby/moby#53927)。 - registry mirror 成功但后续 registry 查询失败时,digest 解析失败(moby/moby#53933)。
- 插件信息获取失败时,插件权限查询仍返回成功(moby/moby#53934)。
- rootless + user namespace 下
--domainname修复,需要支持domainname字段的 OCI runtime(如 runc >= v1.2.0)(moby/moby#53899)。RootlessKit 升到 v3.3.0(moby/moby#53942)。
29.9.0(2026-10-08)
Go 运行时带来的 HTTP/2 修复,影响 2375/2376
这一版随 Go 1.26.9 修掉一组 HTTP/2 问题,受影响的是 daemon 暴露在 TCP 上的 API,即 2375(明文)和 2376(TLS):
- 客户端在发请求时改 HPACK header table 大小,可让 daemon 崩溃(golang/go#81867)。
Trailer头里声明大量字段可绕过 header 大小限制,耗尽 daemon 内存(golang/go#81857)。- 客户端重置 stream 可绕过连接级流控(golang/go#81743)。
- 打开大量 stream 并反复修改 initial window size,可造成 daemon CPU 占用过高(golang/go#81742)。
- Windows 上,对数据根目录有写权限的人放置 junction 后,daemon 可在数据根之外创建目录(golang/go#81739)。
golang.org/x/net 升到 v0.60.0,把同样的 HTTP/2 修复带到已弃用的 /grpc 端点,以及 BuildKit 为 frontend 容器(# syntax= 指令引用的镜像)启动的 gRPC server。
把 daemon 端口暴露到非受信网络的部署,这一版应当尽快跟上:
{
"hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"],
"tls": true,
"tlscacert": "/etc/docker/ca.pem",
"tlscert": "/etc/docker/server-cert.pem",
"tlskey": "/etc/docker/server-key.pem"
}
containerd image store:lazy-pull 开关
新增 lazy-pull daemon feature,控制 docker pull 是否跳过 snapshotter 已经提供的层内容(moby/moby#53877)。对已知的 remote snapshotters(nydus、overlaybd、soci、stargz)默认开启。需要强制完整下载时:
{
"features": {
"containerd-snapshotter": true,
"lazy-pull": false
}
}
解包层已存在时跳过必要 blob,镜像不完整
pull 在解包层已存在的场景下会跳过必需的层 blob,结果镜像能正常运行,但 docker save 导出或 push 时内容不完整(moby/moby#53615)。这类问题在 CI 里表现为:本地跑得好好的缓存镜像,推到 registry 或导出成 tar 之后缺层。升级后对缓存镜像做一次 docker save / push 验证即可确认。
IPsec overlay:最后一个容器离开时释放 SA
最后一个容器离开加密 overlay 网络时,节点的 IPsec security association 和 policy 现在会被释放,不再泄漏到 daemon 重启(moby/moby#53420)。同一 PR 还修了另一处:内核加密 overlay 数据面编程出错时,部分节点间的加密 overlay 流量可能以明文发出,范围限于单向流,例如 UDP DNS 查询和 TCP SYN 握手。验证时可在容器全部退出后查看:
ip xfrm state
ip xfrm policy
网络与运行时相关修复
- ICC(容器间通信)禁用时,桥接网络上的容器之间允许 IPv6 邻居发现,与 IPv4 行为一致(moby/moby#53723)。
- routed gateway 模式下,
docker ps和GET /containers/json漏掉 published 端口(moby/moby#53693)。 - daemon 重启后从 peer 的服务发现和负载均衡中被摘除,直到重新加入 gossip 集群(moby/moby#53688)。
- ICC 禁用时同网络内其它容器访问不到 published 端口,包含通过 routing mesh 发布的 Swarm 服务(moby/moby#53723)。
- 已用 implicit
host-gateway映射的 live-restore 容器接入额外网络的问题(moby/moby#53093)。 - VXLAN 设备已学到 peer 的动态 FDB 条目时,节点重新加入集群或服务重新部署后 peer 不可达(moby/moby#53663)。
- daemon 无法写入
/var/lib/docker时,overlay 网络上的 Swarm 任务被拒(moby/moby#53848)。 - userland proxy 开启时,Swarm 服务 published 端口可从宿主 IPv6 地址访问;自 v29.9.0 起测试并支持(moby/moby#53727)。
- 恢复清理 Docker Engine 28.0.0 及更早版本遗留的空
DOCKER-INGRESSiptables 链和 FORWARD 规则(moby/moby#53825)。
其余:docker container create --name 名称超长时报“含非法字符”的误导性校验错误(moby/moby#53484);rootless 模式每次 GET /version 泄漏一个 RootlessKit API socket 连接(moby/moby#53836);Windows 服务注册/注销清理改进,--unregister-service 幂等(moby/moby#53845)。打包版本:BuildKit v0.34.0、Go 1.26.9、containerd(静态二进制)v2.4.1。RootlessKit 3.2.0。
更早版本要点
29.8.2(2026-09-30,仅安全修复):BuildKit 0.33.1、containerd 2.3.6、runc 1.5.2。包含构造 OCI image index(嵌套/扇出 descriptor)导致无界 CPU/内存(CVE-2026-53493)、恶意 DNS 响应使 registry 连接跳过 TLS 校验或回落到 HTTP(CVE-2026-92543)、Swarm 节点上非特权用户向加密 overlay 网络注入伪造以太帧(CVE-2026-92542),以及多项 BuildKit LLB 问题。
29.8.0(2026-09-03):
- 新增
HostConfig.Umask和docker create/run --umask,作用于主进程、exec 与健康检查(moby/moby#53463)。 - awslogs 支持附加 service name、environment 与自定义 CloudWatch entity 属性(moby/moby#52632)。
- daemon 支持配置默认容器 AppArmor profile 模板(moby/moby#52771)。
- 阻止容器通过 32 位
socketcall(2)创建AF_VSOCKsocket 与宿主 VM 通信(AppArmor/SELinux 规则)(moby/moby#53551)。 - 保留网络名
container与container:(moby/moby#51973)。 - Go SDK 最低支持 Go 1.26。
- 容器列表支持
annotation过滤器(moby/moby#53538)。 - 修复 start interval 大于 start period 时健康检查被延迟(moby/moby#52317)。
- 修复 btrfs 存储驱动下容器根
/为全局可写(moby/moby#53500)。
29.0.0(2025-11-10,破坏性变更):全新安装默认使用 containerd image store(userns-remap 的 daemon 除外);daemon 要求 API v1.44+(Docker v25.0+);cgroup v1 弃用,支持至少到 2029 年 5 月;CLI 移除 Docker Content Trust;通过 daemon 的 firewall-backend 选项提供实验性 nftables;Go module github.com/docker/docker 弃用,改用 github.com/moby/moby/client 和 /api。