Podman 作为 Docker 的开源替代方案,核心优势之一是原生支持 Pod(容器组) 概念。
Podman Pod 是 Podman 容器引擎中最小的编排单元,本质是一组共享网络、存储、PID 命名空间等资源的容器集合。它借鉴了 Kubernetes(K8s)中 Pod 的设计理念,旨在解决“多个关联容器需要紧密协作” 的场景(如应用容器 + 日志收集容器 + 监控容器),让容器间的通信和资源共享更高效、更符合 “微服务拆分但紧密耦合” 的业务需求。

上图展示了 Podman Pod(容器组)的内部结构与资源共享机制,解释 Podman Pod 如何通过共享命名空间和控制组(cgroups)来实现多容器的协同工作。其中:
Pod 整体:作为最外层的逻辑单元,内部包含 ipc(进程间通信)、net(网络)、pid(进程 ID)命名空间和cgroups(控制组),这些资源由 Pod 内的所有容器共享。
Infra Container(基础设施容器):蓝色的 Infra 容器是 Pod 的“骨架”,基于 quay.io/podman/infra 镜像,主要作用是维护 Pod 的共享命名空间(如网络、IPC 等),自身不提供业务功能。
业务容器(Container A、Container B):粉色的 Container A 和 Container B 是实际的业务容器,基于 runc 运行时(容器运行的底层工具),它们共享 Pod 的命名空间和资源限制,可通过 localhost 直接通信。
common 模块:顶部的三个“common” 模块表示 Pod 内所有容器可共享的公共资源或配置,比如共享存储卷、环境变量等,体现了 Pod 内容器的资源协同能力。
简言之,上图清晰地呈现了 Podman 中 “一个 Pod 包含多个容器,且这些容器共享核心系统资源(命名空间、cgroups)” 的设计理念,Infra 容器负责维持底层环境,业务容器专注于业务逻辑,共同构成一个紧密协作的应用单元。
容器的设计原则是“单一职责”(一个容器只运行一个核心进程),但实际业务中,很多组件需要依赖其他辅助组件才能正常工作:
例1:Web 应用容器(运行 Java 服务)需要搭配一个 Sidecar 容器(收集日志、监控指标);
例2:数据库容器需要一个初始化容器(执行建表 SQL),初始化完成后再启动主容器。
如果这些容器单独运行,会面临以下问题:
网络隔离:容器间需要通过端口映射或外部网络通信,延迟高且配置复杂;
资源隔离:无法共享存储(如配置文件)或进程命名空间(无法通过 PID 访问彼此进程);
生命周期管理:无法保证辅助容器与主容器 “同启动、同停止、同迁移”。
Pod 正是为解决这些问题而生 —— 将关联容器 “打包” 成一个逻辑单元,共享核心资源,统一管理生命周期。
Pod 与独立容器的区别主要如下:
特性 | 独立容器 | Pod(多容器集合) |
网络命名空间 | 每个容器独立 | 所有容器共享一个网络命名空间(同一 IP) |
存储共享 | 需通过外部卷挂载共享 | 可共享 Pod 内的“临时存储” 或 “共享卷” |
PID 命名空间 | 每个容器独立 PID 空间 | 可选共享 PID 空间,容器间可通过 PID 通信 |
生命周期管理 | 单独启动 / 停止 / 删除 | 统一启动/停止/删除,Pod 销毁时所有容器销毁 |
资源限制 | 单独设置 CPU / 内存限制 | 可设置 Pod 整体资源限制,也支持容器单独限制 |
每个 Pod 包含以下关键组件,确保容器间协同工作:
Pause 容器(基础设施容器,即 Infra Container 容器):Pod 启动时会先创建一个特殊的 pause 容器(由 Podman 自动管理),其作用是:
占用 Pod 的网络命名空间(作为 Pod 的“网络锚点”)
维持 Pod 的生命周期(Pod 的状态由 pause 容器的状态决定)
协调其他容器的启动和停止顺序
业务容器:用户实际运行应用的容器(如 Web 容器、数据库容器),所有业务容器共享 pause 容器的网络、PID 等命名空间。
共享资源:
网络:Pod 有一个统一的 IP 地址,所有容器通过 localhost 即可通信(无需端口映射)
存储:可定义 Pod 级别的 emptyDir(临时存储,Pod 销毁时数据丢失)或 persistentVolumeClaim(持久化存储),所有容器均可挂载
环境变量:Pod 级别的环境变量会被所有容器继承,也可在容器内单独定义个性化环境变量
Pod 适用于“容器间强依赖、需要紧密协作”的场景,常见案例包括:
Sidecar 模式:辅助主容器完成特定功能(日志收集、监控、配置同步)。例如:Nginx 主容器 + Fluentd 日志收集容器(Fluentd 共享 Nginx 的日志目录,实时收集日志并上传到 Elasticsearch)。
Init 容器模式:在主容器启动前执行初始化操作(如配置文件下载、数据库迁移、权限设置)。例如:Spring Boot 主容器 + Init 容器(Init 容器先从配置中心下载 application.yml 到共享卷,主容器再从共享卷读取配置启动)。
Ad-hoc 调试模式:临时启动一个调试容器,与主容器共享网络 / 存储,排查问题。例如:主容器运行 Java 应用,启动一个包含 jps/jstack 工具的调试容器,共享主容器的 PID 命名空间,直接查看主容器的 Java 进程状态。
多服务紧密耦合模式:多个服务必须在同一主机上运行,且需要高频通信(如前端静态资源容器 + 后端 API 容器,通过 localhost 通信,减少网络延迟)。
用 Podman 创建一个包含 Nginx 和 Redis 容器的 Pod,并让这两个服务都能被外部访问。下面提供完整的创建步骤和配置说明:
首先创建一个 Pod,同时映射 Nginx(80 端口)和 Redis(6379 端口)的端口到主机:
# 创建名为 web-redis-pod 的 Pod,映射主机 8080->80 (Nginx) 和 6379->6379 (Redis) podman pod create \ --name web-redis-pod \ --publish 8080:80 \ --publish 6379:6379 # 示例 C:\Users\Administrator> podman pod create --name web-redis-pod --publish 8080:80 --publish 6379:6379 0c9858859aa8e97fefa2b4839cc1c0f4c589ed40aca1840cbfd66b8f49eae31e
创建一个 redis 容器,不需要使用 -p 绑定端口,端口绑定在 Pod 上面实现,如下:
# 添加 Redis 容器到 Pod 中 podman run \ --pod web-redis-pod \ --name redis \ --restart always \ -d \ redis:alpine # 示例 C:\Users\Administrator> podman run --pod web-redis-pod --name redis --restart always -d redis:alpine Resolving "redis" using unqualified-search registries (/home/user/.config/containers/registries.conf) Trying to pull docker.io/library/redis:alpine... Getting image source signatures Copying blob sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 Copying blob sha256:362eff98b603cadcb31ab0031a47f64fbcf99b9a52045dd55e050c271cdaa5d3 Copying blob sha256:6a229eaa0f8a70b83eb3c40f8adc81d4ad54a3e1835a982d2473b269ae7f7dfc Copying blob sha256:c84a6e003d260521e9b2ecb4cdfe80b7fd68dcb5f0bff54b249b6008e157982c Copying blob sha256:793133e9ba6b86a5ffc07e338aaf08216c0479293d1e75846f2cf6b894bb9a41 Copying blob sha256:2d35ebdb57d9971fea0cac1582aa78935adf8058b2cc32db163c98822e5dfa1b Copying blob sha256:cffa735aaa172bb794d6ae16ec9f9f31fae4e8d1616522d985a732e4dee06622 Copying config sha256:778c3ea605c2c786ad6f7b9efe50c065903b1b4c7a4f5b2c6d76507b01402470 Writing manifest to image destination 16f0e87455366fcc3421987554fb3726cdb05aa3bd84b3d22e22230c28215371
创建一个 nginx 容器,不需要使用 -p 绑定端口,端口绑定在 Pod 上面实现,如下:
# 添加 Nginx 容器到 Pod 中 podman run \ --pod web-redis-pod \ --name nginx \ --restart always \ -d \ nginx:alpine # 示例 C:\Users\Administrator> podman run --pod web-redis-pod --name nginx --restart always -d nginx:alpine Resolving "nginx" using unqualified-search registries (/home/user/.config/containers/registries.conf) Trying to pull docker.io/library/nginx:alpine... Getting image source signatures Copying blob sha256:d9a55dab5954588333096b28b351999099bea5eb3c68c10e99f175b12c97198d Copying blob sha256:8f6a6833e95d43ac524f1f9c5e7c1316c1f3b8e7ae5ba3db4e54b0c5b910e80a Copying blob sha256:2d35ebdb57d9971fea0cac1582aa78935adf8058b2cc32db163c98822e5dfa1b Copying blob sha256:3eaba6cd10a374d9ed629c26d76a5258e20ddfa09fcef511c98aa620dcf3fae4 Copying blob sha256:194fa24e147df0010e146240d3b4bd25d04180c523dc717e4645b269991483e3 Copying blob sha256:df413d6ebdc834bccf63178455d406c4d25e2c2d38d2c1ab79ee5494b18e5624 Copying blob sha256:ff8a36d5502a57c3fc8eeff48e578ab433a03b1dd528992ba0d966ddf853309a Copying blob sha256:bdabb0d442710d667f4fd871b5fd215cc2a430a95b192bc508bf945b8e60999b Copying config sha256:d4918ca78576a537caa7b0c043051c8efc1796de33fee8724ee0fff4a1cabed9 Writing manifest to image destination 8faad774ad79c74f5be1b06bff791506444ef4bd9ba99c33a5f708754f208cc2
执行完上述命令后,打开 Podman Desktop,查看 web-redis-pod 的状态,如下图:

使用浏览器访问 http://localhost:8080 地址,效果如下图:

到这里,Pod 介绍就完成了,更多知识继续阅读后续内容……