OFFSET偏移
← 文章目录OFFSET / FIELD NOTESNO. 118

Docker 与 Podman:架构、兼容与共存

比较引擎控制模型、权限与生态,按工作负载选择工具。

所在专题Docker:从容器运行到应用编排 ↗Podman 容器工作流 ↗
约 10 分钟阅读开始阅读

同一个镜像标准,两种完全不同的哲学。理解了 dockerd 和 Daemonless,就理解了容器引擎的现在和未来。


一句话定位#

graph LR
    subgraph "容器的两个时代"
        D["Docker / 推动容器工作流普及 / Client-Server 架构 / 生态最成熟"]
        P["Podman / OCI 容器引擎 / Daemonless 架构 / 支持 rootless"]
    end
    D -->|"标准化了容器"| OCI["OCI 标准 / 镜像格式 / 运行规范"]
    P -->|"遵循同一标准"| OCI

Docker 推动了镜像与容器工作流普及,并推动 OCI 标准建立。Podman 遵循同一标准,但用完全不同的架构重新实现了一遍。


架构对比:一个管家 vs 你自己动手#

Docker:
  docker CLI  ──REST API──▶  dockerd (ROOT, 常驻)  ──▶  containerd  ──▶  runc
                              └─ 所有操作都经过它
                              └─ 它是唯一的控制点

Podman:
  podman CLI  ──直接 fork/exec──▶  conmon  ──▶  crun/runc
               └─ 每次启动新进程
               └─ 没有中央控制点

这个差异意味着什么?

维度 Docker Podman
后台进程 dockerd 常驻,资源使用依负载 无常驻中央 daemon;容器仍有 conmon 等进程
权限模型 传统 rootful daemon,也支持 rootless 支持 rootful 和 rootless,按运行用户及配置判断
单点故障 daemon 不可用影响管理;live-restore 有助于部分运行场景 无需常驻中央 daemon,但仍共享宿主内核和资源
开机自启 dockerd 开机启动,容器通过 restart policy 通过 systemd + Quadlet 管理
API 方式 dockerd 的 REST API(Socket 是攻击面) 可选 Podman API 和 Docker 兼容 API service/socket,均需控制权限
容器生命周期 daemon/containerd/shim 协作控制生命周期 容器是独立的用户进程

比喻

  • Docker 像住酒店:前台(dockerd)24 小时值班,所有事(入住、退房、叫餐)都经过前台。前台有万能钥匙(root)。
  • Podman 像住自己的房子:你自己开门、关灯、做饭。本地操作不需要常驻前台;rootful 或 API socket 仍可能授予高权限。

兼容性:Docker 的语法,Podman 的引擎#

命令行兼容

# 这两个命令几乎等价
docker run -d --name web -p 8080:80 nginx:alpine
podman run -d --name web -p 8080:80 nginx:alpine

# 简单 CLI 可用 alias 试验,但脚本/API/Compose/buildx/远程行为需逐项验证
alias docker=podman
docker ps          # 实际跑的是 podman ps
docker build -t myapp .  # 实际跑的是 podman build

生态兼容

Docker 工具 Podman 对应
Docker Compose podman-compose 或 podman.socket + docker compose
Docker Desktop Podman Desktop(免费开源)
Docker Hub 相同,都用 docker.io
Dockerfile 常用语法相通,高级 BuildKit 特性及版本支持需验证,podman build 直接读 Dockerfile
Docker Swarm Podman 不支持;用 Kubernetes 工作流或其他编排;generate kube 仅生成兼容配置片段,不等于直接部署迁移

兼容边界

常用互通领域(仍需按版本验证):

  • 镜像格式(OCI 标准)
  • Dockerfile 语法
  • 基本 CLI 命令(run, ps, stop, pull, push, build)
  • 卷(Volume)和绑定挂载
  • 端口映射(除 rootless 端口限制)
  • 环境变量注入

不兼容:

  • Compose deploy 的实现支持差异;deploy.resources 并非仅 Swarm 专用,不能一概判定不支持
  • Docker Swarm 整体
  • docker buildx 的多驱动构建(Podman 用 podman build --platform)
  • docker context(Docker 的多环境切换功能)

安全性:根本差异#

# Docker(默认):docker run 通过 dockerd socket 执行
# 父进程可能是 shim,权限由 daemon/rootless、userns 和容器 USER 等共同决定
sudo docker run -d nginx:alpine
ps aux | grep nginx
# 示意:ps 的 USER 列是进程用户,不显示父进程;查看父关系另查 PPID

# Podman rootless:进程位于用户映射的权限范围,父关系与用户身份不是同一概念
podman run -d nginx:alpine
ps aux | grep nginx
# 示意:宿主可见 UID 取决于用户命名空间映射

关键安全事实:

  • 控制 rootful Docker API 的用户通常可取得近似宿主 root 能力;rootless API 则限于对应用户权限。rootful 管理者可通过高权限挂载等操作访问宿主敏感内容,rootless 不因此获得任意文件读取权
  • Podman rootless 中,容器 UID 0 通常映射到启动用户,其他 UID 可映射到 subordinate IDs;减少宿主 root 暴露,但用户文件、挂载、socket 和内核漏洞仍有风险

选型指南#

graph TD
    A["我需要什么?"] --> B{"需要 Docker 专属功能?"}
    B -->|"Docker Swarm"| D["用 Docker"]
    B -->|"Docker Build Cloud"| D
    B -->|不需要| C{"运行环境?"}
    C -->|"个人开发机"| E["Podman / 按 rootless 与工具链要求验证"]
    C -->|"生产服务器"| F{"用什么管理?"}
    F -->|"systemd"| G["Podman + Quadlet / 声明式 + 原生集成"]
    F -->|"Compose 文件"| H{"单机还是集群?"}
    H -->|"单机"| I["Docker 或 Podman / 看团队习惯"]
    H -->|"集群"| J["Docker Swarm 或 K8s"]
    C -->|"公司强制"| K["用公司的标准 / 通常 Docker"]

具体建议

你的情况 推荐 理由
刚学容器 Podman 开源、常用命令相似,具体工作负载需验证互通
个人项目 Podman 无常驻中央 daemon,可选择 rootless;资源和安全需实测
团队都用 Docker Docker 保持一致,减少协作摩擦
公司项目 Docker 企业支持、CI/CD 集成成熟
生产单机部署 Podman + Quadlet systemd 管理、自动重启、统一日志
生产集群部署 Docker Swarm 或 K8s 编排能力
安全敏感环境 验证 Podman rootless 或 Docker rootless 明确权限、隔离与兼容要求

历史脉络与版本边界#

Docker 在 2013 年开始普及容器镜像工作流,2015 年 OCI 成立并接受 runc 等贡献。Podman 随后发展为 OCI 引擎,强调无常驻中央 daemon 的本地操作和 rootless。Quadlet、网络栈、API 和 Desktop 功能持续演进,不能把某个大版本号等同于全部功能首次出现。

Docker Desktop 许可、Hub 配额和发行版默认选择会改变;它们不是容器格式兼容性的证明。发行版默认引擎与同机共存条件应按实际软件包、socket 和版本配置核对。选型应检查实际版本、容器配置和团队工具链。

共存:同一台机器同时用 Docker 和 Podman#

# 两者可在同台机器并存,分别管理存储;端口、CLI/socket 兼容包和资源仍可能冲突
sudo docker run -d nginx:alpine        # Docker 容器
podman run -d nginx:alpine             # Podman 容器(rootless)

# 查看 Docker 容器
sudo docker ps

# 查看 Podman 容器
podman ps

# 镜像互导
podman save nginx:alpine -o nginx.tar
sudo docker load -i nginx.tar
# 反之亦然

核心结论#

Docker 与 Podman 共享常用镜像标准、仓库和 Dockerfile 工作流,但权限模型、API、构建与编排功能不保证完全互换。根据安全边界、团队工具链、平台及维护方式选择,必要时以实际应用做兼容测试。Daemonless 本身不是绝对安全保证,rootless 也不是 Podman 独有。

参考与延伸

  1. Docker rootless ↗
  2. Docker daemon 安全 ↗
  3. Podman API service ↗
  4. Podman Compose provider ↗
  5. OCI 规范 ↗

根据技术笔记重新整理,示例使用通用名称。

沿专题继续阅读

Docker:从容器运行到应用编排

  1. 01Docker 基础:镜像、容器与守护进程
  2. 02Docker 命令行:镜像、容器、卷与网络
  3. 03Dockerfile 与镜像构建
  4. 04Compose:定义多服务应用
  5. 05Docker 网络与存储
  6. 06Docker 生产实践:资源、安全与恢复
  7. 07NixOS 上声明 Docker 与容器
  8. 08Swarm:从服务副本到集群编排
  9. 09Docker 与 Podman:架构、兼容与共存

Podman 容器工作流

  1. 01Podman 基础原理
  2. 02Podman 基本使用指南
  3. 03Rootless 容器,文件权限到底算谁的?
  4. 04Rootless 配置:映射、ICMP 与注册表
  5. 05Pod 体系与 Kubernetes 清单
  6. 06Quadlet 如何把容器声明变成服务?
  7. 07Quadlet 的 Pod 与多服务配置
  8. 08Compose provider 与 Docker 工具互操作
  9. 09NixOS 上的 Podman 管理
  10. 10Podman 高级运维与调优
  11. 11Docker 与 Podman:架构、兼容与共存
CONTINUE READING / 下一篇Podman 基础原理

从容器、镜像和 OCI 运行时理解 Podman 的架构与权限模型。