- Published on
Podman 6.0 — 移除 slirp4netns、CNI 和 cgroups v1;macOS 默认 provider 换成了 libkrun
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 引言 — 时隔27个月的大版本,以及悄悄变更的归属
- 先看移除清单 — 升级前检查自己的环境
- macOS — 默认 provider 变成了 libkrun
- pasta 独当一面的时代 —— 以及 Pesto 这个实验
- Quadlet —— 从 .app 文件到子目录
- Docker 兼容性改进 = 脚本行为的变化
- CVE-2026-57231 —— 如果你还在 5.8.3 及以下,光这一条就够升级了
- 那么,什么时候升级
- 结语
- 参考资料
引言 — 时隔27个月的大版本,以及悄悄变更的归属
Podman 6.0.0 于 2026 年 6 月 24 日发布。5.0.0 是 2024 年 3 月 19 日发布的,所以这是时隔 27 个月的大版本。紧随其后,7 月 8 日 6.0.1 与 —— 同一天 —— 5.8 分支的 5.8.5 一起发布了。老一代分支在大版本发布后不久仍在收到补丁,这件事本身就是本文后半部分「什么时候升级」判断的重要素材。
比版本号更先引起注意的是仓库地址。发行说明里的 issue 链接全部指向 github.com/podman-container-tools/podman。Podman 与 Buildah、Skopeo 等一起,以「Podman Container Tools」的名义于 2025 年 1 月 21 日获批进入 CNCF Sandbox(CNCF 项目页面、Red Hat 的公告),而 6.0 正是 GitHub 组织迁移真正落地的版本。Go 的导入路径也从 github.com/containers/podman/v5 变成了 go.podman.io/podman/v6。对于把 Podman 作为库来引用的项目而言,光这一点就是一项迁移工作。
本博客此前已经写过从 Docker 迁移到 Podman 的故事。那篇文章写下「Podman 还处在 5.x 世代」还不到十天,6.0 就发布了,所以本文算是它的续篇 —— 只依据发行说明原文,梳理 6.0 里删除了什么、桌面端(尤其是 macOS)发生了什么变化。容器镜像层方面的最新动态,我在containerd 的 EROFS 原生层一文中另行讨论过;本文专注于运行时和桌面这两层。
先看移除清单 — 升级前检查自己的环境
6.0 是一个删除、而非新增功能唱主角的版本。把发行说明里的 Breaking Changes 原样搬过来:
- 移除 slirp4netns rootless 网络栈 —— 只剩下 pasta。专用的
--network-cmd-path选项也一并删除。 - 移除 CNI 网络支持 —— 只支持 Netavark。
- 移除 iptables 支持 —— 需要 nftables。
- 移除 cgroups v1 系统支持 —— 必须使用 cgroups v2。
- 移除 BoltDB 数据库支持 —— 现有 BoltDB 用户会在 6.0 首次运行时尝试自动迁移到 SQLite。
- 移除 Intel Mac 支持。
- 移除 Windows 10 支持。
随之而来的还有配套技术栈的要求。6.0.0 必须搭配 Buildah v1.44.0、Skopeo v1.23、Netavark/Aardvark v2.0.0 一起使用,配置文件的解析逻辑被整体重写,为此还专门发布了一份设计文档。用发行版打包版本的人,发行版会替你配好这套组合;但自己编译或者只升级一部分的人,就得自己核对版本组合。
升级前,可以用下面的方法检查自己的环境是否落在移除清单里:
# 如果网络后端是 cni,在 6.0 上不会工作(必须是 netavark)
podman info --format '{{.Host.NetworkBackend}}'
# 检查 rootless 网络是否固定在 slirp4netns 上 —— 检查 containers.conf
grep -r "slirp4netns" ~/.config/containers/ /etc/containers/ 2>/dev/null
# DB 后端 —— 如果是 boltdb,6.0 首次运行时会尝试迁移到 sqlite
podman info --format '{{.Host.DatabaseBackend}}'
# cgroups 版本 —— 如果是 v1,得先从主机开始迁移
podman info --format '{{.Host.CgroupsVersion}}'
BoltDB → SQLite 虽然有自动迁移,但光凭「自动」两个字就不备份直接升级大版本,是另外一回事。先清理一下容器再升级会更安心。
macOS — 默认 provider 变成了 libkrun
先交代一下 macOS 这段故事的背景: 在 5.0(2024-03)里,QEMU provider 被移除,基于 Apple 原生虚拟化技术的 applehv(内部是 vfkit + Virtualization.framework)成为默认项,而 5.2(2024-08) 又新增了 libkrun 后端。当时的发行说明明确指出,libkrun 的优势在于可以把 GPU 挂载进 VM 来加速工作,但默认值仍然保留为 applehv。
6.0 把这个默认值翻转了过来。发行说明原文是这样写的: "The default podman machine provider on Macs has been changed to libkrun." 这个选择看起来和「想在 VM 里用 GPU」这类需求(比如本地 LLM 推理)的增长脱不了关系(这不是我的猜测 —— 5.2 的发行说明本身就把 GPU 挂载写成了 libkrun 存在的理由)。
实务上重要的几点:
- 已有的 VM 保持原样。变化的是新建 VM 的默认 provider。从 6.0 起,无论当前配置如何,所有
podman machine命令都能操作任意 provider 的 VM,这反而让混用 applehv VM 和 libkrun VM 变得更好管理了。 - 如果还想继续用 applehv,明确指定
podman machine init --provider applehv即可。这个选项本身就是 6.0 新增的。 - Intel Mac 在 6.0 里已经不再受支持,所以这段讨论根本不适用于它 —— 应该留在 5.8.x。
还有一点需要诚实面对。libkrun 是否已经成熟到可以做默认值,证据其实并不一致。6.0.1 和 5.8.5 在同一天修复的那个 bug 是: 「主机上的端口扫描进程会无意中向 libkrun VM 发送关机命令,导致 VM 周期性关闭」 —— 也就是说,默认值升级仅仅两周后,第一个补丁就是修这个的。此外,2025 年 12 月的一次 discussion 报告过,在课堂环境里用 libkrun 时出现了绑定挂载权限问题(按报告者自己的统计,约四分之一的学员必须把宿主目录权限放宽到 777,挂载才能生效),而据称在 applehv 上没有复现。这只是个别用户的报告,不能一概而论,但如果你的工作方式以 -v 绑定挂载为主,那在跟随默认值之前,用自己的工作流验证一下是有理由的。
顺带说一下 Windows 那边: Windows 10 支持被移除的同时,hyperv provider 的 VM 启动、停止不再需要管理员权限了(创建仍然需要,且只适用于新建的 VM),还新增了一个 podman system hyperv-prep 命令,供管理员提前准备好主机。
pasta 独当一面的时代 —— 以及 Pesto 这个实验
移除 slirp4netns 并不突然。早在 5.0,rootless 的默认网络就已经从 slirp4netns 换成了 pasta("for improved performance" —— 5.0 的发行说明原话),6.0 只是删掉了两年多来一直不是默认值的代码。即便如此,containers.conf 或脚本里固化了 slirp4netns 的环境应该还存在,所以前面那行 grep 值得跑一下。
pasta 独当一面的时代,有一个行为特性值得了解: 正如 Podman 网络教程 明确指出的,pasta 模式下的容器默认互相隔离。它不像网桥那样有一张虚拟网络,所以容器之间通信要么走主机端口映射,要么放进同一个 Pod 共享网络命名空间。如果 rootless 场景下容器之间需要直接通信,标准做法是创建一个 rootless netavark 网桥网络。
不过 rootless 网桥有一个由来已久的痛点 —— 负责端口转发的 rootlessport 会作为代理插进来,导致容器看到的客户端源 IP 不再是真实地址。见过连接日志清一色打印网关地址的人对此深有体会。6.0 在这里加入了一个实验性的替代方案: 在 containers.conf 里这样配置,
[network]
rootless_port_forwarder = "pasta"
rootless 网桥网络的端口转发就不再由 rootlessport 处理,而是由一个叫 Pesto 的工具,利用 pasta 的内核级转发来完成。据源码里的说明,rootless 命名空间里共享的 pasta 实例会接管主机侧转发,本地(localhost)流量走内核 splice,外部流量走 TAP,并在这个过程中保留源 IP —— 容器看到的会是真实的客户端地址,而不是代理或网关地址。
这是个值得期待的能力,但预期要放低一些。默认值仍然是 rootlessport,发行说明自己也写着「等稳定性更有把握后再考虑切换」,而且它需要包含 pesto 二进制的 passt 版本(passt-0^20260507.g1afd4ed 及以上)。而 6.0.1 已经修复了一个 Pesto 规则清理的 bug(容器重启、网络重新加载时规则没有被清理,导致转发失败)。「实验性」这个标签不是摆设。这是一个适合在真正在意源 IP 的场景(fail2ban 类工具、访问控制、审计日志)里以 opt-in 方式验证的阶段,还不是拿来当生产默认值用的阶段。
再补充一个附录级别的实验: 在内核 6.18 及以上版本中,加入了用 nsfs 文件句柄替代原本用于保持 rootless 用户命名空间存活的 pause 进程的功能。这是个藏在 drop-pause-process 环境变量后面的实验性功能,但它是一个信号 —— rootless Podman 里一个存在已久的结构性组件,有可能会消失。
Quadlet —— 从 .app 文件到子目录
用 systemd unit 管理容器的 Quadlet 那一侧,也发生了结构性变化。以前用 podman quadlet install 安装的 Quadlet 及其附属文件,是以 .app 文件的形式被跟踪的;从 6.0 开始,改成放进一个子目录里。发行说明的解释是这样能减少 bug、让手动管理更轻松 —— 反过来说,依赖 .app 方式的脚本或文档就成了需要修改的对象。
其他 Quadlet 方面的变化:
.volumeunit 新增了 UID、GID、Options 键(创建时可以指定所有者和常规卷选项)。.containerunit 里,无 source 的 Mount 键现在可以用来挂载匿名卷。- 新增了
/usr/share/containers/systemd/users系列的搜索路径(包含按用户 UID 划分的子路径),方便发行版把 Quadlet 打包分发。 podman quadlet list新增了 status 过滤器、Pod 列、ls别名,以及--noheading。- Quadlet 的 man 手册按文件类型拆分了。
podman generate systemd 过时、Quadlet 成为正解的这条脉络,正是迁移指南里讲过的那样;6.0 是把这个 Quadlet 进一步推向「发行版可以打包分发的东西」这个方向。读起来像是一个信号 —— 把容器部署成 systemd 服务这种模式,正在变成一等公民。
Docker 兼容性改进 = 脚本行为的变化
6.0 里相当一部分 Breaking Changes 都是「向 Docker 看齐」。兼容性改进固然值得高兴,但反过来看,也意味着按老版本 Podman 行为写的脚本,会悄悄地表现出不同的行为。容易踩坑的几个:
podman volume prune现在会像 Docker 一样,只删除匿名卷。要恢复以前那种删除所有未使用卷的行为,需要用新的--all选项。同时新增的还有可以预览删除清单的--dry-run。podman volume list的多重过滤条件从 OR 变成了 AND,多个命令里的label!=过滤也同样改成了 AND 组合。原本叠加多个过滤条件的清理脚本,得到的结果集会不一样。- 在 ps、pod ps、volume ls 里以 JSON 格式取 Labels 字段,现在返回的不再是 JSON map,而是逗号分隔的 key=value 字符串(向 Docker 看齐)。用 jq 解析这段输出的流水线会因此崩掉。
podman commit默认会先暂停容器再提交(防止提交过程中被并发修改)。老行为可以用--pause=false找回来。- 网络隔离默认开启,Docker 兼容 API 版本升到了 v1.44。
--gpus选项现在也兼容 AMD GPU 了(是原本只支持 NVIDIA 的一个扩展)。
「Docker 兼容性变好了」这句话读过去很轻松,但在 CI 或者清理用的定时任务里,volume prune 和过滤条件语义的变化,是实实在在改变了数据被删除的方式。升级之后,第一次运行值得盯紧一点。
CVE-2026-57231 —— 如果你还在 5.8.3 及以下,光这一条就够升级了
随 6.0.0 一起公开的安全修复有一项。GHSA-4hq8-gpf5-8p68(CVE-2026-57231,GitHub 严重级别 high): 恶意镜像可以通过构造过的 Env 条目,把主机的环境变量泄露进容器里,配合通配符 glob,甚至可以在不知道变量名的情况下批量泄露。受影响范围是 v1.8.1 到 v5.8.3 —— 事实上覆盖了近几年几乎所有版本。修复分别落在了 v5.8.4(2026-06-26)和 v6.0.0 里。
「光是 pull 镜像、run 一下,主机环境变量就泄露了」这类漏洞,对桌面用户来说尤其伤。因为开发机正是那种把 API key、token 常年 export 在 shell 环境里的地方。哪怕你没打算升级到 6.0,只要还在 5.8.3 及以下,也应该升到 5.8.4 及以上。
那么,什么时候升级
现在就可以升级的情况:
- 在 Apple Silicon Mac 上从零开始。截至本文写作时(2026-07-17),Homebrew 已经把 6.0.1 作为 stable 分发了,所以 brew 用户实际上已经在 6.0 这条轨道上了。剩下要决定的只是保留现有的 applehv VM,还是用 libkrun 重新建一个。
- 网络后端已经是 netavark + pasta(大多数一直沿用 5.x 默认值的人都是这种情况),数据库用的是 SQLite 而不是 BoltDB —— 用上面的检查命令几秒钟就能判断出来。
- 使用消费 Docker 兼容 API 的工具(比如 compose)—— 能享受到 API v1.44 和这些兼容性修复带来的好处。
需要等一等、或者应该留在 5.8.x 的情况:
- Intel Mac、Windows 10 —— 没有选择余地。5.8.x 是唯一的轨道,而 5.8.5 和 6.0.1 同一天发布这件事,说明当前补丁应该还会继续一段时间(不过官方并没有明说支持期限)。
- 还有 cgroups v1 主机、CNI 网络配置的服务器 —— 得先做主机和网络的迁移。
- 以绑定挂载为主的 macOS 工作流 —— 与其直接跟随 libkrun 默认值,不如先用自己的工作负载验证一下权限行为,或者暂时明确指定
--provider applehv,这样更保守。 - 自动化程度高、依赖解析 ps/volume 输出或 prune 行为的环境 —— 先审计一遍上面那份兼容性变化清单,再升级会更安全。
再补充一点: podman machine os apply 在 6.0 里被重写成基于 bootc switch 的实现,这也是一个悄悄发生的变化。这意味着 machine VM 的 OS 更新,现在是通过切换到一个可启动的容器镜像来处理的 —— 不可变 OS 这条思路,已经一路下沉到了桌面端的 VM(服务器侧不可变 OS 的话题,可以参见Talos 1.13 一文)。
结语
Podman 6.0 不是一个靠新功能来吸引人的版本,而是一个清偿债务的版本。slirp4netns、CNI、iptables、cgroups v1、BoltDB —— 这些早在数年前就已经确定了继任者,6.0 只是宣告这段宽限期结束了。在此之上,还叠加了 CNCF 迁移这样的治理层变化、macOS 上 libkrun 切换这样的桌面层变化,以及 Pesto 这个 rootless 网络的下一步实验。
升级的判断其实很简单。先用上面那三行 podman info 检查自己是否落在移除清单里,中招就先解决那一项;如果是 macOS,就有意识地选定 provider;自动化多的话,先审计一遍 Docker 兼容性变化清单再升级。而不管怎样,都别继续停留在 5.8.3 及以下 —— 光 CVE-2026-57231 这一条,理由就已经足够。
参考资料
- Podman v6.0.0 发行说明
- Podman v6.0.1 发行说明
- Podman v5.8.5 发行说明
- Podman v5.0.0 发行说明 —— pasta 默认化、引入 applehv
- Podman v5.2.0 发行说明 —— 新增 libkrun 后端
- GHSA-4hq8-gpf5-8p68 (CVE-2026-57231) 安全公告
- CNCF —— Podman Container Tools 项目页面 · 沙箱批准 issue
- Red Hat —— 将容器工具贡献给 CNCF 的公告
- Podman 网络教程 —— pasta 与 pesto 文档
- libkrun 绑定挂载权限问题 discussion
- 配置文件解析重写设计文档
- 从 Docker 到 Podman —— 迁移指南(相关文章)