跳转到内容
搜索 Fedora 文档

    浏览当前文档目录

    Podman 上手:安装、日常命令、镜像加速与 Quadlet 开机自启

    Fedora 自带的容器工具就是 Podman,不需要装 Docker。Cloud 镜像上实测:

    Terminal window
    podman --version
    podman info --format '{{.Host.Security.Rootless}}'
    podman version 6.1.0
    true

    true 表示可以在 rootless 模式下运行——普通用户不用 sudo 也能跑容器。

    rootless 结构:用户调用 podman,conmon 托管容器,Quadlet 交给 systemd

    Terminal window
    sudo dnf install podman

    要兼容 docker 命令(很多脚本写死了 docker):

    Terminal window
    sudo dnf install podman-docker

    装完 docker 就是 podman 的软链接,docker ps 能用。

    跑一个容器:

    Terminal window
    podman run --rm docker.io/library/alpine echo "hello from podman"
    hello from podman

    --rm 是跑完即删,不留垃圾。

    看镜像与容器:

    Terminal window
    podman images --format "{{.Repository}}:{{.Tag}} {{.Size}}"
    podman ps -a
    docker.io/library/alpine:latest 8.72 MB
    用途dockerpodman
    跑容器docker runpodman run
    看运行中docker pspodman ps
    看全部docker ps -apodman ps -a
    进容器docker exec -itpodman exec -it
    看日志docker logspodman logs
    构建镜像docker buildpodman build(或 buildah)
    编排docker composepodman compose / Quadlet
    守护进程有 dockerd无守护进程

    最后一行是关键:Podman 直接调 runc/crun,没有常驻守护进程,也就没有 systemctl status docker 这回事。

    默认从 Docker Hub 拉,国内经常超时。加一份 registry 重写:

    Terminal window
    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:

    Terminal window
    time podman pull -q docker.io/library/alpine
    real 0m9.692s
    Terminal window
    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)。

    验证:

    Terminal window
    curl -s http://127.0.0.1:8080/ | head -3
    podman logs web --tail 3
    podman exec -it web sh

    这是 Podman 最实用的部分。传统做法是 podman generate systemd,6.x 已改用 Quadlet——写一个声明文件,systemd 自动生成服务单元。

    先确认目录与生成器:

    Terminal window
    ls -d /etc/containers/systemd
    ls /usr/lib/systemd/system-generators/ | grep podman
    /etc/containers/systemd
    podman-system-generator

    写一个容器:

    Terminal window
    sudo tee /etc/containers/systemd/web.container >/dev/null <<'EOF'
    [Unit]
    Description=Demo web container
    [Container]
    Image=docker.io/library/alpine:latest
    Exec=sleep infinity
    [Install]
    WantedBy=default.target
    EOF

    重载并查看生成的单元:

    Terminal window
    sudo systemctl daemon-reload
    systemctl 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 生成的。不要手工编辑它。

    启动:

    Terminal window
    sudo systemctl start web.service
    systemctl is-active web.service
    podman ps --format "{{.Names}} {{.Status}}"
    active
    systemd-web Up 2 seconds

    容器名自动变成 systemd-web(前缀 systemd-)。

    写进用户目录,不需要 sudo:

    Terminal window
    mkdir -p ~/.config/containers/systemd
    cp /etc/containers/systemd/web.container ~/.config/containers/systemd/
    systemctl --user daemon-reload
    systemctl --user start web.service

    要让用户服务在未登录时也运行(比如开机就起):

    Terminal window
    sudo loginctl enable-linger $USER

    三条常见改动:

    Docker 里的东西Podman 上怎么办
    docker compose updnf install podman-compose 后用 podman-compose up,或转成 Quadlet
    systemctl restart docker没有守护进程;直接操作容器或 restart 对应 service
    /var/run/docker.sock装 podman-docker 后可用兼容 socket,但部分工具仍需改配置
    docker buildpodman build,语法一致(Dockerfile 通用)
    Terminal window
    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 无守护进程,正常