Podman 和 Podman Compose 核心总结
Podman 和 Podman Compose 核心总结
概述
本文档提供 Podman 和 Podman Compose 的完整使用指南,涵盖安装、配置、使用和故障排除等方面。
Podman 核心概念
什么是 Podman
Podman 是 Red Hat 开发的开源容器引擎,作为 Docker 的安全替代品,采用无守护进程架构,提供更安全、更轻量的容器运行环境。
主要特点
- 无守护进程:直接通过 runC 运行容器,无需长期运行的后台服务
- Rootless 支持:普通用户无需 root 权限即可运行容器
- Docker 兼容:命令行接口与 Docker 高度兼容
- 模块化设计:专注于容器运行,构建功能由 Buildah 等工具负责
- 安全优先:默认使用用户命名空间,降低安全风险
与 Docker 的区别
| 特性 | Podman | Docker |
|---|---|---|
| 架构 | 无守护进程 | 客户端-服务器 |
| 权限 | 支持 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 --versionCentOS/RHEL 8+ 系统安装
# 使用 dnf 安装
sudo dnf install -y podman
# 或者安装容器工具包
sudo dnf install -y @container-tools
# 验证安装
podman --versionRocky 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 infoRootless 模式配置(可选但推荐)
# 安装必要的依赖
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-toolsPodman 常用命令
镜像管理
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 -d2. 权限问题
症状:无法创建容器或访问资源
解决方案:
# 使用 Rootless 模式(推荐)
podman-compose --user $(id -u):$(id -g) up -d
# 检查用户命名空间配置
podman unshare cat /proc/self/uid_map3. 网络问题
症状:容器无法访问外部网络或端口冲突
解决方案:
# 配置防火墙规则
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
# 检查端口占用
netstat -tlnp | grep 8080
# 或
ss -tlnp | grep 80804. 镜像问题
症状:镜像拉取失败或速度很慢
解决方案:
# 配置国内镜像源
sudo nano /etc/containers/registries.conf
# 添加以下内容:
[[registry]]
location = "docker.io"
[[registry.mirror]]
location = "registry.docker-cn.com"
# 重新拉取镜像
podman-compose pull5. 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 ~/.bashrc6. 容器启动失败
症状:服务无法正常启动或立即退出
解决方案:
# 查看详细错误信息
podman-compose logs [服务名]
# 进入失败容器排查
podman-compose exec [服务名] /bin/bash
# 检查容器状态
podman ps -a
podman inspect [容器ID]
# 检查配置文件语法
podman-compose config7. 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.servicePodman 与 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.service 或 pod-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.servicePodman 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 nginx3. 无法访问用户服务日志
症状:无法使用 journalctl 查看用户服务日志
解决方案:
# 使用正确的命令格式
journalctl --user -xeu 'podman-compose@项目名称'
# 查看所有用户服务日志
journalctl --user最佳实践
Podman 使用建议
- 优先使用 Rootless 模式:提高安全性,避免使用 root 权限
- 配置镜像加速:针对中国用户,配置国内镜像源
- 使用 systemd 管理容器:使用
podman generate systemd生成服务文件或 Podman Compose 的 systemd 集成 - 启用 linger 功能:确保容器在用户登出后继续运行
- 定期清理资源:使用
podman system prune清理无用资源 - 合理分配资源:为容器设置适当的内存和 CPU 限制
Podman Compose 使用建议
- 版本控制:将 docker-compose.yml 纳入 Git 管理
- 环境分离:使用 .env 文件管理环境变量
- 健康检查:为关键服务配置健康检查
- 资源限制:合理设置内存和 CPU 限制
- 数据持久化:使用 volumes 管理重要数据
- 服务依赖:正确使用 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 则简化了多容器应用的管理,让复杂应用的部署变得简单高效。
核心优势
- 安全性:无守护进程架构,支持 Rootless 模式
- 兼容性:与 Docker 命令高度兼容,迁移成本低
- 轻量性:无需长期运行的后台服务
- 模块化:专注容器运行,其他功能由专门工具负责
使用场景
- 开发环境:快速搭建本地开发环境
- 测试环境:隔离的测试环境部署
- 生产环境:安全要求较高的生产部署
- CI/CD:集成到持续集成和部署流程
通过合理使用 Podman 和 Podman Compose,您可以在保证安全性的同时,享受现代化的容器编排体验。