跳转到内容

Podman 入门

Podman 是 Red Hat 主导开发的容器引擎,与 Docker 的核心区别如下:

特性PodmanDocker
守护进程无守护进程(daemonless)需要 dockerd 守护进程
Root 权限原生支持 rootless 容器需要额外配置
命令兼容兼容 Docker CLI-
Pod 支持原生支持 Pod(类似 Kubernetes)不支持
系统集成使用 systemd 管理容器生命周期自有守护进程管理
默认可用RHEL/CentOS/AlmaLinux 默认仓库自带需添加第三方仓库
Terminal window
sudo dnf install -y podman

验证安装:

Terminal window
podman --version
podman info
Terminal window
# 从 Docker Hub 拉取镜像
podman pull docker.io/library/nginx:latest
# 从 Quay.io 拉取镜像
podman pull quay.io/centos/centos:stream9
# 查看本地镜像列表
podman images
Terminal window
# 前台运行,退出后自动删除
podman run --rm -it centos:stream9 /bin/bash
# 后台运行 Nginx,映射端口 8080 到容器 80
podman run -d --name my-nginx -p 8080:80 docker.io/library/nginx:latest
# 挂载本地目录到容器
podman run -d --name my-web \
-p 8080:80 \
-v /srv/www:/usr/share/nginx/html:Z \
docker.io/library/nginx:latest
Terminal window
# 查看正在运行的容器
podman ps
# 查看所有容器(包括已停止的)
podman ps -a
# 查看容器详细信息
podman inspect my-nginx
# 查看容器日志
podman logs my-nginx
# 实时跟踪日志
podman logs -f my-nginx
Terminal window
# 停止容器
podman stop my-nginx
# 启动已停止的容器
podman start my-nginx
# 重启容器
podman restart my-nginx
# 删除已停止的容器
podman rm my-nginx
# 强制删除运行中的容器
podman rm -f my-nginx
# 删除所有已停止的容器
podman container prune
Terminal window
# 以交互式终端进入容器
podman exec -it my-nginx /bin/bash
# 在容器中执行单条命令
podman exec my-nginx cat /etc/nginx/nginx.conf

创建一个 Containerfile(等同于 Dockerfile):

FROM docker.io/library/almalinux:9-minimal
# 安装应用
RUN microdnf install -y httpd && microdnf clean all
# 复制配置和网页文件
COPY index.html /var/www/html/index.html
COPY httpd.conf /etc/httpd/conf/httpd.conf
# 开放端口
EXPOSE 80
# 启动命令
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
Terminal window
# 构建镜像,-t 指定名称和标签
podman build -t my-httpd:v1 .
# 查看构建好的镜像
podman images
# 使用自建镜像运行容器
podman run -d --name web -p 8080:80 my-httpd:v1
Terminal window
# 将镜像保存为 tar 文件
podman save -o my-httpd-v1.tar my-httpd:v1
# 从 tar 文件加载镜像
podman load -i my-httpd-v1.tar

podman-compose 是 Docker Compose 的兼容替代工具。

Terminal window
sudo dnf install -y python3-pip
pip3 install podman-compose

创建 docker-compose.yml

version: "3"
services:
web:
image: docker.io/library/nginx:latest
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:Z
depends_on:
- app
app:
image: docker.io/library/python:3.11-slim
working_dir: /app
volumes:
- ./app:/app:Z
command: python3 -m http.server 5000
ports:
- "5000:5000"
db:
image: docker.io/library/mariadb:10.11
environment:
MYSQL_ROOT_PASSWORD: changeme
MYSQL_DATABASE: myapp
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
Terminal window
# 启动所有服务(后台运行)
podman-compose up -d
# 查看服务状态
podman-compose ps
# 查看日志
podman-compose logs -f
# 停止并删除所有服务
podman-compose down

Rootless 容器是 Podman 的核心优势之一,允许普通用户无需 root 权限即可运行容器。

  1. 确认用户的 UID 映射已配置:

    Terminal window
    cat /etc/subuid
    cat /etc/subgid

    如果当前用户没有条目,手动添加:

    Terminal window
    sudo usermod --add-subuids 100000-165535 $(whoami)
    sudo usermod --add-subgids 100000-165535 $(whoami)
  2. 以普通用户身份运行容器:

    Terminal window
    podman run -d --name rootless-nginx -p 8080:80 docker.io/library/nginx:latest
  3. 验证容器进程归属:

    Terminal window
    ps aux | grep nginx
    podman top rootless-nginx

Podman 可以生成 systemd 用户服务单元,使容器在用户登录时自动启动:

Terminal window
# 为已有容器生成 systemd 单元文件
podman generate systemd --name rootless-nginx --files --new
# 将生成的文件移到用户 systemd 目录
mkdir -p ~/.config/systemd/user/
mv container-rootless-nginx.service ~/.config/systemd/user/
# 重新加载并启用服务
systemctl --user daemon-reload
systemctl --user enable --now container-rootless-nginx.service
# 允许用户服务在用户退出登录后继续运行
loginctl enable-linger $(whoami)

查看服务状态:

Terminal window
systemctl --user status container-rootless-nginx.service

Quadlet 文件放置位置:

  • 系统级(root):/etc/containers/systemd/
  • 用户级(rootless):~/.config/containers/systemd/

创建一个 .container 文件描述容器:

~/.config/containers/systemd/nginx.container
[Unit]
Description=Nginx (Quadlet 管理)
After=network-online.target
[Container]
Image=docker.io/library/nginx:latest
PublishPort=8080:80
# 卷挂载会自动加 SELinux 标签,相当于 :Z
Volume=%h/nginx/html:/usr/share/nginx/html:Z
[Service]
Restart=always
[Install]
# 开机(用户登录)自动启动
WantedBy=default.target

应用配置:

Terminal window
# 让 systemd 重新读取并生成对应的 nginx.service
systemctl --user daemon-reload
systemctl --user start nginx.service
# 查看状态(注意服务名是文件名 .container -> .service)
systemctl --user status nginx.service
# rootless 容器在用户退出后继续运行
loginctl enable-linger $(whoami)

修改容器配置时,只需编辑 .container 文件并 daemon-reload,无需像 podman generate systemd 那样重新生成单元。系统级单元把文件放到 /etc/containers/systemd/ 并改用 systemctl(不带 --user)即可。

Pod 是 Podman 的独特功能,类似于 Kubernetes 的 Pod 概念,多个容器共享同一个网络命名空间。

Terminal window
# 创建一个 Pod,映射端口
podman pod create --name my-pod -p 8080:80 -p 3306:3306
# 在 Pod 中运行 Nginx
podman run -d --pod my-pod --name pod-nginx docker.io/library/nginx:latest
# 在同一 Pod 中运行 MariaDB
podman run -d --pod my-pod --name pod-db \
-e MYSQL_ROOT_PASSWORD=changeme \
docker.io/library/mariadb:10.11
# 查看 Pod 状态
podman pod ps
podman pod inspect my-pod
# 停止和删除 Pod(会同时操作 Pod 内所有容器)
podman pod stop my-pod
podman pod rm my-pod
Terminal window
# 清理未使用的镜像
podman image prune
# 清理所有未使用的资源(镜像、容器、卷)
podman system prune -a
# 查看磁盘使用情况
podman system df
# 查看容器资源占用
podman stats

EL 10 将 Podman 从 4.x 升级到了 Podman 5.x,主要变化:

特性Podman 4.x(EL 9)Podman 5.x(EL 10)
Rootless 网络后端slirp4netnspasta(默认)
性能基准网络性能更好
API 兼容-与 Podman 4.x 基本兼容

Rootless 网络后端变化

EL 10 上 rootless 容器默认使用 pasta 作为网络后端(替代 slirp4netns),通常性能更好且无需额外配置。如有需要可手动切换:

安装 slirp4netns(如需兼容旧行为)
sudo dnf install slirp4netns
验证 Podman 版本
podman --version
podman info | grep -i network