
一句话定义:Podman(Pod Manager)是一个无守护进程、无根权限的容器引擎,与 Docker 高度兼容,是 Red Hat 主导开发的 OCI 标准化容器运行时。
痛点 | Docker 的问题 | Podman 的解法 |
|---|---|---|
安全 | 需要 root 权限运行守护进程,一旦被攻破 = 主机沦陷 | ✅ 默认 Rootless,普通用户即可运行,攻击者无法获取主机权限 |
架构 | C/S 架构(客户端-服务端),daemon 是单点故障 | ✅ 无守护进程,直接与镜像仓库、存储、内核交互,更轻量更安全 |
系统集成 | 容器生命周期与宿主机解耦,重启后容器不自启 | ✅ 原生支持 systemd,容器可作为系统服务管理 |
** pod 概念** | 需要 Docker Compose 或 Swarm | ✅ 原生支持 Pod(K8s 理念),多容器共享网络和存储 |
企业合规 | Docker Desktop 商业授权收费(大企业) | ✅ 100% 开源免费,RHEL/CentOS 默认自带 |
🔥 关键数据:Red Hat 8+ / CentOS 8+ / Fedora 已将 Podman 设为默认容器引擎,Docker 需要额外安装。
Podman 概念 | Docker 类比 | 说明 |
|---|---|---|
Container(容器) | Container | 隔离的运行环境 |
Pod(容器组) | Pod(K8s 概念) | 🔑 Podman 的杀手锏! 多个容器共享网络/IPC/UTS,像 K8s Pod 一样协同工作 |
Image(镜像) | Image | 从 Registry 拉取的只读模板 |
Volume(数据卷) | Volume | 持久化数据,容器删除后数据不丢失 |
Network(网络) | Network | bridge、host、slirp4netns 等 |
Rootless | ❌ Docker 无此概念 | 🔑 无需 root 权限运行,用户命名空间隔离 |
Quadlet | ❌ Docker 无此概念 | 🔑 用系统服务单元文件定义容器,systemctl 管理 |
传统 Docker(独立容器):
[Container A] ←→ bridge0
[Container B] ←→ bridge0 ← 各自独立 IP,通信需端口映射
Podman Pod(容器组):
[Container A] ─┐
├─→ 共享同一个网络命名空间(同一个 IP!)
[Container B] ─┘ 像 K8s Pod 一样,localhost 直连💡 实战场景:一个 Nginx + 一个 Redis 放在同一个 Pod 里,Nginx 用
redis://localhost:6379就能连 Redis,无需端口映射,无需自定义网络!
bash# 检查是否已安装
podman --version
# 未安装则一键安装
sudo dnf install -y podman
# 安装辅助工具(强烈推荐!)
sudo dnf install -y podman-docker # 提供 docker 命令别名
sudo dnf install -y podman-compose # 提供 docker-compose 别名
sudo dnf install -y containers-common # 镜像仓库配置bashsudo apt update
sudo apt install -y podman
# 同样安装兼容层
sudo apt install -y podman-dockerbash# macOS
brew install podman
podman machine init
podman machine start
# Windows(需 WSL2)
wsl --install
wsl podman machine init
wsl podman machine startbash# 查看版本(带详细信息)
podman version
# 测试运行第一个容器
podman run --rm hello-world
# 查看所有容器(包括已停止的)
podman ps -a🔑 好消息:Podman 几乎完全兼容 Docker CLI,
alias docker=podman即可无缝切换!
操作 | Docker 命令 | Podman 命令 | 说明 |
|---|---|---|---|
拉取镜像 | docker pull nginx | podman pull nginx | ✅ 完全一致 |
运行容器 | docker run -d -p 80:80 nginx | podman run -d -p 80:80 nginx | ✅ 完全一致 |
查看容器 | docker ps | podman ps | ✅ 完全一致 |
停止容器 | docker stop <id> | podman stop <id> | ✅ 完全一致 |
删除容器 | docker rm <id> | podman rm <id> | ✅ 完全一致 |
构建镜像 | docker build -t myapp . | podman build -t myapp . | ✅ 完全一致 |
进入容器 | docker exec -it <id> bash | podman exec -it <id> bash | ✅ 完全一致 |
查看日志 | docker logs <id> | podman logs <id> | ✅ 完全一致 |
命令 | 用途 | 示例 |
|---|---|---|
podman pod create | 创建 Pod | podman pod create --name mypod -p 8080:80 |
podman pod add | 将容器加入 Pod | podman pod add mypod nginx |
podman generate systemd | 生成 systemd 服务文件 | podman generate systemd --name mynginx |
podman unshare | 进入用户命名空间 | podman unshare cat /proc/self/uid_map |
podman play kube | 直接运行 K8s YAML | podman play kube my-deployment.yaml |
podman top | 查看容器内进程 | podman top <container> |
podman stats | 实时资源监控 | podman stats |
普通用户(非 root)就能创建和运行容器,所有操作在用户命名空间中完成,容器内的 root 只是宿主机上的普通用户。
bash# 1. 切换到普通用户(不要用 root!)
su - myuser
# 2. 直接运行(无需任何 sudo)
podman run -d --name mynginx -p 8080:80 nginx
# 3. 验证:容器内的 root 实际是谁?
podman exec mynginx whoami
# 输出:myuser(不是 root!)
# 4. 查看用户映射
podman unshare cat /proc/self/uid_map
# 0 1000 1 # 容器内 UID 0 = 宿主机 UID 1000(myuser)Docker(root 模式):
攻击者逃逸 → 获得宿主机 root 权限 → 完蛋 💀
Podman(rootless 模式):
攻击者逃逸 → 获得的只是 myuser 权限 → 限制在用户目录内 → 可控 ✅限制 | 解决方案 |
|---|---|
无法绑定 1024 以下端口 | 用 sysctl net.ipv4.ip_unprivileged_port_start=80 或用 slirp4netns |
存储驱动默认是 overlay | Rootless 只能用 vfs 或 fuse-overlayfs,性能略低 |
无法使用 --privileged | Rootless 本身就不支持,这是安全特性不是 Bug |
无法访问宿主机 / 目录 | 默认只挂载 $HOME,需显式 --volume /data:/data |
bashpodman pod create --name webapp -p 8080:80 -p 6379:6379bash# 启动 Redis(加入 Pod)
podman run -d --name redis \
--pod webapp \
redis:7-alpine
# 启动 Nginx(加入 Pod)
podman run -d --name nginx \
--pod webapp \
nginx:alpinebash# 进入 Nginx 容器
podman exec -it nginx sh
# 直接用 localhost 访问 Redis!(无需端口映射)
apk add redis
redis-cli -h localhost -p 6379 ping
# 输出:PONG ✅💡 对比 Docker:在 Docker 中实现同样效果,需要创建自定义 bridge 网络 + 容器名 DNS 解析,Podman 一个
--pod就搞定!
这是 Podman 最被低估的杀手级特性——把容器变成系统服务!
bashpodman run -d --name myweb -p 8080:80 nginx:alpinebash# 生成到当前目录
podman generate systemd --name myweb --new --files
# 查看生成的文件
cat container-myweb.service输出示例:
ini[Unit]
Description=Podman container-myweb.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStart=/usr/bin/podman start myweb
ExecStop=/usr/bin/podman stop -t 10 myweb
ExecStopPost=/usr/bin/podman stop -t 10 myweb
ExecStopPost=/usr/bin/podman rm -f myweb
Type=forking
PIDFile=/run/user/1000/containers/overlay-containers/myweb/userdata/conmon.pid
[Install]
WantedBy=default.targetbash# 复制到系统目录(rootless 模式)
cp container-myweb.service ~/.config/systemd/user/
# 重载 systemd
systemctl --user daemon-reload
# 启动服务
systemctl --user start container-myweb.service
# 设置开机自启
systemctl --user enable container-myweb.service
# 查看状态
systemctl --user status container-myweb.servicebash# 修改容器配置(比如换镜像)
podman rm -f myweb
podman run -d --name myweb -p 9090:80 nginx:alpine
# 重新生成并替换服务文件
podman generate systemd --name myweb --new --files --replace
systemctl --user daemon-reload
systemctl --user restart container-myweb.service💡 生产价值:容器故障自动重启、开机自启、日志接入
journalctl——这才是生产级容器管理!
bashpip3 install podman-compose
# 或
sudo dnf install -y podman-composeyaml# docker-compose.yml
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
depends_on:
- redis
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
volumes:
redis_data:bash# 启动(Docker 命令完全可用)
podman-compose up -d
# 查看
podman-compose ps
# 停止
podman-compose down
# 查看日志
podman-compose logs -fbash# 直接运行 K8s 风格的 YAML!
podman play kube deployment.yamlbashpodman images
# 或(更详细)
podman image lsbash# Docker Hub(默认)
podman pull nginx:alpine
# 国内镜像源(阿里云)
podman pull registry.cn-hangzhou.aliyuncs.com/myrepo/nginx:alpine
# 私有 Registry(需登录)
podman login myregistry.com
podman pull myregistry.com/myapp:v1.0bash# 保存为 tar 包
podman save -o nginx.tar nginx:alpine
# 从 tar 包加载(无需网络!)
podman load -i nginx.tar
# 导出为 OCI 存档(保留所有层)
podman save -o nginx-oci.tar nginx:alpine实践 | 命令/配置 | 说明 |
|---|---|---|
✅ 永远用 Rootless | --userns=keep-id | 除非有特殊需求,否则不要用 sudo |
✅ 用 Quadlet 管理 | podman generate systemd | 容器 = 系统服务,故障自恢复 |
✅ 用 Pod 编组 | podman pod create | 减少网络复杂度,模拟 K8s |
✅ 限制资源 | --cpus=2 --memory=512m | 防止容器吃光宿主机资源 |
✅ 只读根文件系统 | --read-only | 大幅提升安全性 |
✅ 不用 latest 标签 | nginx:1.25-alpine | 版本锁定,避免意外升级 |
✅ 定期清理 | podman system prune -a | 清理无用镜像、容器、卷 |
✅ 日志用 journalctl | journalctl -u container-xxx | 统一日志管理 |
✅ 镜像签名验证 | podman pull --sigstore-verify | 防止镜像被篡改 |
✅ SELinux 标签 | :Z 或 :z 后缀 | -v /data:/data:Z 确保权限正确 |
bashpodman run -d \
--name myapp \
--cpus=1.5 \
--memory=512m \
--memory-swap=512m \
--pids-limit=100 \
nginx:alpinebashpodman run -d \
--name secure-app \
--read-only \
--tmpfs /tmp \
--tmpfs /run \
nginx:alpine维度 | Podman 🏆 | Docker |
|---|---|---|
架构 | 无守护进程,fork-exec 模型 | C/S 架构,daemon 单点故障 |
Rootless | ✅ 原生支持,默认开启 | ❌ 需要 Rootless Docker 额外配置 |
安全 | 容器逃逸后只有用户权限 | 容器逃逸 = 宿主机 root |
Pod | ✅ 原生支持 | ❌ 需 Swarm/Compose 模拟 |
Systemd 集成 | ✅ generate systemd 原生支持 | ❌ 需第三方工具 |
K8s YAML | ✅ podman play kube | ❌ 不支持 |
兼容性 | 99% 兼容 Docker CLI | 行业标准 |
商业授权 | 100% 开源(Apache 2.0) | Docker Desktop 大企业收费 |
性能 | 略优(无 daemon 开销) | 略差(daemon 转发) |
社区 | Red Hat 主导,RHEL 默认 | Docker Inc 主导 |
yamlversion: '3.8'
services:
db:
image: mariadb:10.11
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpass123
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass123
volumes:
- db_data:/var/lib/mysql
podman:
# Podman 特有配置
security-opt: ["label=disable"]
wordpress:
image: wordpress:6.4-php8.2-apache
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wppass123
WORDPRESS_DB_NAME: wordpress
volumes:
- wp_data:/var/www/html
depends_on:
- db
volumes:
db_data:
wp_data:bash# 启动
podman-compose up -d
# 查看
podman-compose ps
# 查看日志
podman-compose logs -f wordpress
# 生成 systemd 服务(生产环境)
podman generate systemd --name wordpress-db --files
podman generate systemd --name wordpress-wordpress --files
# 停止
podman-compose down维度 | 核心理念 |
|---|---|
安全 | Rootless 是默认,不是可选项 🔐 |
架构 | 无守护进程 = 无单点故障 = 更轻量 ⚡ |
理念 | Pod + Quadlet = 把容器当系统服务管理 🔧 |
兼容 | 99% Docker 兼容,迁移成本 ≈ 0 🔄 |
趋势 | RHEL 默认、K8s 原生、企业首选 📈 |
🎯 一句话总结:如果你还在用 Docker,你不是落后了,你是在用一个有单点故障、需要 root 权限、无法原生管理的上一代技术。而 Podman,就是它的安全、现代、生产级替代品。
现在就开始:alias docker=podman,然后忘记 Docker 吧。 🚀
本文基于 Podman 4.x/5.x 官方文档及 Red Hat 最佳实践整理,兼容 RHEL 8/9、CentOS Stream、Fedora 38+、Ubuntu 22.04+ 等主流发行版。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。