Podman 上手:安装、日常命令、镜像加速与 Quadlet 开机自启
Fedora 自带的容器工具就是 Podman,不需要装 Docker。Cloud 镜像上实测:
podman --versionpodman info --format '{{.Host.Security.Rootless}}'podman version 6.1.0truetrue 表示可以在 rootless 模式下运行——普通用户不用 sudo 也能跑容器。
sudo dnf install podman要兼容 docker 命令(很多脚本写死了 docker):
sudo dnf install podman-docker装完 docker 就是 podman 的软链接,docker ps 能用。
跑一个容器:
podman run --rm docker.io/library/alpine echo "hello from podman"hello from podman--rm 是跑完即删,不留垃圾。
看镜像与容器:
podman images --format "{{.Repository}}:{{.Tag}} {{.Size}}"podman ps -adocker.io/library/alpine:latest 8.72 MBdocker 与 podman 命令对照
Section titled “docker 与 podman 命令对照”| 用途 | docker | podman |
|---|---|---|
| 跑容器 | docker run | podman run |
| 看运行中 | docker ps | podman ps |
| 看全部 | docker ps -a | podman ps -a |
| 进容器 | docker exec -it | podman exec -it |
| 看日志 | docker logs | podman logs |
| 构建镜像 | docker build | podman build(或 buildah) |
| 编排 | docker compose | podman compose / Quadlet |
| 守护进程 | 有 dockerd | 无守护进程 |
最后一行是关键:Podman 直接调 runc/crun,没有常驻守护进程,也就没有 systemctl status docker 这回事。
国内镜像加速
Section titled “国内镜像加速”默认从 Docker Hub 拉,国内经常超时。加一份 registry 重写:
sudo tee /etc/containers/registries.conf.d/99-cn.conf >/dev/null <<'EOF'unqualified-search-registries = ["docker.io"]
[[registry]]prefix = "docker.io"location = "docker.m.daocloud.io"EOF之后 podman pull nginx 就走镜像站。实测拉 alpine:
time podman pull -q docker.io/library/alpinereal 0m9.692s数据卷与端口
Section titled “数据卷与端口”podman run -d --name web \ -p 8080:80 \ -v /srv/html:/usr/share/nginx/html:Z \ docker.io/library/nginx-v 末尾的 :Z 是 SELinux 标签,Fedora 上必须加——否则容器读不到宿主机目录,报 Permission denied(原理见 SELinux)。
验证:
curl -s http://127.0.0.1:8080/ | head -3podman logs web --tail 3podman exec -it web shQuadlet:让容器开机自启
Section titled “Quadlet:让容器开机自启”这是 Podman 最实用的部分。传统做法是 podman generate systemd,6.x 已改用 Quadlet——写一个声明文件,systemd 自动生成服务单元。
先确认目录与生成器:
ls -d /etc/containers/systemdls /usr/lib/systemd/system-generators/ | grep podman/etc/containers/systemdpodman-system-generator写一个容器:
sudo tee /etc/containers/systemd/web.container >/dev/null <<'EOF'[Unit]Description=Demo web container
[Container]Image=docker.io/library/alpine:latestExec=sleep infinity
[Install]WantedBy=default.targetEOF重载并查看生成的单元:
sudo systemctl daemon-reloadsystemctl status web.service --no-pager | head -5○ web.service - Demo web container Loaded: loaded (/etc/containers/systemd/web.container; generated) Active: inactive (dead)注意 generated:这个 .service 不是你写的,是 Quadlet 从 .container 生成的。不要手工编辑它。
启动:
sudo systemctl start web.servicesystemctl is-active web.servicepodman ps --format "{{.Names}} {{.Status}}"activesystemd-web Up 2 seconds容器名自动变成 systemd-web(前缀 systemd-)。
用户级 Quadlet(rootless,推荐)
Section titled “用户级 Quadlet(rootless,推荐)”写进用户目录,不需要 sudo:
mkdir -p ~/.config/containers/systemdcp /etc/containers/systemd/web.container ~/.config/containers/systemd/systemctl --user daemon-reloadsystemctl --user start web.service要让用户服务在未登录时也运行(比如开机就起):
sudo loginctl enable-linger $USER从 Docker 迁移
Section titled “从 Docker 迁移”三条常见改动:
| Docker 里的东西 | Podman 上怎么办 |
|---|---|
docker compose up | dnf install podman-compose 后用 podman-compose up,或转成 Quadlet |
systemctl restart docker | 没有守护进程;直接操作容器或 restart 对应 service |
/var/run/docker.sock | 装 podman-docker 后可用兼容 socket,但部分工具仍需改配置 |
docker build | podman build,语法一致(Dockerfile 通用) |
sudo systemctl restart docker # 报 Unit docker.service not found看到这个报错不用慌——Podman 没有守护进程可重启。
| 现象 | 原因 |
|---|---|
podman pull 超时 | 没配 registry 镜像,或镜像站缺该镜像 |
挂载目录 Permission denied | 漏了 :Z,SELinux 拦住了 |
| 容器里访问不到外网 | rootless 下需要 --network=host 或检查 pasta/slirp4netns |
| Quadlet 改了不生效 | 忘了 systemctl daemon-reload(改 .container 必须重载) |
| 用户服务退出登录就停 | 没开 loginctl enable-linger |
systemctl restart docker 失败 | Podman 无守护进程,正常 |
- 容器与 rootless — uid 映射与安全边界
- Podman 6 — 6.x 的变化
- 国内加速源 — registry 镜像与其他生态
- SELinux — 为什么挂载要加
:Z - 官方:Podman 文档