Podman 容器引擎¶
一句话说明: Podman 是无守护进程(daemonless)的容器引擎,命令兼容 Docker,但以 rootless 模式运行更安全,且支持 Pod 概念原生对接 Kubernetes。
为什么要学¶
- 无守护进程 — 不需要后台 daemon 常驻,每个容器是独立进程,更安全稳定
- Rootless 容器 — 默认以普通用户运行容器,无需 root 权限,减小攻击面
- Docker CLI 兼容 —
alias docker=podman即可,迁移成本极低 - Pod 原生支持 — 直接生成 Kubernetes YAML,开发到部署无缝衔接
- RHEL/Fedora 默认 — Red Hat 生态的标准容器工具,企业级支持
核心概念详解¶
Podman vs Docker¶
| 特性 | Podman | Docker |
|---|---|---|
| 架构 | 无 daemon,fork-exec | 客户端-daemon |
| 运行权限 | Rootless 默认 | 需 root(或 docker 组) |
| 安全性 | 更高(无特权 daemon) | daemon 有 root 权限 |
| Pod 支持 | 原生 | 需 Docker Compose |
| Compose 兼容 | podman-compose / 兼容 docker-compose | 原生 |
| Systemd 集成 | 原生(quadlet) | 第三方 |
| K8s YAML 生成 | podman generate kube | 无 |
| 镜像格式 | OCI 标准 | OCI 标准 |
| macOS/Windows | Podman Machine (VM) | Docker Desktop (VM) |
核心概念¶
| 概念 | 说明 |
|---|---|
| Container | 与 Docker 容器相同的 OCI 容器 |
| Pod | 共享网络/IPC 命名空间的容器组(对应 K8s Pod) |
| Image | OCI 容器镜像,与 Docker 镜像通用 |
| Volume | 持久化存储卷 |
| Network | 容器网络(CNI/netavark) |
| Quadlet | systemd 原生管理容器的方式 |
Rootless 工作原理¶
传统 Docker:
用户 → docker CLI → docker daemon (root) → containerd → 容器
Podman rootless:
用户 → podman CLI → conmon → 容器 (用户命名空间映射)
无特权 daemon,每个容器由 conmon(容器监控器)管理,崩溃不影响其他容器。
安装与配置¶
Linux¶
# Fedora/RHEL/CentOS
sudo dnf install podman
# Ubuntu/Debian
sudo apt install podman
# Arch Linux
sudo pacman -S podman
macOS¶
Windows¶
# WSL2 中安装
wsl --install Ubuntu
# 然后在 WSL 中 apt install podman
# 或使用 Podman Desktop
winget install RedHat.Podman-Desktop
Rootless 配置(Linux)¶
# 通常安装后即可用,检查 subuid/subgid
cat /etc/subuid
cat /etc/subgid
# 应有类似: username:100000:65536
# 如果没有,手动添加
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
Docker 兼容别名¶
验证¶
快速上手¶
基本操作(与 Docker 完全相同)¶
# 拉取镜像
podman pull python:3.12-slim
# 运行容器
podman run -it --rm python:3.12-slim python -c "print('Hello Podman')"
# 后台运行
podman run -d --name myapp -p 8080:80 nginx
# 查看运行中的容器
podman ps
# 查看日志
podman logs myapp
# 进入容器
podman exec -it myapp bash
# 停止并删除
podman stop myapp
podman rm myapp
构建镜像¶
挂载卷¶
podman run -v ./data:/app/data:Z python:3.12 python /app/data/script.py
# :Z 标签处理 SELinux 上下文(Linux 特有)
进阶用法¶
1. Pod 管理¶
# 创建 Pod(共享网络)
podman pod create --name webapp -p 8080:80 -p 5432:5432
# 在 Pod 中添加容器
podman run -d --pod webapp --name db postgres:16
podman run -d --pod webapp --name app -e DB_HOST=localhost myapp
# Pod 内容器通过 localhost 互通
# db 和 app 共享网络命名空间
# 查看 Pod
podman pod ps
podman pod inspect webapp
# 停止/删除 Pod(包含所有容器)
podman pod stop webapp
podman pod rm webapp
2. 生成 Kubernetes YAML¶
# 从运行中的 Pod 生成 K8s 配置
podman generate kube webapp > webapp.yaml
# 用生成的 YAML 在 Podman 中重建
podman play kube webapp.yaml
# 也可以直接在 K8s 集群中使用
kubectl apply -f webapp.yaml
3. Podman Compose¶
# 安装 podman-compose
pip install podman-compose
# 使用已有 docker-compose.yml
podman-compose up -d
podman-compose down
# 或使用 Docker Compose(v2+ 兼容 Podman socket)
systemctl --user enable --now podman.socket
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock
docker compose up -d
4. Quadlet(Systemd 集成)¶
创建 ~/.config/containers/systemd/myapp.container:
[Unit]
Description=My Application
After=network-online.target
[Container]
Image=docker.io/library/nginx:latest
PublishPort=8080:80
Volume=./html:/usr/share/nginx/html:ro,Z
[Service]
Restart=always
[Install]
WantedBy=default.target
# 重新加载并启动
systemctl --user daemon-reload
systemctl --user start myapp
systemctl --user enable myapp
# 查看状态
systemctl --user status myapp
5. 多阶段构建¶
# Containerfile
FROM rust:1.75 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release
FROM debian:bookworm-slim
COPY --from=builder /app/target/release/myapp /usr/local/bin/
EXPOSE 8080
CMD ["myapp"]
6. 镜像签名与验证¶
# 配置可信镜像源
# /etc/containers/policy.json
# 签名镜像
podman push --sign-by you@example.com myregistry.io/myapp:latest
# 拉取时验证签名
podman pull --tls-verify myregistry.io/myapp:latest
7. 网络管理¶
# 创建自定义网络
podman network create mynet
# 容器加入网络
podman run -d --network mynet --name api myapi
podman run -d --network mynet --name worker myworker
# 容器间通过名称通信
# worker 中可以 curl http://api:8080
# 查看网络
podman network ls
podman network inspect mynet
8. 资源限制¶
# CPU 和内存限制
podman run -d \
--cpus=2 \
--memory=1g \
--memory-swap=2g \
--name limited-app \
myapp
# 查看资源使用
podman stats
9. 镜像加速(国内)¶
编辑 ~/.config/containers/registries.conf:
unqualified-search-registries = ["docker.io"]
[[registry]]
prefix = "docker.io"
location = "docker.io"
[[registry.mirror]]
location = "mirror.ccs.tencentyun.com"
常见问题与排错¶
Q: "permission denied" 运行容器¶
Q: 端口 < 1024 无法绑定(rootless)¶
# 方法1: 使用高端口
podman run -p 8080:80 nginx
# 方法2: 允许非特权端口绑定
sudo sysctl net.ipv4.ip_unprivileged_port_start=80
Q: 存储空间不足¶
Q: macOS 上容器无法访问主机服务¶
# macOS 使用虚拟机,主机地址为
# host.containers.internal 或 host.docker.internal
podman run --add-host=host.docker.internal:host-gateway myapp
Q: Docker Compose 文件不兼容¶
大部分 docker-compose.yml 可直接使用。已知差异: - network_mode: host 在 rootless 中行为不同 - 部分特权操作需要 --privileged - Volume SELinux 标签需要 :Z 或 :z
Q: 如何与 VS Code Dev Container 集成¶
// .devcontainer/devcontainer.json
{
"dockerComposeFile": "docker-compose.yml",
"settings": {
"dev.containers.dockerPath": "podman"
}
}
或设置 VS Code:
参考资源¶
- 官方文档:https://docs.podman.io
- GitHub 仓库:https://github.com/containers/podman
- Podman Desktop:https://podman-desktop.io
- Quadlet 指南:https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html
- 从 Docker 迁移:https://podman.io/docs/installation#migrating-from-docker
- Red Hat 容器文档:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/building_running_and_managing_containers
- Awesome Podman:https://github.com/containers/podman/blob/main/awesome.md