01 - Podman 简介
第 01 章 — Podman 简介
1.1 容器技术简史
容器技术并非一蹴而就,而是经过数十年的演进:
1979 Unix V7 — chroot(文件系统隔离雏形)
2000 FreeBSD Jails(进程级隔离)
2006 Google Process Containers → cgroups
2008 Linux Containers (LXC)
2013 Docker 发布 — 容器技术民主化
2014 Kubernetes 开源 — 容器编排标准化
2015 OCI 成立 — 容器标准治理
2018 Podman 发布 — 无守护进程容器引擎
Docker 的贡献与局限
Docker 极大地推动了容器化普及,但其 客户端-守护进程(Client-Daemon)架构存在固有问题:
| 问题 | 说明 |
|---|---|
| 单点故障 | dockerd 崩溃,所有容器管理功能不可用 |
| 权限集中 | 守护进程以 root 运行,攻击面大 |
| 资源开销 | 常驻守护进程消耗系统资源 |
| systemd 冲突 | 容器内 PID 1 与 systemd 管理机制冲突 |
┌─────────────────────────────────────────┐
│ Docker 架构 │
│ │
│ docker CLI ←→ dockerd (root) │
│ │ │
│ containerd │
│ │ │
│ runc (OCI runtime) │
│ │ │
│ ┌──────┴──────┐ │
│ │ 容器 A 容器 B │ │
│ └─────────────┘ │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ Podman 架构 │
│ │
│ podman CLI → conmon → runc/crun │
│ │ │
│ ┌──────┴──────┐ │
│ │ 容器 A 容器 B │ │
│ └─────────────┘ │
│ │
│ (无守护进程,每个容器独立 fork/exec) │
└─────────────────────────────────────────┘
1.2 Podman 是什么?
Podman(Pod Manager)是由 Red Hat 主导开发的容器管理工具,它具备以下核心特性:
核心设计原则
- 无守护进程(Daemonless):直接 fork/exec 创建容器,无需常驻后台进程
- Rootless 优先:默认以非 root 用户运行,大幅降低安全风险
- OCI 兼容:完全兼容 OCI 镜像规范和运行时规范
- Docker CLI 兼容:命令行接口几乎与 Docker 完全一致
- 原生 Pod 支持:内置 Pod 概念,天然兼容 Kubernetes
技术栈对比
| 组件 | Docker | Podman |
|---|---|---|
| CLI 工具 | docker | podman |
| 守护进程 | dockerd | 无 |
| 容器运行时 | containerd + runc | conmon + crun / runc |
| 构建工具 | docker build | podman build / Buildah |
| 镜像推送 | docker push | podman push / Skopeo |
| 编排 | docker-compose | podman-compose / Quadlet |
| Pod 管理 | 无 | podman pod |
| K8s YAML | 不支持 | podman generate kube / play kube |
💡 提示
Podman、Buildah、Skopeo 被称为"容器工具三件套"(container tools),它们各自专注于容器生命周期的不同阶段,但共享底层库(containers/image、containers/storage)。
1.3 Rootless — 安全的基石
Rootless(无 root 权限)是 Podman 最重要的设计理念之一。
为什么 Rootless 很重要?
传统容器引擎需要 root 权限运行守护进程,这意味着:
攻击 dockerd = 获得宿主机 root 权限
漏洞示例:
- CVE-2019-5736: runc 容器逃逸
- CVE-2020-15257: containerd 网络隔离绕过
- CVE-2024-21626: runc 工作目录泄漏
Rootless 模式下,即使容器运行时被攻破,攻击者也只获得普通用户权限:
┌─────────────────────────────┐
│ 普通用户 (uid=1000) │
│ ┌───────────────────────┐ │
│ │ 用户命名空间 │ │
│ │ ┌─────┐ ┌─────┐ │ │
│ │ │容器A │ │容器B │ │ │
│ │ │root │ │root │ │ │
│ │ │(虚拟)│ │(虚拟)│ │ │
│ │ └─────┘ └─────┘ │ │
│ └───────────────────────┘ │
│ 容器内 root ≠ 宿主机 root │
└─────────────────────────────┘
Rootless 的代价
Rootless 并非没有代价,需要了解其限制:
| 场景 | Root 模式 | Rootless 模式 |
|---|---|---|
| 绑定 1024 以下端口 | ✅ | 需配置 sysctl 或 setcap |
| 访问宿主机设备 | ✅ | 受限 |
| 修改 /etc/resolv.conf | ✅ | 不可 |
| 使用 CNI/Netavark | ✅ | ✅(Podman 4.0+) |
| 多用户隔离 | ❌ | ✅ |
| cgroup v2 管理 | ✅ | ✅(需配置) |
⚠️ 注意
第 05 章将深入讲解 Rootless 模式的完整配置和限制解决方案。
1.4 OCI — 开放容器标准
OCI(Open Container Initiative)于 2015 年由 Docker、CoreOS、Google、Microsoft 等公司联合成立,旨在制定容器行业标准。
OCI 三大规范
| 规范 | 全称 | 作用 |
|---|---|---|
| Runtime Spec | OCI Runtime Specification | 定义容器如何运行(config.json、文件系统、生命周期) |
| Image Spec | OCI Image Specification | 定义镜像格式(manifest、layer、config) |
| Distribution Spec | OCI Distribution Specification | 定义镜像如何分发(Registry API) |
OCI 生态全景:
镜像构建 镜像分发 容器运行
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Buildah │ │ Registry │ │ crun │
│ docker │ │ Skopeo │ │ runc │
│ buildkit │ │ Harbor │ │ kata │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│Image Spec│ │Dist. Spec│ │Runtime │
│ (OCI) │ │ (OCI) │ │Spec (OCI)│
└──────────┘ └──────────┘ └──────────┘
OCI 对 Podman 的意义
因为 Podman 完全遵循 OCI 标准:
- 镜像兼容:Docker Hub 上的镜像可以直接使用
- 运行时可换:可使用 crun、runc、kata-containers 等
- 工具解耦:Buildah 构建的镜像可以被 Podman 运行
- 未来保障:遵循标准不会被厂商锁定
1.5 Podman 的生态系统
Podman 不是孤立的工具,而是一个完整的生态系统:
┌─────────────────────────────────────────────────────┐
│ 用户 / CI / CD │
├──────────┬──────────┬──────────┬─────────────────────┤
│ podman │ Buildah │ Skopeo │ podman-compose │
│ (容器/Pod)│ (构建) │ (传输) │ (多容器编排) │
├──────────┴──────────┴──────────┴─────────────────────┤
│ containers/image (镜像库) │
│ containers/storage (存储库) │
│ containers/common (公共配置) │
├─────────────────────────────────────────────────────┤
│ conmon (容器监控) │
├──────────┬──────────────────────────────────────────┤
│ crun │ runc │ kata-containers │
│ (C实现) │ (Go实现) │ (轻量级VM) │
├──────────┴──────────────────────────────────────────┤
│ Linux Kernel (cgroups, namespaces) │
└─────────────────────────────────────────────────────┘
核心组件说明
| 组件 | 作用 | 语言 |
|---|---|---|
| podman | 容器和 Pod 管理 CLI | Go |
| Buildah | 构建 OCI 镜像(无需守护进程) | Go |
| Skopeo | 镜像仓库间传输、检查、签名 | Go |
| conmon | 容器进程监控和日志收集 | C |
| crun | OCI 运行时(比 runc 更快、内存占用更少) | C |
| containers/image | 镜像操作库 | Go |
| containers/storage | 镜像和容器存储层管理 | Go |
1.6 什么时候选择 Podman?
✅ 推荐使用 Podman 的场景
- 安全敏感环境:金融、医疗、政府等行业对容器安全有严格要求
- systemd 服务器:需要容器随系统启动、自动重启
- CI/CD 流水线:无需守护进程,避免 CI 环境中的权限问题
- 多租户服务器:多个用户共享一台服务器,各自运行容器
- Kubernetes 开发:Pod 概念与 K8s 天然一致
- 边缘计算:资源受限环境下的轻量级容器方案
⚠️ 需要评估的场景
| 场景 | 建议 |
|---|---|
| 团队已深度使用 Docker Compose | 可迁移,但需测试兼容性 |
| 依赖 Docker Desktop 的 GUI 功能 | Podman Desktop 提供类似体验 |
| 使用 Docker Swarm | 建议迁移到 Kubernetes 或 Podman Quadlet |
| Windows 容器(WCOW) | Podman 目前仅支持 Linux 容器 |
1.7 快速体验
如果你想先感受一下 Podman 的使用体验:
# 检查是否已安装
$ podman --version
podman version 5.x.x
# 运行一个简单的容器(与 docker 完全一致)
$ podman run --rm -it alpine echo "Hello Podman!"
Hello Podman!
# 查看 Podman 信息
$ podman info
host:
arch: amd64
buildahVersion: 1.38.x
cgroupManager: systemd
cgroupVersion: v2
conmon:
package: conmon-2.x.x
distribution:
version: "41"
eventLogger: journald
rootless: true # ← Rootless 模式
...
💡 提示
如果你已安装 Docker,可以通过
alias docker=podman快速切换。但更推荐的做法是先阅读第 13 章的迁移指南,了解所有差异后再做切换。
1.8 本章小结
| 知识点 | 要点 |
|---|---|
| Podman 核心优势 | 无守护进程、Rootless、OCI 兼容 |
| 与 Docker 最大区别 | Fork/Exec 架构 vs C/S 架构 |
| Rootless 价值 | 即使容器被攻破,不获得宿主机 root |
| OCI 意义 | 标准化保障,不被厂商锁定 |
| 生态三件套 | Podman + Buildah + Skopeo |
下一步
- 👉 第 02 章:安装与配置 — 在你的系统上安装 Podman