Podman 无根容器实战:常用命令、Pod 与 Docker 兼容
上篇我们聊了 Podman 的架构优势,这一篇直接进入实战。所有命令默认在**无根(rootless)**模式下执行——也就是你以普通用户身份直接运行,无需 sudo。
无根模式到底意味着什么
在无根模式下,Podman 借助 Linux 的 user namespace,把你容器内的 uid 0(root)映射到宿主机上一个普通的高位 UID(例如 1000:100000 区间)。宿主机上真正的 root 与你容器内的 root 完全不是一回事。
# 查看当前无根映射
podman unshare cat /proc/self/uid_map
# 输出类似: 0 1000 1 1 100000 65536
小提示:无根容器因为网络需要桥接,默认使用
slirp4netns或pasta做用户态网络栈。如果你发现-p端口映射不生效,多半是这两个组件没装好。
常用命令速查
镜像与容器生命周期
# 拉取镜像
podman pull docker.io/library/redis:7-alpine
# 后台运行,端口、卷、自重启
podman run -d \
--name redis \
-p 6379:6379 \
-v $HOME/redis-data:/data \
--restart unless-stopped \
redis:7-alpine
# 查看运行中的容器
podman ps
# 查看全部(含已停止)
podman ps -a
# 进入容器执行命令
podman exec -it redis redis-cli ping
# 查看日志
podman logs -f redis
# 停止并删除
podman stop redis && podman rm redis
镜像管理
podman images # 列出本地镜像
podman rmi redis:7-alpine # 删除镜像
podman system prune -a # 清理无用镜像与容器(慎用)
Podman 的原生 Pod
这是 Podman 区别于 Docker 的杀手锏:Pod 是一等公民。一个 Pod 内的多个容器共享同一个网络命名空间(和 IP),就像 Kubernetes 里的 Pod 一样。
# 创建一个 Pod,并映射对外端口
podman pod create --name mypod -p 8080:80
# 在 Pod 内启动容器(它们共享网络)
podman run -dt --pod mypod --name web nginx:alpine
podman run -dt --pod mypod --name sidecar busybox sleep 3600
# 查看 Pod 及其容器
podman pod ps
podman pod inspect mypod
这种"本地即 K8s"的模型,让你在笔记本上就能验证多容器协作的行为,再原样搬上集群。
与 Docker 的兼容实战
一行别名,旧脚本照跑
echo "alias docker='podman'" >> ~/.bashrc
source ~/.bashrc
docker ps # 实际上调用的是 podman
替代 Docker Compose
Podman 提供官方子命令 podman-compose,并兼容现有 docker-compose.yml:
pip install podman-compose
# 直接复用已有的 compose 文件
podman-compose up -d
podman-compose down
如果你的 docker-compose.yml 里写的是 image: redis:7,Podman 默认会从 docker.io 拉取,行为一致。
用 systemd 管理容器开机自启
Podman 与 systemd 是"天作之合"。最推荐的方式是 Quadlet——用声明式文件让 systemd 接管容器。
# ~/.config/containers/systemd/redis.container
[Unit]
Description=Redis 容器
[Container]
Image=docker.io/library/redis:7-alpine
PublishPort=6379:6379
Volume=%h/redis-data:/data
[Service]
Restart=always
[Install]
WantedBy=default.target
启用与启动:
systemctl --user daemon-reload
systemctl --user enable --now redis.container
注意:无根容器要让它在用户登出后仍运行,需要执行一次
loginctl enable-linger $USER。
排错清单
| 现象 | 可能原因 | 解决方式 |
|---|---|---|
| 端口映射失败 | 缺少 slirp4netns/pasta | 安装对应包并确认版本 |
| 无法拉取镜像 | 镜像仓库地址未写全 | 显式写 docker.io/library/xxx |
| 卷权限拒绝 | 无根 UID 映射差异 | 用 podman unshare chown 修正属主 |
| 开机不自启 | 未开启 linger | loginctl enable-linger $USER |
小结
Podman 的无根模式把"最小权限"变成了默认行为,而原生 Pod、docker 兼容别名、compose 与 systemd 集成,又让它几乎无缝接替你原有的 Docker 工作流。
如果你正在评估把开发机或 CI 环境从 Docker 迁到 Podman,现在就是一个不错的时机——命令几乎不用改,安全性却实打实地提升了。