Podman 教程

Podman Pod 介绍

Podman 作为 Docker 的开源替代方案,核心优势之一是原生支持 Pod(容器组) 概念。

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

Podman 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 容器负责维持底层环境,业务容器专注于业务逻辑,共同构成一个紧密协作的应用单元。

  

为什么需要 Pod?

容器的设计原则是“单一职责”(一个容器只运行一个核心进程),但实际业务中,很多组件需要依赖其他辅助组件才能正常工作:

  • 例1:Web 应用容器(运行 Java 服务)需要搭配一个 Sidecar 容器(收集日志、监控指标);

  • 例2:数据库容器需要一个初始化容器(执行建表 SQL),初始化完成后再启动主容器。

如果这些容器单独运行,会面临以下问题:

  • 网络隔离:容器间需要通过端口映射或外部网络通信,延迟高且配置复杂;

  • 资源隔离:无法共享存储(如配置文件)或进程命名空间(无法通过 PID 访问彼此进程);

  • 生命周期管理:无法保证辅助容器与主容器 “同启动、同停止、同迁移”。

Pod 正是为解决这些问题而生 —— 将关联容器 “打包” 成一个逻辑单元,共享核心资源,统一管理生命周期。

  

Pod 与独立容器的区别

Pod 与独立容器的区别主要如下:

特性

独立容器

Pod(多容器集合)

网络命名空间

每个容器独立

所有容器共享一个网络命名空间(同一 IP)

存储共享

需通过外部卷挂载共享

可共享 Pod 内的“临时存储” 或 “共享卷”

PID 命名空间

每个容器独立 PID 空间

可选共享 PID 空间,容器间可通过 PID 通信

生命周期管理

单独启动 / 停止 / 删除

统一启动/停止/删除,Pod 销毁时所有容器销毁

资源限制

单独设置 CPU / 内存限制

可设置 Pod 整体资源限制,也支持容器单独限制

  

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 典型使用场景

Pod 适用于“容器间强依赖、需要紧密协作”的场景,常见案例包括:

  • Sidecar 模式:辅助主容器完成特定功能(日志收集、监控、配置同步)。例如:Nginx 主容器 + Fluentd 日志收集容器(Fluentd 共享 Nginx 的日志目录,实时收集日志并上传到 Elasticsearch)。

  • Init 容器模式:在主容器启动前执行初始化操作(如配置文件下载、数据库迁移、权限设置)。例如:Spring Boot 主容器 + Init 容器(Init 容器先从配置中心下载 application.yml 到共享卷,主容器再从共享卷读取配置启动)。

  • Ad-hoc 调试模式:临时启动一个调试容器,与主容器共享网络 / 存储,排查问题。例如:主容器运行 Java 应用,启动一个包含 jps/jstack 工具的调试容器,共享主容器的 PID 命名空间,直接查看主容器的 Java 进程状态。

  • 多服务紧密耦合模式:多个服务必须在同一主机上运行,且需要高频通信(如前端静态资源容器 + 后端 API 容器,通过 localhost 通信,减少网络延迟)。

  

Pod 简单示例

用 Podman 创建一个包含 Nginx 和 Redis 容器的 Pod,并让这两个服务都能被外部访问。下面提供完整的创建步骤和配置说明:

创建 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

向 Pod 中添加 Redis 容器

创建一个 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

向 Pod 中添加 Nginx 容器

创建一个 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 的状态,如下图:

Podman Pod 介绍

测试外部访问

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

Podman Pod 介绍

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

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号