Podman 完全指南 / 04 - Pod 管理
第 04 章 — Pod 管理
4.1 什么是 Pod?
Pod 是 Kubernetes 的核心概念,源自豌豆荚(Pod)的隐喻——一组紧密关联的容器共享同一个网络命名空间和存储卷。
Podman 是唯一原生支持 Pod 概念的非 Kubernetes 容器引擎。
┌──────────────── Pod ────────────────┐
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ 容器 A │ │ 容器 B │ │
│ │ (应用) │ │ (sidecar) │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ ┌────┴──────────────┴────┐ │
│ │ 共享网络命名空间 │ │
│ │ localhost 互访 │ │
│ └────────────┬───────────┘ │
│ │ │
│ ┌────────────┴───────────┐ │
│ │ 共享存储卷 (可选) │ │
│ └────────────────────────┘ │
│ │
│ infra 容器 (pause) 提供命名空间 │
└──────────────────────────────────────┘
Pod 与 Docker Compose 的对比
| 维度 | Podman Pod | Docker Compose |
|---|---|---|
| 共享网络 | 共享 localhost | 独立 IP,通过服务名通信 |
| K8s 兼容 | ✅ 可导出/导入 K8s YAML | ❌ |
| systemd 集成 | ✅ Quadlet | 需额外配置 |
| 存储卷 | Pod 级别定义 | 服务级别定义 |
| 启动顺序 | Pod 级别 | depends_on 控制 |
| 适用场景 | K8s 开发/微服务 | 多服务编排 |
4.2 Pod 基础操作
4.2.1 创建 Pod
# 创建空 Pod(含 infra 容器)
podman pod create --name myapp
# 创建 Pod 并映射端口
podman pod create --name webapp -p 8080:80 -p 8443:443
# 指定网络
podman pod create --name myapp --network mynet
# 添加标签
podman pod create --name myapp \
--label env=production \
--label app=web
# 添加 hosts 映射
podman pod create --name myapp \
--add-host db:10.0.0.5 \
--add-host cache:10.0.0.6
# 自定义 DNS
podman pod create --name myapp \
--dns 8.8.8.8 \
--dns-search example.com
# 查看 Pod 列表
podman pod ls
# 查看 Pod 详情
podman pod inspect myapp
4.2.2 在 Pod 中运行容器
# 在 Pod 中运行容器(-d 后台,--pod 指定 Pod)
podman run -d --pod myapp --name web nginx:1.27-alpine
# 同一个 Pod 中运行多个容器
podman run -d --pod myapp --name app myapp:latest
podman run -d --pod myapp --name sidecar fluentd:latest
# 由于共享 localhost,容器间可直接互访
# 从 app 容器访问 web 容器
podman exec app curl http://localhost:80
4.2.3 Pod 生命周期管理
# 启动 Pod(启动所有容器)
podman pod start myapp
# 停止 Pod(停止所有容器)
podman pod stop myapp
# 重启 Pod
podman pod restart myapp
# 暂停/恢复 Pod
podman pod pause myapp
podman pod unpause myapp
# 删除 Pod(需先停止或 -f 强制)
podman pod rm myapp
podman pod rm -f myapp
# 清理所有已停止的 Pod
podman pod prune
# 查看 Pod 内容器
podman pod ps
4.3 经典 Pod 模式
4.3.1 Sidecar 模式:Web + 日志收集
# 创建 Pod
podman pod create --name webapp -p 8080:80
# 主应用容器
podman run -d --pod webapp \
--name web \
-v web-content:/usr/share/nginx/html:Z \
nginx:1.27-alpine
# 日志收集 Sidecar
podman run -d --pod webapp \
--name logger \
-v web-content:/data:ro,Z \
busybox \
sh -c 'tail -f /data/access.log'
4.3.2 Ambassador 模式:应用 + 数据库代理
# 创建 Pod
podman pod create --name backend -p 8080:8080
# 应用容器
podman run -d --pod backend \
--name app \
-e DATABASE_URL=postgres://user:pass@localhost:5432/mydb \
myapp:latest
# PostgreSQL 作为同 Pod 的数据库
podman run -d --pod backend \
--name db \
-e POSTGRES_USER=user \
-e POSTGRES_PASSWORD=pass \
-e POSTGRES_DB=mydb \
-v pgdata:/var/lib/postgresql/data:Z \
postgres:16-alpine
# 应用通过 localhost:5432 连接数据库
4.3.3 Init Container 模式:初始化 + 运行
# 创建 Pod
podman pod create --name data-app -p 8080:80
# 初始化容器(拉取配置)
podman run --rm --pod data-app \
--name init \
-v app-config:/config:Z \
busybox \
sh -c '
wget -O /config/app.conf https://config.example.com/prod.conf
echo "Config downloaded"
'
# 主应用(使用下载的配置)
podman run -d --pod data-app \
--name app \
-v app-config:/app/config:ro,Z \
myapp:latest --config /app/config/app.conf
4.4 Kubernetes YAML 兼容
Podman 最独特的功能之一是与 Kubernetes YAML 的双向互操作。
4.4.1 从 Pod 生成 Kubernetes YAML
# 创建一个完整的 Pod
podman pod create --name demo-app -p 8080:80
podman run -d --pod demo-app --name web nginx:1.27-alpine
podman run -d --pod demo-app \
--name app \
-e APP_ENV=production \
-v app-data:/data:Z \
myapp:v1.0
# 生成 Kubernetes YAML
podman generate kube demo-app > demo-app.yaml
生成的 YAML 示例:
# demo-app.yaml(podman generate kube 生成)
# Generation of Kubernetes YAML is still under development!
#
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-5.x.x
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2026-05-10T08:00:00Z"
labels:
app: demo-app
name: demo-app
spec:
containers:
- args:
- nginx
- -g
- daemon off;
image: docker.io/library/nginx:1.27-alpine
name: web
ports:
- containerPort: 80
hostPort: 8080
- env:
- name: APP_ENV
value: production
image: docker.io/library/myapp:v1.0
name: app
volumeMounts:
- mountPath: /data
name: app-data
volumes:
- name: app-data
persistentVolumeClaim:
claimName: app-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: "2026-05-10T08:00:00Z"
name: app-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
💡 提示
podman generate kube不仅能导出单个 Pod,还支持导出多个 Pod 和 Service:
# 导出多个对象
podman generate kube pod1 pod2 > multi-pod.yaml
# 导出包含 Deployment(而非 Pod)
podman kube generate --type deployment demo-app > deployment.yaml
# 导出包含 Service
podman kube generate --type service demo-app > service.yaml
4.4.2 从 Kubernetes YAML 创建 Pod
# 使用 Kubernetes YAML 在 Podman 中运行
podman kube play demo-app.yaml
# 使用持久卷声明
podman kube play --configmap config.yaml demo-app.yaml
# 后台运行
podman kube play demo-app.yaml
# 停止并清理
podman kube down demo-app.yaml
4.4.3 开发工作流
Podman 本地开发 Kubernetes 生产部署
┌────────────────────┐ ┌────────────────────┐
│ │ │ │
│ podman pod create │ │ kubectl apply -f │
│ ↓ │ │ ↑ │
│ podman run ... │ ──────▶ │ demo-app.yaml │
│ ↓ │ generate │ │
│ podman generate │ │ kind: Deployment │
│ kube │ │ kind: Service │
│ ↓ │ │ │
│ demo-app.yaml │ │ │
│ │ │ │
└────────────────────┘ └────────────────────┘
4.5 生产场景
场景一:微服务本地开发环境
#!/bin/bash
# dev-env.sh — 使用 Pod 一键启动微服务开发环境
POD_NAME="microservices"
# 清理旧环境
podman pod rm -f $POD_NAME 2>/dev/null
# 创建 Pod
podman pod create --name $POD_NAME \
-p 3000:3000 \ # API Gateway
-p 5432:5432 \ # PostgreSQL
-p 6379:6379 # Redis
# 启动 PostgreSQL
podman run -d --pod $POD_NAME --name postgres \
-e POSTGRES_USER=dev \
-e POSTGRES_PASSWORD=devpass \
-e POSTGRES_DB=appdb \
-v pgdata:/var/lib/postgresql/data:Z \
postgres:16-alpine
# 启动 Redis
podman run -d --pod $POD_NAME --name redis \
redis:7-alpine
# 启动应用(等待数据库就绪)
podman run -d --pod $POD_NAME --name api \
-e DATABASE_URL=postgres://dev:devpass@localhost:5432/appdb \
-e REDIS_URL=redis://localhost:6379 \
myapi:latest
echo "开发环境已启动!"
echo "API: http://localhost:3000"
echo "PostgreSQL: localhost:5432"
echo "Redis: localhost:6379"
场景二:导出到 Kubernetes 集群
# 1. 在 Podman 中验证应用
podman kube play deployment.yaml
# 2. 功能测试通过后,直接部署到 K8s
kubectl --context production apply -f deployment.yaml
# 3. 或者进一步转换为 Helm Chart
mkdir -p myapp/templates
mv deployment.yaml myapp/templates/
4.6 本章小结
| 知识点 | 要点 |
|---|---|
| Pod 概念 | 共享网络命名空间的容器组 |
| 创建 | podman pod create --name <name> -p <ports> |
| 管理 | podman pod start/stop/rm/ls/inspect |
| K8s 导出 | podman generate kube <pod> |
| K8s 导入 | podman kube play <file.yaml> |
| 经典模式 | Sidecar、Ambassador、Init Container |
| 核心优势 | 本地开发体验与 K8s 生产环境一致 |
下一步
- 👉 第 05 章:Rootless 模式 — 深入理解非 root 容器运行