Podman 知识图谱

一、一句话结论

Podman 体系分六层看:核心概念(无守护进程 + rootless)→ 镜像管理 → 容器运行 → pod 编排 → 网络与存储 → systemd 集成与生态;它与 Docker 的命令几乎一一对应,但架构是根本不同的两件事——没有中心守护进程,容器进程直接由用户会话拉起,安全和生命周期模型因此全变。

二、原理与来由(分层依据)

Docker 模型是「一个 root 守护进程代管一切」,容器逃逸即拿到宿主机 root。Podman 的回应是把守护进程去掉:每个容器是 fork 出来的父子进程树(conmon 监控 + OCI 运行时 crun/runc 真正跑容器),谁启动谁拥有——普通用户跑的容器天然无 root 权限(rootless)。分层依据是使用链路:先有镜像(build/pull)→ 才能运行容器(run/exec)→ 多容器组队成 pod(共享网络命名空间)→ 网络与存储决定它们怎么通、数据放哪 → systemd quadlet 决定开机自启与重启策略 → 生态层处理与 Docker/K8s 的互操作。排查容器问题的顺序:镜像本身查镜像层,起不来查容器层,互通查网络层,丢数据查存储层,重启异常查 systemd 集成层。

三、细节与用法

① 核心概念

主题 一句话要点 检索关键词
无守护进程 没有常驻 dockerd 等价物;容器 = 用户的进程树(podman fork + conmon 监控 + crun 运行),podman ps 退出容器仍在 无守护进程、conmon
rootless 普通用户跑容器,宿主机无 root、容器内 UID 映射(/etc/subuid、subgid);这是与 Docker 最本质的差异 rootless、UID 映射
OCI 标准 镜像(image spec)与运行时(runtime spec)都是开放标准;crun(C,默认)或 runc(Go)可切换 OCI、crun、runc
命令兼容 alias docker=podman 大多直接可用(build/run/push/exec/logs 一致);无 daemon 的差异点在 API 模式与 socket 场景 docker 别名、兼容性

② 镜像管理

主题 一句话要点 检索关键词
构建 podman build 用 Containerfile(与 Dockerfile 同语法);多阶段构建减体积;buildah 可脚本化精细构建 Containerfile、多阶段
分层与缓存 镜像 = 只读层叠加;构建缓存按指令命中,变的指令放后面(先 COPY 依赖清单再 COPY 源码) 分层、缓存命中
仓库操作 pull/push 走 registry(docker.io、quay.io);containers-registries.conf 配置镜像源与不安全源;skopeo 免拉取检视/复制镜像 registry、skopeo、镜像源

③ 容器运行

主题 一句话要点 检索关键词
生命周期 run(创建即跑)/ create + start(分离)/ stop / rm;--rm 用完即删;inspect 看一切元数据 run、--rm、inspect
进入与日志 exec 在运行容器里开进程;logs 看容器 stdout/stderr;podman exec -it <c> bash 日常调试 exec、logs
资源限制 --memory / --cpus / --pids-limit;rootless 下内核 cgroup 限制同样生效 资源限制、cgroup
健康检查 镜像内 HEALTHCHECK 指令 + podman healthcheck run;自动重启依赖 systemd 而非 --restart(后者在 rootless 无守护场景靠 podman 策略近似) HEALTHCHECK、重启策略

④ pod(Podman 的辨识度)

主题 一句话要点 检索关键词
pod 概念 借自 K8s:一个 pod 内多容器共享网络命名空间(同一 IP、可 localhost 互访)与可选的 IPC/PID pod、共享网络
典型用法 infra 容器持有 pod 的网络;应用容器挂进 pod,如「应用 + sidecar 代理」本地互访 infra 容器、sidecar
生成与导出 podman generate kube 把运行中的容器/pod 导出为 K8s YAML;podman kube play 反向按 YAML 起——本地到集群的轻量通道 generate kube、kube play

⑤ 网络与存储

主题 一句话要点 检索关键词
rootless 网络 无 root 无法建桥,靠 slirp4netns / pasta(新默认)用户态网络栈;--network slirp4netns:port_handler=slirp4netns 处理端口转发性能 slirp4netns、pasta
端口映射 -p 宿主端口:容器端口;rootless 下宿主端口 >1024 或借助 rootlessport 转发低端口 端口映射、rootlessport
卷与挂载 命名卷(-v data:/path,由 containers/storage 管理)与绑定挂载(-v /host/path:/path);rootless 绑定挂载受 SELinux 约束(:Z/:z 重标) 卷、绑定挂载、SELinux
持久化位置 rootless 数据在 ~/.local/share/containers/;迁移机器就是搬这个目录加配置 存储位置、迁移

⑥ systemd 集成与生态

主题 一句话要点 检索关键词
quadlet 现代方式:~/.config/containers/systemd/*.container 声明式定义,systemd 直接管理(自动生成 service),开机自启 / 重启策略 / 依赖关系全交给 systemd quadlet、开机自启
旧式生成 podman generate systemd 已被 quadlet 取代(新部署别再用) generate systemd
compose 兼容 podman-compose 或 podman compose(外部包装)跑 docker-compose.yml;复杂依赖网络的后端有差异,非 100% 等价 podman-compose
桌面与 K8s Podman Desktop 图形界面;Podman Desktop + Kind 可本地拉起 K8s 测试环境 Podman Desktop、Kind
与 Docker 取舍 单机 / 开发机 / 无 root 权限服务器 → Podman 顺理成章;已有 K8s 编排的集群侧不在此讨论 Docker 对比

四、流程图(图谱一页图)

flowchart TD
    subgraph S1["① 核心概念"]
        A1["无守护进程"]
        A2["rootless · UID 映射"]
        A3["OCI 标准 · crun"]
    end
    subgraph S2["② 镜像管理"]
        B1["Containerfile · 多阶段"]
        B2["分层缓存"]
        B3["registry · skopeo"]
    end
    subgraph S3["③ 容器运行"]
        C1["生命周期 · --rm"]
        C2["exec · logs"]
        C3["资源限制 · 健康检查"]
    end
    subgraph S4["④ pod 编排"]
        D1["pod · 共享网络"]
        D2["generate kube · kube play"]
    end
    subgraph S5["⑤ 网络与存储"]
        E1["slirp4netns · pasta"]
        E2["端口映射"]
        E3["卷 · SELinux 标签"]
    end
    subgraph S6["⑥ systemd 与生态"]
        F1["quadlet"]
        F2["podman-compose"]
        F3["Podman Desktop · Kind"]
    end
    S1 -->|"镜像先行"| S2
    S2 ~~~ S3
    S3 ~~~ S4
    S4 ~~~ S5
    S5 ~~~ S6

层间竖排是阅读顺序(使用链路见「二、原理与来由」);① 的无守护进程与 rootless 是其余所有层行为差异的根源。

五、边界与关联

六、出处

来源 位置 核实日期
Podman 官方文档(podman.io + docs.podman.io) podman.io 2026-10-08
Red Hat 官方博客与 man 手册(podman-systemd.unit、containers-registries.conf) redhat.com / man pages 2026-10-08
个人实践(rootless 容器日常使用经验) 各层一句话要点为经验浓缩 2026-10-08

七、存疑与待办