Contents

Podman 和 Podman Compose 核心总结

Podman 和 Podman Compose 核心总结

概述

本文档提供 Podman 和 Podman Compose 的完整使用指南,涵盖安装、配置、使用和故障排除等方面。

Podman 核心概念

什么是 Podman

Podman 是 Red Hat 开发的开源容器引擎,作为 Docker 的安全替代品,采用无守护进程架构,提供更安全、更轻量的容器运行环境。

主要特点

  • 无守护进程:直接通过 runC 运行容器,无需长期运行的后台服务
  • Rootless 支持:普通用户无需 root 权限即可运行容器
  • Docker 兼容:命令行接口与 Docker 高度兼容
  • 模块化设计:专注于容器运行,构建功能由 Buildah 等工具负责
  • 安全优先:默认使用用户命名空间,降低安全风险

与 Docker 的区别

特性PodmanDocker
架构无守护进程客户端-服务器
权限支持 Rootless通常需要 root
平台主要面向 Linux跨平台原生支持
工具链模块化(Buildah 等)一体化
生态社区资源相对较少成熟完善

Podman 安装指南

系统要求

  • Linux 操作系统(推荐 CentOS 8+/RHEL 8+/Rocky Linux 9+)
  • 至少 2GB 内存
  • 10GB 可用磁盘空间

Ubuntu/Debian 系统安装

# 更新软件包索引
sudo apt update

# 安装 Podman
sudo apt install -y podman

# 验证安装
podman --version

CentOS/RHEL 8+ 系统安装

# 使用 dnf 安装
sudo dnf install -y podman

# 或者安装容器工具包
sudo dnf install -y @container-tools

# 验证安装
podman --version

Rocky Linux 9 系统安装

系统更新

# 检查系统版本
cat /etc/rocky-release
# 应该输出类似:Rocky Linux release 9.x (Blue Onyx)

# 更新系统到最新
sudo dnf update -y

安装 Podman

# Rocky Linux 9 默认包含 Podman,直接安装
sudo dnf install -y podman

# 安装容器工具包(可选,包含完整工具链)
sudo dnf install -y container-tools

# 验证安装
podman --version
# 输出类似:podman version 4.x.x

服务管理

# 启动 Podman 服务
sudo systemctl start podman

# 设置开机自启
sudo systemctl enable podman

# 检查服务状态
sudo systemctl status podman

安装后配置

镜像加速配置(中国用户推荐)

# 创建配置目录
sudo mkdir -p /etc/containers

# 配置 registries.conf
sudo tee /etc/containers/registries.conf << EOF
[registries.search]
registries = ['docker.io', 'registry.fedoraproject.org', 'registry.access.redhat.com']

[[registry]]
prefix = "docker.io"
location = "docker.io"

[[registry.mirror]]
location = "registry.docker-cn.com"

[[registry.mirror]]
location = "hub-mirror.c.163.com"

[[registry.mirror]]
location = "mirror.ccs.tencentyun.com"
EOF

# 测试配置
podman info

Rootless 模式配置(可选但推荐)

# 安装必要的依赖
sudo dnf install -y shadow-utils

# 配置用户命名空间(对于新用户)
echo "user.max_user_namespaces=28633" | sudo tee /etc/sysctl.d/99-podman.conf
sudo sysctl -p /etc/sysctl.d/99-podman.conf

# 验证 Rootless 模式
podman unshare cat /proc/self/uid_map

安装常用插件

# 安装 Podman Compose 依赖
sudo dnf install -y python3 python3-pip

# 安装构建工具(可选)
sudo dnf install -y buildah skopeo

# 安装网络工具(调试用)
sudo dnf install -y net-tools

Podman 常用命令

镜像管理

podman images          # 查看本地镜像
podman search nginx    # 搜索镜像
podman pull nginx      # 下载镜像
podman rmi nginx       # 删除镜像

容器操作

podman run -d --name web nginx    # 运行容器
podman ps                          # 查看运行中的容器
podman stop web                    # 停止容器
podman rm web                      # 删除容器
podman exec -it web bash           # 进入容器终端

文件操作

podman cp web:/etc/nginx/nginx.conf ./  # 从容器复制文件
podman cp ./config.conf web:/etc/nginx/ # 复制文件到容器

Podman Compose 核心概念

什么是 Podman Compose

Podman Compose 是 Docker Compose 的替代品,用于通过 YAML 文件定义和管理多容器应用。它提供了与 Docker Compose 相同的用户体验,但基于更安全的 Podman 容器引擎。

安装 Podman Compose

前置依赖检查

# 检查 Python3 是否已安装
python3 --version
# Rocky Linux 9 默认包含 Python 3.9

# 检查 pip3
pip3 --version
# 如果未安装,使用 sudo dnf install -y python3-pip

安装方法

方法 1:直接安装(推荐)

# 使用 pip3 安装
pip3 install podman-compose

# 验证安装
podman-compose --version

方法 2:国内加速(中国用户)

# 使用清华源安装
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple podman-compose

方法 3:开发版安装(最新功能)

# 从 GitHub 安装最新开发版
pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz

方法 4:用户目录安装(无需 root)

# 安装到用户目录
pip3 install --user podman-compose

# 添加 PATH(如果命令不可用)
echo 'export PATH=$PATH:~/.local/bin' >> ~/.bashrc
source ~/.bashrc

验证安装

# 检查版本
podman-compose --version

# 测试配置文件
mkdir -p ~/test-compose
cd ~/test-compose

# 创建测试配置
cat > podman-compose.yml << EOF
version: '3'
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
EOF

# 测试配置
podman-compose config

# 启动测试服务
podman-compose up -d

# 检查状态
podman-compose ps

# 停止并清理
podman-compose down
cd ~ && rm -rf ~/test-compose

环境变量配置

# 添加到 PATH(如果未自动添加)
echo 'export PATH=$PATH:~/.local/bin' >> ~/.bashrc

# 设置 Podman Compose 提供程序(某些系统需要)
echo 'export PODMAN_COMPOSE_PROVIDER=podman' >> ~/.bashrc

# 重新加载配置
source ~/.bashrc

卸载方法

# 卸载 podman-compose
pip3 uninstall podman-compose

# 清理残留文件(可选)
rm -rf ~/.local/lib/python*/site-packages/podman_compose*
rm -rf ~/.cache/pip/

配置文件结构

podman-compose.yml 示例

version: '3.8'

services:
  web:
    image: nginx:alpine
    container_name: web-server
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./html:/usr/share/nginx/html:ro
    networks:
      - web-network
    restart: unless-stopped
    depends_on:
      - app
      - db

  app:
    image: php:8.1-fpm-alpine
    container_name: php-app
    volumes:
      - ./app:/var/www/html
    networks:
      - web-network
      - app-network
    environment:
      - DB_HOST=db
      - DB_NAME=myapp
      - DB_USER=appuser
      - DB_PASS=secretpass
    restart: unless-stopped
    depends_on:
      - db

  db:
    image: mysql:8.0
    container_name: mysql-db
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: myapp
      MYSQL_USER: appuser
      MYSQL_PASSWORD: secretpass
    volumes:
      - db-data:/var/lib/mysql
      - ./mysql.cnf:/etc/mysql/conf.d/custom.cnf:ro
    networks:
      - app-network
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    container_name: redis-cache
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    networks:
      - app-network
    restart: unless-stopped

networks:
  web-network:
    driver: bridge
  app-network:
    driver: bridge

volumes:
  db-data:
    driver: local
  redis-data:
    driver: local

环境变量文件

# .env 文件
MYSQL_ROOT_PASSWORD=supersecretrootpass
MYSQL_DATABASE=production_db
MYSQL_USER=produser
MYSQL_PASSWORD=prodpass

# 在 docker-compose.yml 中使用
environment:
  MYSQL_ROOT_PASSWORD: \({MYSQL_ROOT_PASSWORD}
  MYSQL_DATABASE: \){MYSQL_DATABASE}

实际应用示例

WordPress 站点

version: '3.8'

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpresspass
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress:/var/www/html
    depends_on:
      - db

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpresspass
      MYSQL_ROOT_PASSWORD: rootpass
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

开发环境

version: '3.8'

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development

  backend:
    build: ./backend
    ports:
      - "5000:5000"
    volumes:
      - ./backend:/app
    environment:
      - FLASK_ENV=development
      - DATABASE_URL=postgresql://user:pass@db:5432/devdb
    depends_on:
      - db

  db:
    image: postgres:14
    environment:
      POSTGRES_DB: devdb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

常用命令速查

基本操作

# 启动服务
podman-compose up -d

# 停止服务
podman-compose down

# 重启服务
podman-compose restart

# 查看状态
podman-compose ps

# 查看日志
podman-compose logs

# 构建镜像
podman-compose build

高级操作

# 扩展服务
podman-compose up -d --scale web=3

# 重新创建容器
podman-compose up -d --force-recreate

# 不缓存构建
podman-compose build --no-cache

# 进入容器
podman-compose exec web bash

# 运行一次性命令
podman-compose run --rm web python manage.py migrate

故障排除

常见问题及解决方案

1. “Run compose workloads via an external provider” 错误

症状:运行 podman-compose 时出现此提示

原因:Podman Compose 无法找到外部提供程序

解决方案

# 1. 确保 Podman Compose 正确安装
which podman-compose

# 2. 检查 Podman 是否正常运行
podman version

# 3. 设置环境变量指定提供程序
export PODMAN_COMPOSE_PROVIDER=podman
echo 'export PODMAN_COMPOSE_PROVIDER=podman' >> ~/.bashrc

# 4. 重新运行命令
podman-compose up -d

2. 权限问题

症状:无法创建容器或访问资源

解决方案

# 使用 Rootless 模式(推荐)
podman-compose --user $(id -u):$(id -g) up -d

# 检查用户命名空间配置
podman unshare cat /proc/self/uid_map

3. 网络问题

症状:容器无法访问外部网络或端口冲突

解决方案

# 配置防火墙规则
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload

# 检查端口占用
netstat -tlnp | grep 8080
# 或
ss -tlnp | grep 8080

4. 镜像问题

症状:镜像拉取失败或速度很慢

解决方案

# 配置国内镜像源
sudo nano /etc/containers/registries.conf

# 添加以下内容:
[[registry]]
location = "docker.io"
[[registry.mirror]]
location = "registry.docker-cn.com"

# 重新拉取镜像
podman-compose pull

5. Python 环境问题

症状:Podman Compose 无法运行或报错

解决方案

# 检查 Python 环境
python3 --version
pip3 --version

# 重新安装 Podman Compose
pip3 uninstall podman-compose
pip3 install --user podman-compose

# 确保 PATH 包含用户 bin 目录
echo 'export PATH=$PATH:~/.local/bin' >> ~/.bashrc
source ~/.bashrc

6. 容器启动失败

症状:服务无法正常启动或立即退出

解决方案

# 查看详细错误信息
podman-compose logs [服务名]

# 进入失败容器排查
podman-compose exec [服务名] /bin/bash

# 检查容器状态
podman ps -a
podman inspect [容器ID]

# 检查配置文件语法
podman-compose config

7. systemd 服务相关问题

症状:使用 systemd 管理的 Podman 容器无法正常启动

解决方案

# 检查用户 linger 状态
loginctl show-user $(whoami) | grep Linger

# 如果为 no,启用 linger
sudo loginctl enable-linger $(whoami)

# 重新加载 systemd 配置
systemctl --user daemon-reload

# 查看详细错误日志
journalctl --user -xeu container-service-name.service

# 检查服务文件权限
chmod 644 ~/.config/systemd/user/container-service-name.service

Podman 与 systemd 服务集成

systemd user service 概念

systemd 为每个用户提供了管理自己服务的方法,称为 user instance。通过 user instance,用户可以自行管理自己的 user service,无需 root 权限。用户自定义的服务配置文件通常位于 $XDG_CONFIG_PATH/systemd/user(通常是 ~/.config/systemd/user/)。

每次用户登录(创建新会话)时,会创建一个 systemd user instance 并启动用户激活的服务。常见的用户服务包括:

  • pipewire 守护进程
  • gpg-agent
  • 代理服务
  • 容器服务(如 Podman 容器)

Linger 机制

通常情况下,用户服务只会在用户创建首个活跃会话(即登录)时自动启动,并在用户登出全部会话后自动停止。这对于需要持续运行的容器服务来说是个问题。

systemd 自 233 版本后提供了 loginctl enable-linger 功能,允许用户服务在系统启动时一并启动,并且不会因为用户登出而停止。这对于使用专用非 root 用户运行容器服务至关重要。

启用 Linger

# 为当前用户启用 linger
sudo loginctl enable-linger $(whoami)

# 或者指定用户名
sudo loginctl enable-linger username

# 检查 linger 状态
loginctl show-user $(whoami) | grep Linger

使用 podman generate systemd 生成服务文件

Podman 提供了生成 systemd 服务文件的内置功能,适用于单个容器或 Pod:

# 为单个容器生成服务文件
podman generate systemd --new --name container_name --files

# 为 Pod 生成服务文件
podman generate systemd --new --name pod_name --files

参数说明:

  • --new:服务启动时创建新容器
  • --name:指定容器或 Pod 名称
  • --files:生成服务文件到当前目录

生成的服务文件通常命名为 container-container_name.servicepod-pod_name.service

配置和启用生成的服务文件

# 创建用户服务目录
mkdir -p ~/.config/systemd/user/

# 移动生成的服务文件
mv container-container_name.service ~/.config/systemd/user/

# 重新加载 systemd 配置
systemctl --user daemon-reload

# 启用并启动服务
systemctl --user enable --now container-container_name.service

# 检查服务状态
systemctl --user status container-container_name.service

# 查看服务日志
journalctl --user -xeu container-container_name.service

Podman Compose 与 systemd 集成

Podman Compose 提供了与 systemd 直接集成的功能,可以更方便地管理多容器应用:

安装服务模板

首先需要以 root 用户执行以下命令安装服务模板:

podman-compose systemd -a create-unit

这会创建一个系统级的服务模板,用于管理 Podman Compose 项目。

使用 Podman Compose systemd 集成

在包含 docker-compose.yml 文件的项目目录中,可以使用以下命令启用服务:

# 启用并立即启动服务
systemctl --user enable --now 'podman-compose@项目名称'

# 查看服务状态
systemctl --user status 'podman-compose@项目名称'

# 查看服务日志
journalctl --user -xeu 'podman-compose@项目名称'

注意:项目名称默认为当前目录名称,可以根据实际情况指定。

Podman Compose 服务的管理命令

# 启动服务
systemctl --user start 'podman-compose@项目名称'

# 停止服务
systemctl --user stop 'podman-compose@项目名称'

# 重启服务
systemctl --user restart 'podman-compose@项目名称'

# 禁用服务(开机不自动启动)
systemctl --user disable 'podman-compose@项目名称'

常见问题及解决方案

1. 容器在用户登出后停止

症状:用户登出后,使用 Podman 运行的容器自动停止

原因:未启用用户的 linger 功能

解决方案

sudo loginctl enable-linger $(whoami)

2. cgroup 相关错误

症状:日志中出现 “The cgroupv2 manager is set to systemd but there is no systemd user session available”

原因:缺少 systemd 用户会话或用户会话配置不正确

解决方案

# 启用 linger
sudo loginctl enable-linger $(whoami)

# 或者显式指定 cgroup 管理器
podman run --cgroup-manager=cgroupfs nginx

3. 无法访问用户服务日志

症状:无法使用 journalctl 查看用户服务日志

解决方案

# 使用正确的命令格式
journalctl --user -xeu 'podman-compose@项目名称'

# 查看所有用户服务日志
journalctl --user

最佳实践

Podman 使用建议

  1. 优先使用 Rootless 模式:提高安全性,避免使用 root 权限
  2. 配置镜像加速:针对中国用户,配置国内镜像源
  3. 使用 systemd 管理容器:使用 podman generate systemd 生成服务文件或 Podman Compose 的 systemd 集成
  4. 启用 linger 功能:确保容器在用户登出后继续运行
  5. 定期清理资源:使用 podman system prune 清理无用资源
  6. 合理分配资源:为容器设置适当的内存和 CPU 限制

Podman Compose 使用建议

  1. 版本控制:将 docker-compose.yml 纳入 Git 管理
  2. 环境分离:使用 .env 文件管理环境变量
  3. 健康检查:为关键服务配置健康检查
  4. 资源限制:合理设置内存和 CPU 限制
  5. 数据持久化:使用 volumes 管理重要数据
  6. 服务依赖:正确使用 depends_on 管理服务启动顺序

配置优化

version: '3'
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro  # 只读挂载
    restart: unless-stopped              # 自动重启策略
    healthcheck:                         # 健康检查
      test: ["CMD", "curl", "-f", "http://localhost/"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:                              # 资源限制
      resources:
        limits:
          memory: 256M
        reservations:
          memory: 128M

总结

Podman 提供了更安全、更轻量的容器运行环境,特别适合对安全性要求较高的场景。Podman Compose 则简化了多容器应用的管理,让复杂应用的部署变得简单高效。

核心优势

  1. 安全性:无守护进程架构,支持 Rootless 模式
  2. 兼容性:与 Docker 命令高度兼容,迁移成本低
  3. 轻量性:无需长期运行的后台服务
  4. 模块化:专注容器运行,其他功能由专门工具负责

使用场景

  • 开发环境:快速搭建本地开发环境
  • 测试环境:隔离的测试环境部署
  • 生产环境:安全要求较高的生产部署
  • CI/CD:集成到持续集成和部署流程

通过合理使用 Podman 和 Podman Compose,您可以在保证安全性的同时,享受现代化的容器编排体验。