跳转到内容

Podman vs Docker:如何选择

Podman 和 Docker 都能构建、运行和管理 OCI 容器,日常命令几乎一致。EL 系统默认推荐 Podman(随 RHEL 8 起预装),而 Docker 拥有更庞大的生态。这篇文章从架构讲到兼容性,帮你做出选择。

这是两者最本质的区别:

  • Docker:客户端-服务端架构,依赖常驻的 dockerd 守护进程。所有容器都是 dockerd 的子进程,守护进程崩溃会影响所有运行中的容器;守护进程以 root 运行,历来是安全关注点。
  • Podman:无守护进程(daemonless)。每条命令直接通过 fork-exec 启动容器,容器是当前 shell 的子进程。没有常驻服务意味着没有单点故障,退出登录后容器照常运行。
查看容器进程归属(Podman 中是普通子进程)
$ podman top mycontainer pid ppid user
  • Podman:设计上 rootless 优先,普通用户无需 sudo 即可构建和运行容器,配合 user namespace 把容器内 root 映射为宿主机普通用户。这是 RHEL 默认且推荐的用法。
  • Docker:rootless 模式存在且可用,但属于可选配置,生产中仍以 root 运行 dockerd 为主流。

如果你的场景是多人共用服务器、CI 环境、HPC 或任何”不想给用户 root”的环境,Podman 的 rootless 模型有明显优势。

EL 生态里,容器作为服务管理是刚需:

  • Podman + Quadlet:RHEL 9.4 起推荐用 Quadlet(systemd generator),写一个 .container 文件就能把容器声明为 systemd 服务,随系统启动、自动拉起。
  • Docker:依靠 docker.service 托管,容器的重启策略(restart=always)依赖守护进程存活。
~/.config/containers/systemd/webapp.container
[Unit]
Description=My web app
[Container]
Image=quay.io/example/webapp:latest
PublishPort=8080:80
[Service]
Restart=always
[Install]
WantedBy=default.target
让 systemd 加载容器单元
$ systemctl daemon-reload
$ systemctl start webapp.service

podman build/run/push/pull/images/ps 与 Docker 同名命令参数一致,肌肉记忆可以无缝迁移。

Podman 提供 Docker REST API 兼容层:

启用 Docker 兼容 socket,让依赖 Docker API 的工具直接工作
$ systemctl --user start podman.socket

安装 podman-docker 包后,docker 命令会被透明转发给 Podman。

Podman 支持 docker-compose(通过兼容 socket)和 podman-compose。大多数 Compose 文件无需修改即可运行,但带 Docker 专有特性(如 Swarm 服务)的除外。

RHEL 系的 Podman 没有默认仓库,拉取镜像要写全限定名:

Terminal window
# 会提示选择来源(short-name resolution)
$ podman run nginx
# 推荐写法
$ podman run docker.io/library/nginx:latest
$ podman run registry.access.redhat.com/ubi9/ubi:latest
维度PodmanDocker
架构无守护进程dockerd 守护进程
Rootless默认推荐可选配置
systemd 集成Quadlet 原生依赖守护进程
Pods(多容器共享命名空间)支持不支持(用 Compose)
Docker API兼容层原生
Docker Desktop(GUI)无(macOS/Windows 用 podman machine)有
预装于 RHEL/AlmaLinux/Rocky是否
生态与教程数量较少最多
  • EL 服务器、rootless、systemd 原生集成 → Podman。它是发行版默认,安全模型更适合多用户服务器
  • 团队已有大量 Docker 资产、依赖 Docker Desktop 或 Swarm → Docker。兼容层可以过渡,但没必要强行替换
  • CI/CD 与 K8s 工作流 → 两者都行;构建产物是 OCI 镜像,推到任意 registry 后完全通用