本节摘要:Pod 是 Kubernetes 的最小调度单元——一组共享网络与 IPC 命名空间的容器。Podman 把这个概念完整搬到单机:pod create 建立 Pod 与 infra 容器(一个暂停态的占位进程),随后加入的容器共享它的网络栈。本节实操验证共享效果,解释 infra 容器的存在理由,并对比 Docker Compose 的"服务组"模型与 Pod 模型的语义差别。
先回答一个合理的疑问:我又不跑 Kubernetes,为什么要关心 Pod?答案藏在"共享"二字里。开发中经常遇到这样的需求:一个应用容器和一个日志收集容器必须看到同一块网络——日志容器要访问应用容器的回环地址;或者一个应用与一个代理要共享同一 IPC 通道做零拷贝通信。Docker 的解法是创建一个共享的 bridge 网络让容器通过容器名互访,可行,但回环地址不通、IPC 各自独立。
Pod 的解法更彻底:组内容器直接共享同一个网络命名空间——同一个 IP、同一组端口空间、回环互通。这正是 Kubernetes 里"为什么一个 Pod 内的多个容器能像同一台机器上的进程一样协作"的原因。Podman 原生支持这套语义,代价是你要多理解一个角色:infra 容器。
实操最直观。创建一个带 infra 容器的 Pod,加入两个业务容器,验证共享:
# 创建 Pod,发布端口,infra 容器自动创建 podman pod create --name devpod -p 8080:80 # 4c1d... # 查看当前 Pod 里的容器——多了一个没让你创建的 podman ps -a --pod # CONTAINER ID IMAGE COMMAND STATUS POD NAMES # 2b8e... registry.access.../... Created devpod 2b8e-infra # 解读:第一个"容器"就是 infra 容器,镜像是发行版提供的 pause 镜像 # 加入两个业务容器:一个简易 http 服务,一个客户端 podman run -d --pod devpod --name web docker.io/library/nginx:alpine podman run --pod devpod --name probe alpine:3.19 \ sh -c 'wget -qO- http://127.0.0.1:80 | head -1' # <!DOCTYPE html> # 关键点:probe 容器通过 127.0.0.1 直接访问到了 web 容器的服务。 # 没有网络别名解析、没有跨容器路由——它们本来就在同一个网络栈里 # 验证共享:两个容器看到的网络设备完全一致 podman exec web ip addr show eth0 | grep 'inet ' podman exec probe ip addr show eth0 | grep 'inet ' # 两边输出同一个 IP。因为 eth0 属于共享的网络命名空间
infra 容器的镜像通常叫 pause,它只做一件事:sleep,占据着 Pod 的共享命名空间。存在理由牵涉生命周期问题:网络命名空间必须有进程持有才不会销毁。如果共享的网络栈属于第一个业务容器,那这个容器一退出,整组容器的网络就塌了——同 Pod 的其他容器瞬间失联。
pause 把"命名空间的持有者"与"业务容器"解耦:它不做事,所以几乎不会崩;它活着,命名空间就活着;业务容器可以随意重启进出,互不牵连。Kubernetes 在集群里用的正是同一个机制(每个 Pod 第一个启动的就是 pause 容器)。验证一下它确实在偷懒:
# infra 容器的进程开销 podman pod stats devpod --no-stream # POD CPU% MEM # devpod 0.01% 300KiB 级别 # 几乎为零——这就是"占位"的成本 # 试着删掉 infra 容器会怎样? # podman 会拒绝或导致 Pod 网络失效,取决于版本; # 正确的解体顺序永远是:先删业务容器,再 pod rm
一个容易踩的坑顺带记录:podman run --pod 时再指定 -p 端口映射会被拒绝——端口属于 Pod 整体,必须在 pod create 时声明。这个设计同样来自 Kubernetes:端口是 Pod 的属性,不是容器的。
用一张结构图把两种组织方式的形态差别画出来,比文字更直观:

既然讲对比驱动,就把三种"把容器组织起来"的方式并排放:
| 维度 | Docker bridge 网络 | Docker Compose | Podman Pod |
|---|---|---|---|
| 网络共享 | 容器名互访,回环不通 | 同左(service 名解析) | 同一网络栈,回环互通 |
| IPC 共享 | 默认各自独立 | 默认各自独立 | 组内共享 IPC 命名空间 |
| 生命周期 | 各容器独立 | 随 project 启停 | infra 持有,业务容器可单独进出 |
| 端口声明 | 每容器各自 -p | 每服务各自映射 | pod create 时统一声明 |
| 与 K8s 的语义距离 | 远 | 中(service 集合近似) | 近(同一 Pod 概念) |
Compose 的"一组服务"与 Pod 的"一组容器"看起来都是"把相关的东西放一起",但语义重心不同:Compose 描述的是服务拓扑(谁依赖谁、什么顺序启动),每个容器仍是独立的网络公民;Pod 描述的是进程协作(谁和谁共享一台"机器"),组内容器像同一主机上的进程。前者适合"应用 + 数据库 + 缓存"这种服务组合,后者适合"应用 + 日志收集"这种进程级共生。选错模型不会立刻报错,但会让通信方式变得别扭——第 8 章 play kube 会看到这个差别的终局形态。