Podman 的 Pod 让本地容器共享指定命名空间,并为 Kubernetes 清单工作流提供一种组织方式。
什么是 Pod?(零基础版)#
从一个场景理解
想象你部署一个网站,需要三个东西:Web 服务器 + 后台 API + 数据库。
Docker 方式(各自独立):
容器 A (nginx) 独立网络地址(示意)
容器 B (api) 独立网络地址(示意)
容器 C (postgres) 独立网络地址(示意)独立网络命名空间常通过桥接网络和容器 DNS 通信;实际开销取决于网络实现和工作负载,不能据此认定单机数据库必须与 API 放进同一 Pod。
Pod 方式(住同一个"房间"):
┌──────── Pod 共享网络 ────────┐
│ localhost │
│ 容器 A (nginx) │ ← 通过 localhost:3000 访问 API
│ 容器 B (api) │ ← 通过 localhost:5432 访问 DB
│ 容器 C (postgres) │
└──────────────────────────────┘Pod 的核心特性:同一个 Pod 内的容器共享网络——它们可以用 localhost 互相通信,不需要暴露端口到外部。
Pod 和 Kubernetes 的关系
Kubernetes 中,Pod 是最小的调度单位——你永远无法直接运行一个容器,你必须把它放在一个 Pod 里。Podman 把 Pod 概念带到了本地开发环境,让你在单机上也能享受相同的组织方式。
Pod 基本操作#
创建一个空 Pod
# 创建 Pod 并暴露端口
podman pod create --name mypod -p 127.0.0.1:8080:80
# └───────┘ └────────┘
# Pod 名称 把 Pod 的 80 端口映射到宿主机 8080
# 查看所有 Pod
podman pod ps
# 输出类似:
# POD ID NAME STATUS CREATED INFRA ID # OF CONTAINERS
# abc123... mypod Running 2s ago def456... 1
# 注意:刚创建的 Pod 已经有 1 个容器——这就是 infra 容器Infra 容器是什么?
默认创建 Pod 时,Podman 创建一个 infra 容器。它的作用类似 Pod 的"房东"——持有共享的网络、IPC 等名字空间。其他容器加入 Pod 时,"住进"这个房东的房子里。
# 查看 infra 容器(podman pod ps 中 INFRA ID 对应的容器)
podman ps --pod
# infra 容器名字类似 abc123-infra,状态为 Running
# 当前默认由 Podman 创建本地轻量 infra 镜像;可用 --infra-image 覆盖向 Pod 中添加容器
# 创建 Pod
podman pod create --name webapp -p 127.0.0.1:8080:80
# 向 Pod 中添加 nginx 容器
podman run -d --pod webapp --name web docker.io/library/nginx:alpine
# └───────┘ └──────┘
# 加入 webapp Pod 容器名
# 添加 API 容器(同一 Pod 内可用 localhost 访问 nginx)
podman run -d --pod webapp --name api myapi:latest
# 添加数据库容器
podman run -d --pod webapp --name db \
--env-file /path/to/private/postgres.env \
-v pgdata:/var/lib/postgresql/data \
postgres:16-alpine关键:现在 api 容器可以通过 localhost:80 访问 web,web 可以通过 localhost:3000 访问 api,都在共享网络命名空间;服务需监听相应端口,端口不能冲突。
管理 Pod
# 查看 Pod 内所有容器
podman pod ps --ctr-names
# 查看 Pod 详情
podman pod inspect webapp
# 停止整个 Pod(停掉里面所有容器)
podman pod stop webapp
# 启动整个 Pod
podman pod start webapp
# 重启整个 Pod
podman pod restart webapp
# 暂停/恢复 Pod
podman pod pause webapp
podman pod unpause webapp
# 删除 Pod(和里面所有容器)
podman pod rm -f webappPodman ↔ Kubernetes 双向转换#
这是 Podman 独特的杀手能力。
从 Pod 生成 Kubernetes YAML
# 生成 K8s YAML
podman kube generate webapp > webapp.yaml
# 产出后检查镜像、环境变量、卷、hostPath、标签和网络字段
# 迁移集群前调整清单;经授权部署时才运行 kubectl apply -f webapp.yaml生成的 YAML 示例(简化):
apiVersion: v1
kind: Pod
metadata:
name: webapp
spec:
containers:
- name: web
image: docker.io/library/nginx:alpine
ports:
- containerPort: 80
- name: db
image: docker.io/library/postgres:16-alpine
env:
- name: POSTGRES_PASSWORD
value: NON_SECRET_EXAMPLE_REPLACE_BEFORE_USE从 Kubernetes YAML 运行本地容器
# 手头有个 K8s YAML,想本地跑起来看看
podman kube play webapp.yaml
# 本地解释支持的 Kubernetes 对象/字段,不是完整 Kubernetes 控制平面
# Podman 会解析 YAML,在本地创建对应的 Pod 和容器生成 systemd 服务文件
# 为当前运行的 Pod 生成 systemd unit file
podman generate systemd --files --name webapp --pod-prefix myapp
# --files 输出到当前目录;--name 使用资源名;webapp 是位置参数;--pod-prefix 控制前缀
# 但官方现在更推荐用 Quadlet(见下一篇)实战示例:WordPress + MySQL in a Pod#
# 1. 创建 Pod
podman pod create --name wordpress -p 127.0.0.1:8080:80
# 2. 启动 MariaDB(WordPress 的数据库)
podman run -d \
--pod wordpress \
--name wp-db \
--env-file /path/to/private/mariadb.env \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser \
-v wp-db:/var/lib/mysql \
docker.io/library/mariadb:11
# 3. 启动 WordPress
podman run -d \
--pod wordpress \
--name wp-app \
-e WORDPRESS_DB_HOST=127.0.0.1 \
-e WORDPRESS_DB_USER=wpuser \
--env-file /path/to/private/wordpress.env \
-e WORDPRESS_DB_NAME=wordpress \
docker.io/library/wordpress:latest
# 4. 打开 http://localhost:8080,WordPress 安装界面就绪
# 5. 生成 K8s YAML 存档
podman kube generate wordpress > wordpress-k8s.yaml对比 Docker Compose:Compose 的 depends_on 控制依赖,不决定寻址方式;同一网络中通常通过服务名解析。Pod 可用 localhost,但仍经过网络栈,并非零开销。MariaDB 初始化与 WordPress 启动仍需就绪重试。
Pod 的存储共享#
同一 Pod 内的容器可以共享卷,但需要显式挂载同一路径:
podman run -d --pod mypod --name container-a -v shared:/data app-a:latest
podman run -d --pod mypod --name container-b -v shared:/data app-b:latest
# container-a 和 container-b 都能读写 shared 卷里的文件示例 env 文件存放在仓库外且权限受限,分别提供匹配的数据库口令等必需值;所有展示字符串为无效演示值。导出的 kube 清单可能包含明文环境变量,不能直接当作安全存档上传。podman play kube 是 podman kube play 的别名,generate kube 为旧入口;命令更名不等于功能变为完整 Kubernetes。Pod 共享哪些 namespace 可配置;共享网络不自动共享文件系统和卷。podman generate systemd 已弃用,保留只为识别旧工作流,新服务采用 Quadlet。
参考与延伸
- Podman 官方 run 手册 ↗
- Podman 官方总览与 rootless ↗
- Pod 创建与 infra ↗
- kube play 范围 ↗
- kube generate ↗
- 旧 systemd 生成命令 ↗
根据技术笔记重新整理,示例使用通用名称。