一份面向 Linux 运维、后端开发、DevOps 工程师的系统化 Podman 教程。本文涵盖架构原理、安装配置、镜像管理、容器编排、网络存储、生产部署、性能优化、故障排查与 Kubernetes 集成等全方位内容。
目录
一、Podman 概述与发展历程
1.1 什么是 Podman
Podman(Pod Manager) 是由 Red Hat 主导开发的开源容器引擎,遵循 OCI(Open Container Initiative)标准。它提供了与 Docker 兼容的命令行接口,但采用了完全不同的架构设计理念。
1.2 发展历程
2018年初:Podman 1.0 正式发布,主打 daemonless 架构
2019年:RHEL 8 将 Podman 作为默认容器工具,移除 Docker
2020年:Podman 2.0 发布,引入 REST API 和 Docker API 兼容层
2021年:Podman 3.0 发布,增强网络功能(netavark)
2022年:Podman 4.0 发布,原生支持 Podman Compose
2023年:Podman 4.5+ 强化 Kubernetes YAML 支持
2024年:Podman 5.0 发布,性能与安全性进一步优化
1.3 核心特性
无守护进程架构:无需常驻后台进程,降低系统资源占用
原生 Rootless 支持:普通用户即可运行容器,提升安全性
OCI 标准兼容:完全兼容 Docker 镜像格式
Pod 原生支持:支持 Kubernetes Pod 概念
systemd 深度集成:可直接生成 systemd 服务单元
强安全模型:支持 SELinux、User Namespace、cgroup v2
API 兼容层:可替代 Docker daemon(podman-docker)
1.4 适用场景
单机容器化部署:替代 Docker,安全性更高
边缘计算节点:资源受限环境的理想选择
CI/CD 流水线:构建镜像无需 Docker daemon
本地开发环境:Rootless 容器开发更安全
Kubernetes 前置验证:本地测试 Pod YAML
二、核心架构与技术原理
2.1 架构对比
Docker 架构
Docker CLI
↓
Docker Daemon (dockerd)
↓
containerd
↓
containerd-shim
↓
runc
↓
Container Process
Podman 架构
Podman CLI
↓
libpod (库)
↓
runc / crun (容器运行时)
↓
Container Process (直接 fork)
2.2 Daemonless 的技术实现
核心机制:
Podman 命令直接调用 libpod 库
libpod 通过 OCI Runtime(runc/crun)启动容器
容器进程成为 Podman 的子进程
退出后容器进程由
conmon监控(Podman 4.0+ 默认)
conmon 的作用:
监控容器进程生命周期
处理容器日志
保持 TTY 连接
容器异常退出后清理资源
2.3 Rootless 技术原理
User Namespace 映射:
# 宿主机上查看用户 ID 映射
$ cat /proc/<container_pid>/uid_map
0 1000 1
1 100000 65536
# 解释:
# 容器内 UID 0 → 宿主机 UID 1000
# 容器内 UID 1-65536 → 宿主机 UID 100000-165535
关键配置文件:
/etc/subuid:子 UID 范围/etc/subgid:子 GID 范围~/.config/containers/storage.conf:Rootless 存储配置
2.4 存储驱动
支持的存储驱动:
overlay:推荐,性能最佳(需内核 4.0+)
vfs:兼容性最佳,性能较差
btrfs:支持子卷快照
zfs:高级功能丰富
配置示例:
# /etc/containers/storage.conf
[storage]
driver = "overlay"
runroot = "/run/containers/storage"
graphroot = "/var/lib/containers/storage"
[storage.options.overlay]
mountopt = "nodev,metacopy=on"
三、Podman vs Docker:深度对比
3.1 核心差异对比表
3.2 性能对比
启动速度(冷启动 100 个容器):
Podman Rootless:约 12 秒
Podman Root:约 8 秒
Docker:约 10 秒
内存占用(空闲状态):
Podman:~5MB(仅 conmon)
Docker:~100MB(dockerd + containerd)
镜像拉取速度:
基本持平,取决于镜像源
3.3 命令兼容性
完全兼容的命令:
podman run / stop / rm / exec / logs / ps
podman build / push / pull / tag / rmi
podman network create / inspect / ls
podman volume create / inspect / ls / rm
Podman 特有命令:
podman generate systemd # 生成 systemd 服务
podman generate kube # 生成 K8s YAML
podman pod create / start # Pod 管理
使用 alias 兼容 Docker 命令:
alias docker=podman
或安装 podman-docker 包:
sudo dnf install podman-docker
3.4 何时选择 Podman
优先选择 Podman:
生产环境服务器(安全性要求高)
Rootless 容器场景
systemd 管理容器服务
CI/CD 镜像构建(无需 daemon)
Kubernetes 迁移准备
可以继续用 Docker:
Docker Desktop 桌面开发环境
团队已有 Docker 技术栈
依赖 Docker 特有功能(如 Docker Swarm)
四、安装与环境配置
4.1 主流发行版安装
Ubuntu / Debian
# Ubuntu 22.04+
sudo apt update
sudo apt install -y podman
# 验证安装
podman --version
CentOS Stream / Rocky Linux / AlmaLinux
# RHEL 系发行版
sudo dnf install -y podman
# CentOS 7 需要额外源
sudo yum install -y epel-release
sudo yum install -y podman
Fedora
# Fedora 默认已安装
sudo dnf install -y podman
Arch Linux
sudo pacman -S podman
openSUSE
sudo zypper install podman
4.2 macOS 安装(开发环境)
使用 Homebrew:
brew install podman
# 初始化 Podman Machine(VM)
podman machine init
# 启动虚拟机
podman machine start
# 验证
podman info
Podman Machine 参数调整:
# 自定义资源
podman machine init --cpus 4 --memory 8192 --disk-size 50
# 查看虚拟机状态
podman machine list
4.3 Windows 安装(WSL2 环境)
前置条件:安装 WSL2 和 Ubuntu
# 在 WSL2 Ubuntu 中安装
sudo apt update
sudo apt install -y podman
# 配置 Windows 端访问
# 在 PowerShell 中设置环境变量
$env:DOCKER_HOST = "unix:///run/podman/podman.sock"
4.4 验证安装
# 查看版本
podman --version
# 查看系统信息
podman info
# 测试运行容器
podman run --rm hello-world
五、Rootless 容器详解
5.1 Rootless 概述
Rootless 容器允许普通用户在无 root 权限的情况下运行容器,这是 Podman 最重要的安全特性之一。
5.2 检查 Rootless 状态
# 查看当前运行模式
podman info | grep -i rootless
# 输出示例:
# rootless: true
5.3 配置子 UID/GID
检查配置:
cat /etc/subuid
cat /etc/subgid
如果缺失,手动配置:
# 为用户分配 65536 个子 UID
sudo usermod --add-subuids 100000-165535 $USER
# 为用户分配 65536 个子 GID
sudo usermod --add-subgids 100000-165535 $USER
验证配置:
grep $USER /etc/subuid
grep $USER /etc/subgid
重新登录(必须):
# 注销后重新登录,或执行:
newgrp $(id -gn)
5.4 Rootless 限制与解决方案
限制 1:无法绑定特权端口(<1024)
问题:
podman run -p 80:80 nginx
# Error: cannot listen on privileged port 80
解决方案 1:使用高端口映射:
podman run -p 8080:80 nginx
解决方案 2:启用 CAP_NET_BIND_SERVICE:
# 仅对特定用户生效
sudo setcap cap_net_bind_service=+ep $(which podman)
解决方案 3:使用 rootful 模式:
sudo podman run -p 80:80 nginx
限制 2:Volume 权限映射问题
问题:容器内文件属主在宿主机上显示为高 UID。
示例:
# 容器内文件
podman exec myapp ls -ln /app/data
# 输出:-rw-r--r-- 1 0 0 1024 Jan 1 12:00 file.txt
# 宿主机查看
ls -ln /home/user/data
# 输出:-rw-r--r-- 1 100000 100000 1024 Jan 1 12:00 file.txt
解决方案:使用 :U 选项自动修复权限:
podman run -v /home/user/data:/app/data:U nginx
限制 3:cgroup 限制(cgroup v1 环境)
问题:Rootless 容器在 cgroup v1 环境下无法限制资源。
检查 cgroup 版本:
stat -fc %T /sys/fs/cgroup/
# cgroup2fs → cgroup v2(支持 Rootless)
# tmpfs → cgroup v1(不完全支持 Rootless)
解决方案:升级到 cgroup v2。
# 在 GRUB 配置中添加内核参数
sudo vim /etc/default/grub
# GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1"
# 更新 GRUB
sudo update-grub
# 重启系统
sudo reboot
5.5 Rootless 最佳实践
默认使用 Rootless:除非必须用特权端口
合理配置子 UID 范围:避免范围过小导致容器启动失败
使用
:U选项:简化 Volume 权限管理启用 cgroup v2:获得完整资源限制能力
配置 linger:允许用户服务在注销后继续运行
# 启用 linger
loginctl enable-linger $USER
六、镜像管理与优化
6.1 镜像源配置
6.1.1 国内镜像加速(必配)
配置文件路径:
Root 模式:
/etc/containers/registries.conf.d/Rootless 模式:
~/.config/containers/registries.conf
示例配置:
# /etc/containers/registries.conf.d/dockerhub.conf
[[registry]]
prefix = "docker.io"
location = "docker.io"
[[registry.mirror]]
location = "docker.mirrors.ustc.edu.cn"
[[registry.mirror]]
location = "registry.docker-cn.com"
常用国内镜像源:
中科大:
docker.mirrors.ustc.edu.cn阿里云:
<your-id>.mirror.aliyuncs.com腾讯云:
mirror.ccs.tencentyun.com网易:
hub-mirror.c.163.com
重新加载配置:
# 无需重启服务,直接生效
podman pull nginx
6.1.2 自建私有镜像仓库配置
# /etc/containers/registries.conf.d/private.conf
[[registry]]
location = "registry.example.com"
insecure = false # HTTPS 设置为 false
如果是 HTTP 私有仓库:
[[registry]]
location = "192.168.1.100:5000"
insecure = true
6.2 镜像操作
6.2.1 拉取镜像
# 拉取最新版本
podman pull nginx
# 拉取指定版本
podman pull nginx:1.25-alpine
# 拉取指定架构镜像
podman pull --platform=linux/arm64 nginx
# 从私有仓库拉取
podman pull registry.example.com/myapp:v1.0
6.2.2 查看镜像
# 列出所有镜像
podman images
# 查看镜像详细信息
podman inspect nginx:latest
# 查看镜像层历史
podman history nginx
6.2.3 镜像标签与推送
# 打标签
podman tag nginx:latest myregistry.com/nginx:v1.0
# 推送到远程仓库
podman push myregistry.com/nginx:v1.0
# 推送时登录
podman login myregistry.com
podman push myregistry.com/nginx:v1.0
6.2.4 删除镜像
# 删除单个镜像
podman rmi nginx
# 强制删除(即使有容器使用)
podman rmi -f nginx
# 删除所有未使用镜像
podman image prune
# 删除所有镜像
podman rmi -a
6.3 构建镜像
6.3.1 使用 Dockerfile
示例 Dockerfile:
FROM alpine:3.19
RUN apk add --no-cache python3 py3-pip
WORKDIR /app
COPY requirements.txt .
RUN pip3 install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python3", "app.py"]
构建镜像:
# 基础构建
podman build -t myapp:v1.0 .
# 指定 Dockerfile
podman build -f Dockerfile.prod -t myapp:prod .
# 多阶段构建示例
podman build --target production -t myapp:prod .
# 设置构建参数
podman build --build-arg VERSION=1.0 -t myapp:1.0 .
6.3.2 Buildah 高级构建
Buildah 是 Podman 生态的专用构建工具,提供更精细的控制。
# 安装 Buildah
sudo dnf install buildah
# 从基础镜像开始
buildah from alpine:3.19
# 运行命令
buildah run alpine-working-container -- apk add python3
# 复制文件
buildah copy alpine-working-container ./app /app
# 提交为镜像
buildah commit alpine-working-container myapp:v1.0
6.4 镜像优化技巧
6.4.1 多阶段构建
# 构建阶段
FROM golang:1.21 AS builder
WORKDIR /build
COPY . .
RUN go build -o app
# 运行阶段
FROM alpine:3.19
COPY --from=builder /build/app /app/
CMD ["/app/app"]
6.4.2 减小镜像体积
技巧:
使用 Alpine 基础镜像
合并 RUN 命令减少层数
删除构建缓存
使用
.dockerignore
示例:
# 不推荐:多层
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean
# 推荐:单层
RUN apt-get update && \
apt-get install -y curl && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
6.4.3 缓存优化
# 先复制依赖文件(变化少)
COPY requirements.txt .
RUN pip install -r requirements.txt
# 后复制源代码(变化多)
COPY . .
七、容器生命周期管理
7.1 创建与启动容器
7.1.1 基础运行
# 前台运行
podman run nginx
# 后台运行
podman run -d nginx
# 指定容器名称
podman run -d --name web nginx
# 自动删除(退出后删除容器)
podman run --rm alpine echo "hello"
7.1.2 端口映射
# 单端口映射
podman run -d -p 8080:80 nginx
# 多端口映射
podman run -d -p 8080:80 -p 8443:443 nginx
# 绑定到指定 IP
podman run -d -p 192.168.1.10:8080:80 nginx
# 随机端口映射
podman run -d -P nginx
7.1.3 环境变量
# 单个环境变量
podman run -e MYSQL_ROOT_PASSWORD=secret mysql
# 多个环境变量
podman run -e DB_HOST=localhost \
-e DB_PORT=3306 \
-e DB_USER=root \
myapp
# 从文件读取环境变量
podman run --env-file=.env myapp
.env 文件示例:
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=secret
7.1.4 资源限制
# 限制内存
podman run -m 512m nginx
# 限制 CPU
podman run --cpus=2 nginx
# CPU 配额(20% CPU)
podman run --cpu-quota=20000 nginx
# 限制 I/O
podman run --device-read-bps /dev/sda:1mb nginx
7.2 容器查看与监控
# 查看运行中的容器
podman ps
# 查看所有容器(包括停止的)
podman ps -a
# 查看容器详细信息
podman inspect web
# 查看容器资源使用情况
podman stats
# 查看容器日志
podman logs web
# 实时跟踪日志
podman logs -f web
# 查看最近 100 行日志
podman logs --tail 100 web
7.3 进入与执行命令
# 进入容器 Shell
podman exec -it web /bin/bash
# 执行单个命令
podman exec web ls /var/log
# 以 root 用户执行
podman exec --user root web apt-get update
# 在容器中运行后台进程
podman exec -d web nginx -s reload
7.4 停止与删除
# 停止容器
podman stop web
# 强制停止(发送 SIGKILL)
podman stop -t 0 web
# 重启容器
podman restart web
# 删除容器
podman rm web
# 强制删除运行中的容器
podman rm -f web
# 删除所有停止的容器
podman container prune
7.5 容器导出与导入
# 导出容器为 tar 文件
podman export web > web-container.tar
# 导入 tar 为镜像
cat web-container.tar | podman import - web:exported
# 保存镜像为 tar(推荐)
podman save -o nginx.tar nginx:latest
# 加载镜像
podman load -i nginx.tar
八、数据持久化与存储方案
8.1 Volume 卷管理
8.1.1 创建与管理 Volume
# 创建命名卷
podman volume create mydata
# 查看所有卷
podman volume ls
# 查看卷详情
podman volume inspect mydata
# 删除卷
podman volume rm mydata
# 删除所有未使用的卷
podman volume prune
8.1.2 使用 Volume
# 挂载命名卷
podman run -d -v mydata:/app/data nginx
# 只读挂载
podman run -d -v mydata:/app/data:ro nginx
# 挂载时指定驱动
podman run -d -v mydata:/app/data:z nginx
8.2 Bind Mount(绑定挂载)
# 基础挂载
podman run -d -v /data/app:/app nginx
# 只读挂载
podman run -d -v /data/app:/app:ro nginx
# SELinux 场景(推荐)
podman run -d -v /data/app:/app:Z nginx
# 多个挂载点
podman run -d \
-v /data/app:/app \
-v /data/logs:/var/log \
nginx
8.3 SELinux 标签说明
SELinux 标签选项:
示例:
# 私有标签(推荐)
podman run -v /data:/app:Z nginx
# 共享标签
podman run -v /shared:/app:z nginx
检查 SELinux 标签:
ls -Z /data
# drwxr-xr-x. root root system_u:object_r:container_file_t:s0:c123,c456 /data
8.4 Rootless Volume 权限处理
8.4.1 使用 :U 选项自动修复
# 自动调整 UID/GID 映射
podman run -v /home/user/data:/app:U nginx
8.4.2 手动设置权限
# 查看容器内的 UID
podman exec myapp id
# uid=0(root) gid=0(root)
# 在宿主机上设置对应的权限
chown -R 100000:100000 /home/user/data
8.5 临时文件系统(tmpfs)
# 挂载 tmpfs(内存存储)
podman run -d --tmpfs /tmp:rw,size=100m nginx
# 应用场景:缓存、临时文件
podman run -d \
--tmpfs /tmp:rw,size=256m \
--tmpfs /var/cache:rw,size=512m \
myapp
8.6 存储最佳实践
优先使用命名卷:管理方便,性能更好
SELinux 环境必须使用
:Z或:z敏感数据使用加密卷(如 LUKS)
定期备份 Volume 数据
避免在容器层写入大量数据
九、网络模型与配置
9.1 网络模式
Podman 支持以下网络模式:
9.2 网络操作
9.2.1 查看网络
# 列出所有网络
podman network ls
# 查看网络详情
podman network inspect podman
9.2.2 创建自定义网络
# 创建桥接网络
podman network create mynet
# 指定子网
podman network create \
--subnet 172.20.0.0/16 \
--gateway 172.20.0.1 \
mynet
# 指定网络驱动
podman network create --driver bridge mynet
9.2.3 使用网络
# 运行时指定网络
podman run -d --network mynet nginx
# 连接到多个网络
podman run -d \
--network mynet \
--network frontend \
nginx
# 使用宿主机网络(高性能)
podman run -d --network host nginx
9.2.4 容器互联
# 在同一网络中,容器可通过名称互联
podman network create appnet
podman run -d --name db --network appnet mysql
podman run -d --name web --network appnet nginx
# web 容器可以通过 "db" 访问数据库
podman exec web ping db
9.3 DNS 配置
# 自定义 DNS 服务器
podman run -d --dns 8.8.8.8 nginx
# 添加 hosts 记录
podman run -d --add-host db:192.168.1.100 nginx
# 查看容器 DNS 配置
podman exec nginx cat /etc/resolv.conf
9.4 端口映射高级用法
# 映射端口范围
podman run -d -p 8000-8100:8000-8100 myapp
# 协议指定(TCP/UDP)
podman run -d -p 53:53/udp dnsmasq
# 查看端口映射
podman port nginx
9.5 Rootless 网络特殊处理
Rootless 模式默认使用 slirp4netns:
# 检查网络驱动
podman info | grep -i network
# 切换到 netavark(推荐,Podman 4.0+)
# 编辑配置文件
vim ~/.config/containers/containers.conf
[network]
network_backend = "netavark"
性能优化:
# 使用 pasta(Podman 4.5+,性能更好)
podman run -d --network pasta nginx
十、多容器编排:Podman Compose
10.1 Podman Compose 概述
Podman 4.0+ 原生支持 podman compose 命令(无需安装 Python 版 podman-compose)。
10.2 安装(旧版本)
# Podman 4.0+ 无需安装,直接使用
podman compose version
# 如果是旧版本,安装 Python 版
pip3 install podman-compose
10.3 Compose 文件示例
docker-compose.yml:
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
networks:
- frontend
depends_on:
- app
app:
image: myapp:latest
environment:
- DB_HOST=db
- DB_PORT=5432
volumes:
- ./app:/app
networks:
- frontend
- backend
depends_on:
- db
db:
image: postgres:15-alpine
environment:
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=mydb
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- backend
volumes:
pgdata:
networks:
frontend:
backend:
10.4 Compose 操作命令
# 启动所有服务
podman compose up -d
# 查看服务状态
podman compose ps
# 查看日志
podman compose logs -f
# 停止所有服务
podman compose down
# 重启服务
podman compose restart
# 删除所有资源(包括卷)
podman compose down -v
# 构建镜像
podman compose build
# 扩容服务
podman compose up -d --scale app=3
10.5 Compose 最佳实践
环境变量使用
.env文件
# .env
DB_PASSWORD=secret
APP_VERSION=1.0
# docker-compose.yml
services:
app:
image: myapp:${APP_VERSION}
environment:
- DB_PASSWORD=${DB_PASSWORD}
使用 healthcheck
services:
db:
image: postgres:15
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
interval: 10s
timeout: 5s
retries: 5
资源限制
services:
app:
image: myapp
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
memory: 512M
10.6 Compose vs systemd
开发环境:使用 Compose(快速迭代) 生产环境:使用 systemd(稳定可靠)
十一、Podman + systemd 生产部署
11.1 为什么选择 systemd
优势:
系统级服务管理
崩溃自动重启
日志集成 journald
开机自启
依赖管理
11.2 生成 systemd 服务
11.2.1 生成容器服务
# 运行容器
podman run -d --name webapp \
-p 8080:80 \
-v /data/app:/app:Z \
nginx
# 生成 systemd 服务文件
podman generate systemd --new --files --name webapp
# 输出文件:container-webapp.service
生成的服务文件示例:
[Unit]
Description=Podman container-webapp.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run \
--cidfile=%t/%n.ctr-id \
--cgroups=no-conmon \
--rm \
--sdnotify=conmon \
--replace \
--name webapp \
-p 8080:80 \
-v /data/app:/app:Z \
nginx
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all
[Install]
WantedBy=default.target
11.2.2 安装与启动服务
Rootless 模式:
# 移动服务文件到用户目录
mkdir -p ~/.config/systemd/user/
mv container-webapp.service ~/.config/systemd/user/
# 重新加载 systemd
systemctl --user daemon-reload
# 启动服务
systemctl --user start container-webapp
# 设置开机自启
systemctl --user enable container-webapp
# 允许用户服务在注销后继续运行
loginctl enable-linger $USER
Root 模式:
# 移动服务文件到系统目录
sudo mv container-webapp.service /etc/systemd/system/
# 重新加载 systemd
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start container-webapp
# 设置开机自启
sudo systemctl enable container-webapp
11.3 服务管理
# 查看服务状态
systemctl --user status container-webapp
# 查看日志
journalctl --user -u container-webapp -f
# 重启服务
systemctl --user restart container-webapp
# 停止服务
systemctl --user stop container-webapp
# 禁用开机自启
systemctl --user disable container-webapp
11.4 Pod 的 systemd 服务
# 创建 Pod
podman pod create --name mypod -p 8080:80
# 在 Pod 中运行容器
podman run -d --pod mypod nginx
podman run -d --pod mypod redis
# 生成 Pod 的 systemd 服务
podman generate systemd --new --files --name mypod
# 会生成多个文件:
# - pod-mypod.service(Pod 服务)
# - container-mypod-nginx.service
# - container-mypod-redis.service
11.5 systemd 最佳实践
使用
--new标志:确保每次启动都创建新容器使用
--files:生成独立文件便于版本控制启用 linger:允许用户服务持久运行
配置依赖关系:使用
After=和Requires=监控日志:集成 journald
十二、Pod 概念与多容器协作
12.1 Pod 概述
Pod 是 Kubernetes 的核心概念,Podman 原生支持 Pod,使单机环境也能使用 Pod 模型。
Pod 特点:
共享网络命名空间(localhost 互通)
共享存储卷
共享 IPC 命名空间
生命周期统一管理
12.2 创建与管理 Pod
12.2.1 创建 Pod
# 创建 Pod
podman pod create --name mypod -p 8080:80
# 查看 Pod
podman pod ls
# 查看 Pod 详情
podman pod inspect mypod
12.2.2 在 Pod 中运行容器
# 在 Pod 中启动容器
podman run -d --pod mypod --name web nginx
podman run -d --pod mypod --name cache redis
# Pod 内容器共享网络
# web 容器可以通过 localhost 访问 redis
podman exec web curl localhost:6379
12.2.3 Pod 生命周期管理
# 启动 Pod(启动所有容器)
podman pod start mypod
# 停止 Pod
podman pod stop mypod
# 重启 Pod
podman pod restart mypod
# 删除 Pod(同时删除所有容器)
podman pod rm mypod
# 强制删除
podman pod rm -f mypod
12.3 实战:WordPress + MySQL Pod
# 创建 Pod
podman pod create --name wordpress -p 8080:80
# 运行 MySQL
podman run -d \
--pod wordpress \
--name db \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=wordpress \
-v wpdb:/var/lib/mysql \
mysql:8.0
# 运行 WordPress
podman run -d \
--pod wordpress \
--name wp \
-e WORDPRESS_DB_HOST=127.0.0.1 \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=secret \
-e WORDPRESS_DB_NAME=wordpress \
wordpress:latest
# 访问:http://localhost:8080
12.4 Pod 与 Kubernetes 的对应关系
十三、Kubernetes 集成与迁移
13.1 生成 Kubernetes YAML
13.1.1 从容器生成
# 运行容器
podman run -d --name webapp -p 8080:80 nginx
# 生成 K8s YAML
podman generate kube webapp > webapp.yaml
生成的 YAML 示例:
apiVersion: v1
kind: Pod
metadata:
name: webapp
spec:
containers:
- name: webapp
image: nginx:latest
ports:
- containerPort: 80
hostPort: 8080
protocol: TCP
13.1.2 从 Pod 生成
# 创建 Pod
podman pod create --name mypod -p 8080:80
podman run -d --pod mypod nginx
# 生成 K8s YAML
podman generate kube mypod > mypod.yaml
13.2 从 Kubernetes YAML 创建 Pod
# 从 YAML 创建 Pod
podman play kube mypod.yaml
# 查看创建的 Pod
podman pod ls
# 删除 Pod
podman play kube --down mypod.yaml
13.3 Kubernetes 迁移最佳实践
迁移流程:
本地开发阶段:使用 Podman + Compose
单机验证阶段:使用 Podman Pod + systemd
生成 K8s YAML:
podman generate kube本地测试 YAML:
podman play kube部署到 K8s 集群:
kubectl apply -f
注意事项:
Podman 生成的 YAML 可能需要手动调整
资源限制、探针等需补充
服务发现需改为 K8s Service
13.4 与 Minikube / Kind 结合
# 构建镜像并导入到 Minikube
podman save myapp:latest | minikube image load -
# 或者共享镜像仓库
eval $(minikube docker-env)
podman build -t myapp:latest .
十四、安全加固与最佳实践
14.1 安全特性
14.1.1 Rootless 容器
# 默认使用 Rootless
podman run nginx
# 检查运行模式
podman info | grep rootless
14.1.2 SELinux 强制访问控制
# 启用 SELinux
sudo setenforce 1
# 检查 SELinux 状态
getenforce
# 使用 SELinux 标签运行容器
podman run -v /data:/app:Z nginx
14.1.3 User Namespace 隔离
# 检查 User Namespace
podman exec myapp cat /proc/self/uid_map
# 输出:
# 0 1000 1
# 1 100000 65536
14.1.4 Capabilities 管理
# 移除不必要的 Capabilities
podman run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
# 查看容器 Capabilities
podman exec myapp cat /proc/self/status | grep Cap
14.2 镜像安全扫描
# 使用 Trivy 扫描镜像
trivy image nginx:latest
# 使用 Clair
podman run -d --name clair arminc/clair-local-scan
podman exec clair analyze nginx:latest
14.3 网络安全
# 禁用网络
podman run --network none alpine
# 使用只读文件系统
podman run --read-only nginx
# 禁用特权模式
podman run --security-opt=no-new-privileges nginx
14.4 Secrets 管理
# 创建 Secret
echo "my_secret_password" | podman secret create db_password -
# 在容器中使用 Secret
podman run -d \
--secret db_password \
-e DB_PASSWORD_FILE=/run/secrets/db_password \
myapp
# 容器内读取 Secret
cat /run/secrets/db_password
14.5 安全最佳实践清单
✅ 默认使用 Rootless 模式
✅ 启用 SELinux
✅ 定期扫描镜像漏洞
✅ 使用最小权限原则
✅ 禁用不必要的 Capabilities
✅ 使用只读文件系统
✅ 限制资源使用
✅ 使用 Secrets 管理敏感信息
✅ 定期更新镜像
✅ 审计容器日志
十五、性能调优与监控
15.1 存储性能优化
15.1.1 使用 Overlay2 驱动
# 检查存储驱动
podman info | grep -i storage
# 配置 Overlay2
vim /etc/containers/storage.conf
[storage]
driver = "overlay"
[storage.options.overlay]
mountopt = "nodev,metacopy=on"
15.1.2 Volume 性能优化
# 使用本地卷(性能最佳)
podman volume create --driver local mydata
# 禁用 copy-up(大文件场景)
podman run -v /data:/app:nocopy nginx
15.2 网络性能优化
15.2.1 使用 Host 网络(高性能)
podman run --network host nginx
15.2.2 使用 Pasta(Rootless 高性能网络)
# Podman 4.5+
podman run --network pasta nginx
15.3 资源监控
15.3.1 实时监控
# 查看容器资源使用
podman stats
# 查看特定容器
podman stats webapp
# JSON 格式输出
podman stats --format json
15.3.2 集成 Prometheus
安装 cAdvisor:
podman run -d \
--name cadvisor \
-p 8080:8080 \
-v /:/rootfs:ro \
-v /var/run:/var/run:ro \
-v /sys:/sys:ro \
-v /var/lib/containers/:/var/lib/containers:ro \
gcr.io/cadvisor/cadvisor:latest
配置 Prometheus:
scrape_configs:
- job_name: 'cadvisor'
static_configs:
- targets: ['localhost:8080']
15.4 日志管理
# 查看日志
podman logs webapp
# 限制日志大小
podman run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx
# 集成 syslog
podman run -d \
--log-driver syslog \
--log-opt syslog-address=udp://localhost:514 \
nginx
15.5 性能基准测试
# 容器启动时间
time podman run --rm alpine echo "hello"
# 镜像拉取速度
time podman pull nginx
# 网络吞吐量
podman run --rm networkstatic/iperf3 -c <server_ip>
十六、故障排查手册
16.1 容器无法启动
问题 1:端口被占用
# 错误信息
Error: failed to expose port 8080: listen tcp 0.0.0.0:8080: bind: address already in use
# 解决方案
# 查找占用端口的进程
sudo lsof -i :8080
# 更换端口
podman run -p 8081:80 nginx
问题 2:镜像拉取失败
# 错误信息
Error: failed to pull image: connection timeout
# 解决方案
# 1. 配置镜像加速
vim ~/.config/containers/registries.conf
# 2. 检查网络
ping docker.mirrors.ustc.edu.cn
# 3. 手动拉取
podman pull --tls-verify=false nginx
16.2 Volume 权限问题
问题:Rootless 容器无法写入宿主机目录
# 错误信息
Permission denied: '/app/data'
# 解决方案 1:使用 :U 选项
podman run -v /data:/app:U nginx
# 解决方案 2:手动调整权限
chown -R 100000:100000 /data
# 解决方案 3:使用命名卷
podman volume create mydata
podman run -v mydata:/app nginx
16.3 SELinux 拒绝访问
# 错误信息
SELinux is preventing access
# 解决方案 1:使用 :Z 标签
podman run -v /data:/app:Z nginx
# 解决方案 2:查看 SELinux 日志
sudo ausearch -m avc -ts recent
# 解决方案 3:临时禁用 SELinux(不推荐)
sudo setenforce 0
16.4 网络连接问题
问题:容器无法访问外网
# 检查网络配置
podman network inspect podman
# 检查防火墙
sudo firewall-cmd --list-all
# 检查 DNS
podman exec myapp cat /etc/resolv.conf
# 重启网络
podman network rm podman
podman network create podman
16.5 性能问题
问题:容器运行缓慢
# 检查资源使用
podman stats
# 检查存储驱动
podman info | grep -i graphdriver
# 检查日志大小
du -sh /var/lib/containers/storage/
# 清理未使用资源
podman system prune -a
16.6 常用诊断命令
# 系统信息
podman info
# 事件监控
podman events
# 查看容器进程
podman top webapp
# 检查容器健康状态
podman healthcheck run webapp
# 查看系统日志
journalctl -u podman -f
十七、实战案例
17.1 案例一:部署 LNMP 环境
17.1.1 创建网络
podman network create lnmp
17.1.2 部署 MySQL
podman run -d \
--name mysql \
--network lnmp \
-e MYSQL_ROOT_PASSWORD=rootpass \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser \
-e MYSQL_PASSWORD=wppass \
-v mysql_data:/var/lib/mysql \
mysql:8.0
17.1.3 部署 Nginx + PHP-FPM
创建 Dockerfile:
FROM php:8.2-fpm-alpine
RUN docker-php-ext-install mysqli pdo pdo_mysql
WORKDIR /var/www/html
构建镜像:
podman build -t php-fpm:custom .
运行 PHP-FPM:
podman run -d \
--name php \
--network lnmp \
-v /data/www:/var/www/html \
php-fpm:custom
运行 Nginx:
podman run -d \
--name nginx \
--network lnmp \
-p 8080:80 \
-v /data/www:/var/www/html:ro \
-v /data/nginx.conf:/etc/nginx/nginx.conf:ro \
nginx:alpine
17.2 案例二:Redis 主从复制
# 创建网络
podman network create redis-cluster
# 主节点
podman run -d \
--name redis-master \
--network redis-cluster \
-p 6379:6379 \
redis:7-alpine
# 从节点 1
podman run -d \
--name redis-slave1 \
--network redis-cluster \
-p 6380:6379 \
redis:7-alpine \
redis-server --replicaof redis-master 6379
# 从节点 2
podman run -d \
--name redis-slave2 \
--network redis-cluster \
-p 6381:6379 \
redis:7-alpine \
redis-server --replicaof redis-master 6379
# 验证主从状态
podman exec redis-master redis-cli INFO replication
17.3 案例三:CI/CD 构建环境
使用 Podman 构建镜像(无需 Docker daemon):
#!/bin/bash
# build.sh
APP_NAME="myapp"
VERSION=$(git describe --tags --always)
# 构建镜像
podman build \
--build-arg VERSION=$VERSION \
-t ${APP_NAME}:${VERSION} \
-t ${APP_NAME}:latest \
.
# 推送到私有仓库
podman push ${APP_NAME}:${VERSION} registry.example.com/${APP_NAME}:${VERSION}
podman push ${APP_NAME}:latest registry.example.com/${APP_NAME}:latest
# 清理旧镜像
podman image prune -f
17.4 案例四:监控栈部署
docker-compose.yml:
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prom_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
command:
- '--path.rootfs=/host'
volumes:
- '/:/host:ro,rslave'
volumes:
prom_data:
grafana_data:
启动:
podman compose up -d
十八、生产环境检查清单
18.1 安全检查
[ ] 使用 Rootless 模式
[ ] 启用 SELinux
[ ] 定期扫描镜像漏洞
[ ] 使用最小权限容器
[ ] Secrets 管理到位
[ ] 限制容器资源
[ ] 启用只读文件系统
[ ] 审计日志配置
18.2 性能检查
[ ] 存储驱动为 overlay
[ ] 镜像源配置加速
[ ] 网络模式优化
[ ] 日志轮转配置
[ ] 监控系统部署
[ ] 资源限制合理
18.3 可靠性检查
[ ] systemd 服务配置
[ ] 容器健康检查
[ ] 自动重启策略
[ ] 数据卷备份
[ ] 灾难恢复演练
[ ] 版本控制
18.4 运维检查
[ ] 文档完善
[ ] 监控告警
[ ] 日志集中收集
[ ] 自动化部署
[ ] 更新策略
[ ] 回滚方案
十九、总结与展望
19.1 Podman 的核心优势
安全性:Rootless 容器 + SELinux + User Namespace
轻量级:无守护进程,资源占用低
兼容性:完全兼容 Docker 镜像与命令
生产友好:systemd 集成,稳定可靠
Kubernetes 原生:Pod 支持,平滑迁移
19.2 技术选型建议
适合使用 Podman 的场景:
Linux 服务器生产环境
安全性要求高的企业
Rootless 容器需求
systemd 服务管理
Kubernetes 迁移准备
可以继续使用 Docker 的场景:
Windows / macOS 桌面开发
Docker Desktop 生态依赖
Docker Swarm 集群
团队技术栈已固定
19.3 未来发展趋势
性能持续优化:网络、存储驱动改进
更好的 Windows 支持:原生 Windows 容器
增强的 Kubernetes 集成:CRI-O 深度整合
企业级功能增强:多租户、审计、合规
生态完善:更多工具与平台支持
19.4 学习路径建议
入门阶段:掌握基础命令,替代 Docker
进阶阶段:理解 Rootless、网络、存储
高级阶段:systemd 集成、安全加固
专家阶段:Kubernetes 迁移、生产调优
附录
A. 常用命令速查表
B. 配置文件路径
C. 参考资源
官方文档:https://docs.podman.io/
GitHub 仓库:https://github.com/containers/podman
Red Hat 文档:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/
社区论坛:https://podman.io/community/
本文完
持续更新中...如有问题或建议,欢迎反馈。
版权声明:本文基于 CC BY-NC-SA 4.0 协议发布。