Docker 与 Podman 容器技术完全指南
📖 前面项目开发部署基本上都基于docker进行的,后面docker商业化收费加之k8s不再原生支持docker,陆续开始迁移使用podman,本文旨在帮助新手从零建立容器技术的知识体系,涵盖从历史起源到未来趋势的全面内容。
目录
- 第一部分:容器技术的历史起源
- 1.1 容器技术之前:虚拟化技术的发展
- 1.2 操作系统级虚拟化的探索
- 1.3 Linux 内核的容器基础
- 第二部分:Docker 的诞生与崛起
- 2.1 Docker 的起源故事
- 2.2 Docker 的核心技术架构
- 2.3 Docker 的版本演变与发展历程
- 2.4 Docker 生态系统的形成
- 第三部分:容器标准化进程
- 3.1 OCI 开放容器标准
- 3.2 CRI 容器运行时接口
- 3.3 CNI 容器网络接口
- 3.4 CSI 容器存储接口
- 第四部分:Podman 的崛起与技术优势
- 4.1 Podman 的诞生背景
- 4.2 Podman 的架构设计
- 4.3 Podman 与 Docker 的核心差异
- 4.4 Podman Desktop 的发展
- 第五部分:Docker 与 Podman 详细技术对比
- 5.1 架构对比
- 5.2 安全性对比
- 5.3 兼容性对比
- 5.4 性能对比
- 5.5 命令对比速查表
- 第六部分:容器编排技术
- 6.1 从单容器到容器编排
- 6.2 Kubernetes 的统治地位
- 6.3 Docker Swarm 与 Kubernetes 的竞争
- 6.4 Podman 与 Kubernetes 的天然契合
- 第七部分:容器生态全景
- 7.1 容器运行时
- 7.2 容器镜像与仓库
- 7.3 容器构建工具
- 7.4 容器安全工具
- 7.5 容器监控与日志
- 第八部分:现代容器技术的前沿趋势
- 8.1 WebAssembly (Wasm) 容器
- 8.2 无根容器(Rootless Containers)
- 8.3 不可变基础设施
- 8.4 eBPF 与容器可观测性
- 8.5 机密容器(Confidential Containers)
- 8.6 边缘计算与容器
- 8.7 容器与 AI/ML 的融合
- 第九部分:新手实践指南
- 9.1 选择 Docker 还是 Podman?
- 9.2 环境搭建
- 9.3 从零开始的第一个容器
- 9.4 学习路径建议
- 第十部分:总结与展望
第一部分:容器技术的历史起源
1.1 容器技术之前:虚拟化技术的发展
1.1.1 物理服务器时代
在容器技术出现之前,IT 基础设施主要依赖物理服务器。每台服务器通常只运行一个应用,这导致了严重的资源浪费:
- 资源利用率低:服务器 CPU 使用率通常只有 5%-15%
- 扩展困难:部署新应用需要购买新硬件
- 维护成本高:大量的物理设备需要机房、电力、散热
- 部署周期长:新应用上线可能需要数周的硬件采购和配置时间
1.1.2 虚拟机的诞生
为了解决物理服务器的资源浪费问题,虚拟化技术应运而生:
1960s – 1970s:虚拟化的萌芽
- 1964 年:IBM 推出 CP-40 大型机操作系统,首次实现了虚拟化概念
- 1972 年:IBM 发布 VM/370,这是第一个商用虚拟化操作系统,允许在一台物理机上运行多个虚拟机实例
1990s – 2000s:虚拟化的成熟
- 1998 年:VMware 成立,次年推出 VMware Workstation,将虚拟化技术带到 x86 平台
- 2001 年:VMware 推出 ESX Server(后改名 ESXi),开创了服务器虚拟化市场
- 2003 年:Xen 开源虚拟化项目发布,被 Red Hat、SUSE 等采用
- 2006 年:Amazon 推出 AWS EC2,基于 Xen 虚拟化,开启了云计算时代
- 2007 年:KVM(Kernel-based Virtual Machine)被合并到 Linux 内核主线
虚拟机的优缺点:
| 完全隔离,安全性高 | 资源开销大(每个 VM 需要完整 OS) |
| 可运行不同操作系统 | 启动时间长(分钟级) |
| 硬件级隔离 | 镜像体积大(GB 级别) |
| 成熟的管理工具 | 内存和 CPU 利用率较低 |
1.1.3 虚拟机到容器的思想转变
虚拟机虽然解决了硬件利用率问题,但仍存在本质缺陷:
┌─────────────────────────────────────────────┐
│ 虚拟机架构 │
├─────────┬─────────┬─────────┬───────────────┤
│ App A │ App B │ App C │ │
├─────────┼─────────┼─────────┤ │
│ Bins/ │ Bins/ │ Bins/ │ │
│ Libs │ Libs │ Libs │ │
├─────────┼─────────┼─────────┤ │
│ Guest │ Guest │ Guest │ │
│ OS │ OS │ OS │ │
├─────────┴─────────┴─────────┴───────────────┤
│ Hypervisor (VMM) │
├─────────────────────────────────────────────┤
│ Host Operating System │
├─────────────────────────────────────────────┤
│ Infrastructure (Hardware) │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ 容器架构 │
├─────────┬─────────┬─────────┬───────────────┤
│ App A │ App B │ App C │ │
├─────────┼─────────┼─────────┤ │
│ Bins/ │ Bins/ │ Bins/ │ │
│ Libs │ Libs │ Libs │ │
├─────────┴─────────┴─────────┴───────────────┤
│ Container Runtime │
├─────────────────────────────────────────────┤
│ Host Operating System │
├─────────────────────────────────────────────┤
│ Infrastructure (Hardware) │
└─────────────────────────────────────────────┘
核心区别在于:虚拟机虚拟化的是硬件,而容器虚拟化的是操作系统。容器共享宿主机的内核,因此更加轻量。
1.2 操作系统级虚拟化的探索
容器技术的思想并非 Docker 首创,其历史可以追溯到几十年前:
1.2.1 chroot(1979 年)
- 时间:1979 年,随 Unix V7 发布
- 功能:改变进程的根目录,实现文件系统级别的隔离
- 局限:只提供文件系统隔离,无法隔离网络、进程、用户等
- 意义:开创了"进程隔离"的先河,是容器技术的思想起源
# chroot 基本用法
sudo chroot /path/to/new/root /bin/bash
1.2.2 FreeBSD Jails(2000 年)
- 时间:2000 年,R&D Associates 为 FreeBSD 开发
- 功能:在 chroot 基础上增加了网络、用户、进程的隔离
- 特点:每个 Jail 是一个独立的虚拟环境,有自己的 IP 地址、主机名
- 意义:第一个真正意义上的操作系统级虚拟化实现
1.2.3 Linux VServer(2001 年)
- 时间:2001 年发布
- 功能:在 Linux 上实现类似 FreeBSD Jails 的隔离
- 特点:通过修改 Linux 内核实现安全分区
- 局限:需要打补丁的内核,未进入主线
1.2.4 Solaris Zones(2004 年)
- 时间:2004 年,Sun Microsystems 发布
- 功能:Solaris 操作系统上的虚拟化技术
- 特点:资源控制更精细,支持动态创建和管理
- 意义:推动了企业级容器技术的发展
1.2.5 OpenVZ(2005 年)
- 时间:2005 年发布
- 功能:基于 Linux 内核的操作系统级虚拟化
- 特点:需要修改内核,主要用于 VPS 托管
- 影响:VPS 行业的主要技术基础
1.2.6 LXC – Linux Containers(2008 年)
- 时间:2008 年发布
- 开发者:由 IBM 工程师 Daniel Lezenga 和 Canonical 的 Serge Hallyn 主导
- 功能:利用 Linux 内核的 cgroups 和 namespaces 实现完整的操作系统级虚拟化
- 意义:Docker 的直接技术前身,Docker 最初就是基于 LXC 构建的
- 特点:
- 不需要修改内核(使用原生内核特性)
- 提供完整的 Linux 系统环境
- 包含完整的 init 进程
- 比虚拟机轻量得多
# LXC 基本用法
lxc-create -t download -n mycontainer
lxc-start -n mycontainer
lxc-attach -n mycontainer
1.3 Linux 内核的容器基础
容器技术能够实现,依赖于 Linux 内核的两大核心特性:
1.3.1 Namespaces(命名空间)
Namespaces 是 Linux 内核提供的一种资源隔离机制,最早在 2002 年的 Linux 2.4.19 中引入。它将内核的全局资源进行封装,使得每个命名空间内的进程拥有独立的资源视图。
Linux 内核提供了以下 8 种 Namespace:
| Mount (mnt) | Linux 2.4.19 (2002) | 文件系统挂载点 |
| UTS | Linux 2.6.19 (2006) | 主机名和域名 |
| IPC | Linux 2.6.19 (2006) | 进程间通信资源 |
| PID | Linux 2.6.24 (2008) | 进程 ID |
| Network (net) | Linux 2.6.29 (2009) | 网络栈(接口、路由、防火墙规则) |
| User | Linux 3.8 (2013) | 用户和组 ID |
| Cgroup | Linux 4.6 (2016) | Cgroup 根目录 |
| Time | Linux 5.6 (2020) | 系统时钟 |
# 查看进程的 Namespace
ls -la /proc/$$/ns/
# 输出示例:
# lrwxrwxrwx 1 root root 0 … cgroup -> 'cgroup:[4026531835]'
# lrwxrwxrwx 1 root root 0 … ipc -> 'ipc:[4026531839]'
# lrwxrwxrwx 1 root root 0 … mnt -> 'mnt:[4026531840]'
# lrwxrwxrwx 1 root root 0 … net -> 'net:[4026531840]'
# lrwxrwxrwx 1 root root 0 … pid -> 'pid:[4026531836]'
# lrwxrwxrwx 1 root root 0 … user -> 'user:[4026531837]'
# lrwxrwxrwx 1 root root 0 … uts -> 'uts:[4026531838]'
1.3.2 Cgroups(控制组)
Cgroups(Control Groups)由 Google 工程师 Paul Menage 和 Rohit Seth 于 2006 年开发,最初命名为"进程容器"(Process Containers),2008 年合并到 Linux 内核主线(2.6.24)。
Cgroups 的核心功能是限制、记录和隔离进程组使用的物理资源:
| cpu | 限制 CPU 使用时间 |
| cpuset | 绑定到特定 CPU 核心 |
| cpuacct | 统计 CPU 使用情况 |
| memory | 限制内存使用量 |
| blkio | 限制块设备 I/O |
| devices | 控制设备访问权限 |
| freezer | 暂停/恢复进程组 |
| net_cls | 网络数据包分类标记 |
| pids | 限制进程数量 |
# Cgroup v2 示例:限制进程内存为 512MB
mkdir /sys/fs/cgroup/mygroup
echo 536870912 > /sys/fs/cgroup/mygroup/memory.max
echo $$ > /sys/fs/cgroup/mygroup/cgroup.procs
1.3.3 Union File Systems(联合文件系统)
UnionFS 是容器镜像分层技术的基础。它允许将多个目录(称为分支)叠加在一起,形成一个统一的文件系统视图。
主要实现:
- AUFS(Advanced Multi-Layered Unification File System):Docker 早期默认使用的联合文件系统
- OverlayFS:Linux 内核主线(3.18)合并的联合文件系统,现为 Docker 默认存储驱动
- Devicemapper:基于块设备的存储驱动
- Btrfs / ZFS:支持快照和写时复制的文件系统
┌────────────────────────┐
│ Container Layer │ ← 可写层(Copy-on-Write)
├────────────────────────┤
│ Image Layer 3 │ ← 只读层(如: 应用代码)
├────────────────────────┤
│ Image Layer 2 │ ← 只读层(如: 依赖库)
├────────────────────────┤
│ Image Layer 1 │ ← 只读层(如: 基础系统)
└────────────────────────┘
第二部分:Docker 的诞生与崛起

2.1 Docker 的起源故事
2.1.1 dotCloud 的困境
Docker 诞生于一家名为 dotCloud 的 PaaS(Platform as a Service)公司。dotCloud 由 Solomon Hykes 于 2008 年在巴黎创立,后来搬到旧金山。
dotCloud 的 PaaS 平台需要支持多种编程语言和框架(Python、Ruby、Java、Node.js 等),他们面临的核心问题是:如何在同一个基础设施上高效地运行和隔离不同的应用?
他们尝试了虚拟机方案,但发现:
- 虚拟机启动太慢,无法满足快速扩展的需求
- 每个应用一个 VM,资源浪费严重
- 镜像太大,传输和部署效率低
2.1.2 LXC 的尝试与不足
dotCloud 团队转向了 LXC(Linux Containers),LXC 虽然比虚拟机轻量,但仍有不足:
- 使用复杂:需要了解底层的 namespace 和 cgroup 配置
- 镜像管理困难:没有统一的镜像格式和分发机制
- 可移植性差:不同环境之间的迁移很困难
- 缺乏开发者友好的接口
2.1.3 Docker 的诞生
2013 年 3 月,Solomon Hykes 在 PyCon 2013 大会上首次展示了 Docker。这个演示只有 5 分钟,但震撼了整个技术圈。
Docker 最初是 dotCloud 内部的一个项目,基于 LXC 构建,但做了关键性的创新:
# Docker 诞生前:部署一个应用可能需要
# 1. 安装操作系统
# 2. 配置网络
# 3. 安装运行时环境
# 4. 安装依赖
# 5. 部署应用代码
# 6. 配置应用
# 整个过程可能需要数小时甚至数天
# Docker 出现后:
docker run -p 80:80 my-web-app
# 一条命令,秒级启动
2.1.4 Solomon Hykes 的开创性贡献
Solomon Hykes 对容器技术的贡献不仅仅是一个工具,更重要的是他提出了一种新的软件交付范式:
“Docker 的目标不是创建一个新的技术,而是让现有的技术(Linux 容器)变得简单易用。” — Solomon Hykes, PyCon 2013
他的核心理念是 “Build, Ship, Run”:
- Build:用 Dockerfile 构建应用镜像
- Ship:将镜像推送到仓库
- Run:在任何支持 Docker 的环境中运行
2.2 Docker 的核心技术架构
2.2.1 整体架构
Docker 采用经典的 客户端-服务器(C/S)架构:
┌─────────────────────────────────────────────────────────┐
│ Docker Host │
│ │
│ ┌──────────┐ ┌──────────────────────────────────┐ │
│ │ │ │ Docker Daemon │ │
│ │ Docker │ │ (dockerd) │ │
│ │ Client │───>│ │ │
│ │ (docker) │ │ ┌────────────┐ ┌──────────────┐ │ │
│ │ │ │ │ Images │ │ Containers │ │ │
│ └──────────┘ │ └────────────┘ └──────────────┘ │ │
│ ↑ │ │ │ │ │
│ │ │ ┌─────────┴───────────┴────────┐│ │
│ User Input │ │ Container Runtime ││ │
│ │ │ (containerd → runc) ││ │
│ │ └──────────────────────────────┘│ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
2.2.2 核心组件详解
1. Docker Client (docker)
- 用户与 Docker 交互的命令行工具
- 通过 REST API 与 Docker Daemon 通信
- 可以连接本地或远程的 Daemon
2. Docker Daemon (dockerd)
- Docker 的核心守护进程
- 负责管理:容器生命周期、镜像、网络、存储卷
- 监听 Docker API 请求
- 与 containerd 交互来管理容器
3. containerd
- 2016 年从 Docker 中分离出来的容器运行时
- 负责容器的完整生命周期管理
- 管理镜像、容器存储、网络等
- 已成为 CNCF 毕业项目
4. runc
- 最底层的容器运行时
- 实现 OCI 运行时规范
- 直接调用 Linux 内核的 namespace 和 cgroup
- 创建和运行容器进程
5. Docker Registry
- 镜像仓库服务
- Docker Hub 是默认的公共仓库
- 支持私有仓库部署
2.2.3 容器运行流程
docker run -d –name web -p 80:80 nginx
执行上述命令时,Docker 内部的完整流程:
1. Docker Client 发送 REST API 请求给 Docker Daemon
│
▼
2. Docker Daemon 收到请求,检查本地是否有 nginx 镜像
│
▼
3. 如果没有镜像,从 Docker Hub 拉取 nginx 镜像
│
▼
4. Docker Daemon 调用 containerd 创建容器
│
▼
5. containerd 调用 runc 创建容器进程
│
▼
6. runc 配置 namespaces、cgroups、rootfs
│
▼
7. 容器进程启动,nginx 开始运行
│
▼
8. Docker Daemon 配置端口映射(80:80)
│
▼
9. 返回容器 ID 给 Docker Client
2.3 Docker 的版本演变与发展历程
2.3.1 关键里程碑时间线
| 2013.03 | Docker 首次公开演示 | Solomon Hykes 在 PyCon 展示 |
| 2013.03 | Docker 0.1 发布 | 基于 LXC 的第一个版本 |
| 2013.06 | Docker 加入 Y Combinator | 获得创业加速支持 |
| 2013.07 | Docker 0.5 发布 | 移除 LXC 默认依赖,引入 libcontainer |
| 2013.10 | Docker 0.6.5 | 支持容器的重启策略 |
| 2013.10 | dotCloud 更名为 Docker Inc. | 公司战略全面转向容器 |
| 2013.11 | 获得 1500 万美元 B 轮融资 | Greylock Partners 领投 |
| 2014.01 | Docker 0.7 | 引入插件化存储驱动 |
| 2014.04 | Docker 0.9 | 引入 exec driver,支持多种运行时 |
| 2014.06 | Docker 1.0 | 第一个正式稳定版本,标志 Docker 进入生产就绪 |
| 2014.06 | DockerCon 2014 | 第一届 Docker 大会,超过 1000 人参加 |
| 2014.08 | 获得 4000 万美元 C 轮融资 | 估值约 4 亿美元 |
| 2014.11 | Docker 1.3 | 引入 docker exec,安全增强 |
| 2014.12 | CoreOS 推出 Rocket (rkt) | Docker 的第一个主要竞争对手 |
| 2015.01 | 获得 9500 万美元 D 轮融资 | 估值约 10 亿美元,成为"独角兽" |
| 2015.03 | Docker 1.5 | 支持只读容器、IPv6 |
| 2015.04 | OCI 成立 | Docker 与 CoreOS 共同推动容器标准化 |
| 2015.06 | Docker 1.6 | 引入 docker build 的多阶段构建 |
| 2015.07 | Docker 1.7 | 支持多主机网络 |
| 2015.11 | Docker 1.9 | 引入编排功能、多主机网络、新的插件系统 |
| 2016.02 | Docker 1.10 | 用户命名空间支持、安全增强 |
| 2016.06 | Docker 1.12 | 内置 Swarm 编排功能(Swarm Mode) |
| 2016.12 | containerd 从 Docker 分离 | 成为独立项目,后加入 CNCF |
| 2017.01 | Docker 更名 Moby | 社区争议事件 |
| 2017.03 | Docker Enterprise Edition (EE) | 推出企业版产品 |
| 2017.10 | 获得 9200 万美元融资 | 投资者包括沙特阿美旗下基金 |
| 2018.07 | Docker 18.06 | 支持 Kubernetes 作为编排后端 |
| 2019.03 | Docker Desktop Enterprise | 面向企业的桌面开发工具 |
| 2019.11 | Docker Enterprise 被 Mirantis 收购 | Docker Inc. 聚焦开发者工具 |
| 2020.01 | Docker Hub 限制免费用户的拉取频率 | 引发社区不满 |
| 2020.05 | Docker Desktop 调整许可政策 | 限制大企业免费使用 |
| 2021.08 | Docker Desktop 改为订阅制 | 250 人以上企业需付费 |
| 2022.05 | Docker Scout 发布 | 容器镜像安全扫描服务 |
| 2023 | Docker 商业模式持续调整 | 开发者工具订阅 |
2.3.2 Docker 的重大战略转折
转折 1:从 LXC 到 libcontainer(2014 年)
Docker 最初基于 LXC 构建,但 2014 年决定开发自己的容器运行时 libcontainer,减少对 LXC 的依赖。这个决定:
- 降低了外部依赖带来的不确定性
- 使 Docker 对容器的控制更加精细
- 后来 libcontainer 演变为 runc
转折 2:编排之争(2016 年)
2016 年 Docker 在 1.12 版本中内置了 Swarm Mode,直接与 Kubernetes 竞争。这场"编排战争"最终以 Kubernetes 的胜利告终:
- Docker Swarm:简单易用,但功能有限
- Kubernetes:功能强大,生态丰富,Google 开源
转折 3:Docker Enterprise 出售(2019 年)
2019 年 11 月,Mirantis 收购了 Docker 的企业业务(Docker Enterprise)。Docker Inc. 转型专注于开发者工具:
- Docker Desktop
- Docker Hub
- Docker Dev Environments
- Docker Scout(安全扫描)
2.4 Docker 生态系统的形成
2.4.1 Docker Hub
Docker Hub 是全球最大的容器镜像仓库,截至 2024 年:
- 超过 1500 万个 镜像仓库
- 每月超过 150 亿次 镜像拉取
- 拥有数千个官方镜像(nginx、python、node、mysql 等)
2.4.2 Dockerfile 生态
Dockerfile 定义了一种标准化的应用打包方式,成为事实标准:
# 典型的多阶段构建 Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci –only=production
FROM node:18-alpine
WORKDIR /app
COPY –from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
2.4.3 Docker Compose
Docker Compose(最初叫 Fig)允许用 YAML 文件定义和运行多容器应用:
# docker-compose.yml 示例
version: '3.8'
services:
web:
build: .
ports:
– "80:3000"
depends_on:
– db
– redis
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
volumes:
– pgdata:/var/lib/postgresql/data
redis:
image: redis:7–alpine
volumes:
pgdata:
第三部分:容器标准化进程
3.1 OCI 开放容器标准
3.1.1 OCI 的诞生
2015 年 6 月,在 Docker 和 CoreOS 的共同推动下,Linux 基金会成立了 OCI(Open Container Initiative,开放容器计划)。
OCI 的成立背景:
- Docker 快速发展,但 Docker Inc. 控制着核心技术
- CoreOS 推出了 Rocket (rkt) 竞争
- 行业需要统一标准,避免碎片化
OCI 的创始成员包括:Docker、CoreOS、Google、Microsoft、Red Hat、IBM、Amazon 等 20 多家公司。
3.1.2 OCI 规范
OCI 定义了两个核心规范:
1. Runtime Specification(运行时规范)
- 定义如何运行一个容器
- 涉及文件系统、命名空间、cgroups 等配置
- runc 是该规范的参考实现
2. Image Specification(镜像规范)
- 定义容器镜像的格式
- 包括镜像清单(manifest)、层(layers)、配置(config)
- 确保镜像的跨平台可移植性
3. Distribution Specification(分发规范,2020 年新增)
- 定义如何推送和拉取镜像
- 标准化镜像仓库 API
┌──────────────────────────────────────────────┐
│ OCI 标准 │
│ │
│ ┌─────────────┐ ┌──────────┐ ┌─────────┐ │
│ │ Runtime │ │ Image │ │ Dist │ │
│ │ Spec │ │ Spec │ │ Spec │ │
│ │ │ │ │ │ │ │
│ │ How to run │ │ How to │ │ How to │ │
│ │ containers │ │ package │ │ share │ │
│ │ │ │ images │ │ images │ │
│ └─────────────┘ └──────────┘ └─────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ runc / crun / kata │ │
│ │ OCI 镜像格式 │ │
│ │ Registry API v2 │ │
│ └─────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
3.1.3 OCI 的影响
OCI 标准化使得:
- 不同的容器运行时可以互换使用
- 镜像可以在不同的平台间无缝迁移
- 避免了厂商锁定
- 促进了容器生态的繁荣
3.2 CRI 容器运行时接口
CRI(Container Runtime Interface) 是 Kubernetes 定义的容器运行时接口,于 2016 年随 Kubernetes 1.5 引入。
CRI 的目的:
- 让 Kubernetes 与特定的容器运行时解耦
- 允许接入不同的容器运行时(containerd、CRI-O 等)
┌───────────────────────────────────┐
│ kubelet │
│ │ │
│ ┌─────────┴──────────┐ │
│ │ CRI │ │
│ │ (gRPC 接口) │ │
│ └─────────┬──────────┘ │
│ │ │
│ ┌─────────┼──────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ CRI-O containerd kata │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ runc runc kata-shim │
└───────────────────────────────────┘
3.3 CNI 容器网络接口
CNI(Container Network Interface) 由 CoreOS 提出,是一组用于配置 Linux 容器网络接口的规范和库。
主流 CNI 插件:
- Calico:基于 BGP 的网络方案,支持网络策略
- Flannel:CoreOS 开发的简单覆盖网络
- Cilium:基于 eBPF 的高性能网络方案
- Weave Net:支持加密的覆盖网络
3.4 CSI 容器存储接口
CSI(Container Storage Interface) 是 Kubernetes 定义的容器存储接口,允许存储供应商为容器提供持久化存储。
第四部分:Podman 的崛起与技术优势

4.1 Podman 的诞生背景
4.1.1 Docker 的问题
随着 Docker 的发展,社区和企业用户发现了越来越多的问题:
1. 架构安全问题
- Docker Daemon(dockerd)以 root 权限运行
- 所有容器操作通过 Daemon 统一管理
- Daemon 被攻破意味着所有容器被攻破
- 存在"单点突破,全面沦陷"的风险
2. 单点故障
- Docker Daemon 是一个长期运行的中心化进程
- Daemon 崩溃会影响所有正在运行的容器
- 不符合 Unix 哲学的"做一件事并做好"
3. 许可和商业模式
- Docker Inc. 的商业策略不断变化
- Docker Desktop 对大企业收费
- Docker Hub 的拉取频率限制
4. 生态控制权
- Docker Inc. 对容器标准有过多话语权
- 社区对 Docker Inc. 的决策不满
4.1.2 Red Hat 的容器战略
Red Hat 作为 Linux 企业市场的领导者,在容器技术上有自己的战略:
2013-2014 年:Red Hat 与 Docker 合作,将 Docker 集成到 RHEL 中 2014-2015 年:Red Hat 开始投资容器安全 2015-2016 年:Red Hat 开发 CRI-O 作为 Kubernetes 的轻量级运行时 2017-2018 年:Red Hat 开始开发 Podman 作为 Docker 的替代品
4.1.3 Podman 的名字含义
Podman = Pod Manager
“Pod” 的概念来自 Kubernetes,一个 Pod 是一组共享网络和存储的容器。Podman 在设计时就原生支持 Pod 的概念,这是它与 Docker 的一个重要区别。
4.2 Podman 的架构设计
4.2.1 无守护进程架构(Daemonless)
Podman 最重要的设计决策是无守护进程架构:
┌──────────────────────────────────────────────┐
│ Docker 架构 │
│ │
│ ┌─────────┐ ┌─────────────────────┐ │
│ │ Docker │─────>│ Docker Daemon │ │
│ │ CLI │ API │ (dockerd) │ │
│ └─────────┘ │ │ │
│ │ containerd ─── runc│ │
│ └─────────────────────┘ │
│ │
│ 用户请求 ──> Daemon ──> containerd ──> runc │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Podman 架构 │
│ │
│ ┌─────────┐ │
│ │ Podman │──fork/exec──> conmon ──> runc │
│ │ CLI │ │
│ └─────────┘ 每个容器一个 conmon 进程 │
│ │
│ 用户请求 ──> fork/exec ──> 容器进程 │
└──────────────────────────────────────────────┘
对比分析:
| 守护进程 | dockerd 为中心化守护进程 | 无守护进程 |
| 进程模型 | 所有容器由 Daemon 管理 | 每个容器独立进程 |
| 故障影响 | Daemon 崩溃影响所有容器 | 容器间互不影响 |
| 安全模型 | Daemon 需要 root 权限 | 支持 rootless |
| 资源占用 | Daemon 常驻内存 | 按需创建进程 |
4.2.2 conmon(Container Monitor)
Podman 使用 conmon 作为容器的监控进程:
- 每个容器对应一个 conmon 进程
- 负责容器的日志收集
- 监控容器的退出状态
- 处理容器的 I/O 流
- 作为容器进程的父进程(PID 1)
# 查看 conmon 进程
ps aux | grep conmon
# root 1234 conmon –api-version 1 -c abc123 …
# root 5678 conmon –api-version 1 -c def456 …
4.2.3 Podman 的组件体系
Podman 是 Buildah、Skopeo、Podman 三大工具之一(被统称为"新容器三件套"):
| Podman | 运行和管理容器 | docker run / docker ps |
| Buildah | 构建容器镜像 | docker build |
| Skopeo | 镜像仓库操作 | docker push / pull |
┌───────────────────────────────────────────────────┐
│ Red Hat 容器工具栈 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Podman │ │ Buildah │ │ Skopeo │ │
│ │ │ │ │ │ │ │
│ │ 运行容器 │ │ 构建镜像 │ │ 管理仓库 │ │
│ │ 管理Pod │ │ OCI格式 │ │ 复制镜像 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ └──────────────┼──────────────┘ │
│ │ │
│ ┌───────┴───────┐ │
│ │ containers/ │ │
│ │ image (通用库)│ │
│ └───────┬───────┘ │
│ │ │
│ ┌───────┴───────┐ │
│ │ OCI 运行时 │ │
│ │ runc / crun │ │
│ └───────────────┘ │
└───────────────────────────────────────────────────┘
4.3 Podman 与 Docker 的核心差异
4.3.1 无守护进程 vs 有守护进程
Docker 的 Daemon 问题:
# Docker:所有操作都经过 Daemon
$ docker run nginx # Client -> Daemon -> containerd -> runc
$ docker ps # Client -> Daemon
$ docker build . # Client -> Daemon
# 如果 Daemon 崩溃:
$ sudo systemctl stop docker
# 所有容器停止!正在运行的服务全部中断!
Podman 的 Fork/Exec 模型:
# Podman:每个容器独立进程
$ podman run nginx # 直接 fork/exec -> conmon -> runc
$ podman ps # 直接读取容器状态
$ podman build . # 直接 fork/exec
# 没有中心化 Daemon,不存在单点故障
# 即使 Podman 进程结束,正在运行的容器不受影响
4.3.2 Rootless(无根/非特权)支持
Podman 的 Rootless 是一等公民:
# Docker 传统方式:Daemon 以 root 运行
$ whoami
user
$ docker run nginx
# 连接到以 root 运行的 Daemon -> 容器以 root 运行
# Podman Rootless:整个过程无需 root
$ whoami
user
$ podman run nginx
# 直接以 user 身份 fork/exec -> 容器以 user 身份运行
Rootless 的安全优势:
# 即使容器被攻破,攻击者也只是普通用户权限
# 不会获得宿主机的 root 权限
# Docker 场景:
# 容器逃逸 -> 获得 Daemon 的 root 权限 -> 完全控制宿主机
# Podman Rootless 场景:
# 容器逃逸 -> 只获得普通用户权限 -> 影响有限
Rootless 的技术实现:
- User Namespaces:映射容器内的 root 到宿主机的普通用户
- slirp4netns:用户态网络栈(不需要创建网络接口的权限)
- FUSE-OverlayFS:用户态的联合文件系统
# Podman Rootless 的 UID 映射
$ cat /etc/subuid
user:100000:65536
$ cat /etc/subgid
user:100000:65536
# 容器内的 root(UID 0) 映射到宿主机的 UID 100000
# 容器内的 UID 1 映射到宿主机的 UID 100001
# …以此类推
4.3.3 Pod 的原生支持
# Podman 创建 Pod(类似 Kubernetes 的概念)
$ podman pod create –name myapp -p 80:80
# 在同一个 Pod 中运行多个容器
$ podman run -d –pod myapp –name web nginx
$ podman run -d –pod myapp –name cache redis
# web 和 cache 共享网络命名空间(可以通过 localhost 互相访问)
# 类似 Kubernetes 中一个 Pod 内多个容器的通信方式
Docker 没有原生的 Pod 概念,需要使用 Docker Compose 或自定义网络来实现类似功能。
4.3.4 与 Kubernetes 的兼容性
Podman 在设计上就考虑了与 Kubernetes 的兼容性:
# Podman 可以直接生成 Kubernetes YAML
$ podman generate kube myapp-pod > myapp.yaml
# 生成的 YAML 可以直接用于 kubectl apply
$ kubectl apply -f myapp.yaml
# Podman 可以从 Kubernetes YAML 创建 Pod
$ podman play kube myapp.yaml
4.4 Podman Desktop 的发展
Podman Desktop 是 Red Hat 推出的桌面 GUI 工具,对标 Docker Desktop:
发展历程:
- 2022 年 2 月:Podman Desktop 首次发布(v0.0.1)
- 2022 年 9 月:支持 Windows 和 macOS
- 2023 年:加入 CNCF 沙箱项目
- 2024 年:功能持续完善,支持 Kubernetes 集成
核心特性:
- 图形化容器管理
- 镜像管理
- Pod 管理
- Kubernetes YAML 生成
- 支持扩展(VS Code 风格的插件系统)
- 支持 Docker 兼容模式
主流框架对 Podman 的优先推荐:
很多现代框架和工具已经将 Podman 作为首选推荐:
| Red Hat OpenShift | 使用 CRI-O + Podman |
| Fedora | 默认使用 Podman |
| RHEL 8+ | 默认使用 Podman |
| Ubuntu 22.04+ | 推荐 Podman |
| Spring Boot | 推荐 Buildah/Podman |
| Quarkus | 优先支持 Podman |
| Rancher Desktop | 使用 containerd(Podman 兼容) |
| Kind (K8s in Docker) | 支持 Podman 作为 provider |
| Minikube | 支持 Podman 作为 driver |
| GitLab CI | 支持 Podman runner |
第五部分:Docker 与 Podman 详细技术对比
5.1 架构对比
┌──────────────────── Docker 架构 ────────────────────┐
│ │
│ ┌─────────┐ REST API ┌──────────────────────┐ │
│ │ Docker │─────────────>│ dockerd │ │
│ │ CLI │ │ (daemon, root) │ │
│ └─────────┘ │ │ │ │
│ │ ┌────┴────┐ │ │
│ │ │containerd│ │ │
│ │ └────┬────┘ │ │
│ │ │ │ │
│ │ ┌────┴────┐ │ │
│ │ │ runc │ │ │
│ │ └─────────┘ │ │
│ └──────────────────────┘ │
│ │
│ 特点:中心化守护进程,所有容器由 Daemon 管理 │
└──────────────────────────────────────────────────────┘
┌──────────────────── Podman 架构 ────────────────────┐
│ │
│ ┌─────────┐ ┌──────────────────────┐ │
│ │ Podman │──fork/exec──>│ conmon + runc │ │
│ │ CLI │ │ (每个容器独立进程) │ │
│ └─────────┘ └──────────────────────┘ │
│ ┌──────────────────────┐ │
│ │ conmon + runc │ │
│ │ (另一个容器) │ │
│ └──────────────────────┘ │
│ │
│ 特点:无守护进程,每个容器直接由 CLI fork 出来 │
└──────────────────────────────────────────────────────┘
5.2 安全性对比
| 默认运行权限 | root(Daemon 需要 root) | 支持 rootless(用户态) |
| Rootless 支持 | 后期添加(Docker 20.10+) | 设计之初就支持 |
| 守护进程攻击面 | Daemon 是单一攻击目标 | 无 Daemon,攻击面分散 |
| SELinux 支持 | 支持 | 支持且更好(Red Hat 主导) |
| Seccomp 配置 | 支持 | 支持 |
| User Namespaces | 支持 | 默认启用 |
| 容器逃逸影响 | 可能获取 Daemon 的 root 权限 | 只影响当前用户 |
Docker Rootless 配置示例:
# Docker 也支持 rootless,但配置更复杂
$ dockerd-rootless-setuptool.sh install
$ export DOCKER_HOST=unix:///run/user/1000/docker.sock
Podman Rootless 使用示例:
# Podman rootless 开箱即用
$ podman run –rm -it alpine sh
# 直接以当前用户身份运行,无需额外配置
5.3 兼容性对比
5.3.1 Docker CLI 兼容
Podman 几乎完全兼容 Docker CLI:
# 方法 1:使用 podman 命令
$ podman run -d -p 80:80 –name web nginx
# 方法 2:设置别名(完全替代 docker 命令)
$ alias docker=podman
$ docker run -d -p 80:80 –name web nginx
# 实际执行的是 podman
# 方法 3:设置 DOCKER_HOST(兼容更多工具)
$ export DOCKER_HOST=$(podman machine inspect –format '{{.ConnectionInfo.PodmanSocket.Path}}')
5.3.2 Docker API 兼容
Podman 提供了兼容 Docker API 的服务:
# 启动 Podman 的 Docker API 兼容服务
$ podman system service –time=0 tcp:0.0.0.0:2375 &
# 使用 Docker CLI 连接
$ docker -H tcp://localhost:2375 ps
5.3.3 Docker Compose 兼容
# Podman 原生支持 podman-compose
$ pip install podman-compose
$ podman-compose up -d
# 或者使用 Docker Compose 与 Podman 配合
$ export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock
$ docker-compose up -d
5.4 性能对比
启动时间对比(典型场景):
| 首次启动容器 | ~500ms | ~600ms | Podman 无 Daemon 预热 |
| Daemon 已启动时 | ~200ms | ~300ms | Docker Daemon 缓存优势 |
| 无 Daemon 运行 | 不适用 | ~300ms | Podman 无需预热 Daemon |
| 冷启动 | ~2s | ~1s | Podman 无 Daemon 启动开销 |
资源占用对比:
| 内存(空闲时) | ~80-150MB(Daemon) | ~0(无 Daemon) |
| 内存(运行容器时) | Daemon + 容器 | conmon + 容器 |
| CPU(空闲时) | ~0-1%(Daemon) | 0% |
| CPU(运行容器时) | 与 Podman 相当 | 与 Docker 相当 |
实际差异:在生产环境中,两者的性能差异很小。选择的主要考量应该是安全性和架构,而非性能。
5.5 命令对比速查表
5.5.1 容器操作
| 运行容器 | docker run | podman run |
| 查看容器 | docker ps | podman ps |
| 停止容器 | docker stop | podman stop |
| 删除容器 | docker rm | podman rm |
| 查看日志 | docker logs | podman logs |
| 进入容器 | docker exec -it | podman exec -it |
| 复制文件 | docker cp | podman cp |
| 容器状态 | docker inspect | podman inspect |
| 容器统计 | docker stats | podman stats |
5.5.2 镜像操作
| 拉取镜像 | docker pull | podman pull |
| 推送镜像 | docker push | podman push |
| 构建镜像 | docker build | podman build 或 buildah build |
| 查看镜像 | docker images | podman images |
| 删除镜像 | docker rmi | podman rmi |
| 镜像历史 | docker history | podman history |
| 标记镜像 | docker tag | podman tag |
5.5.3 网络操作
| 查看网络 | docker network ls | podman network ls |
| 创建网络 | docker network create | podman network create |
| 删除网络 | docker network rm | podman network rm |
5.5.4 卷操作
| 查看卷 | docker volume ls | podman volume ls |
| 创建卷 | docker volume create | podman volume create |
| 删除卷 | docker volume rm | podman volume rm |
5.5.5 Podman 独有功能
| 创建 Pod | podman pod create | Docker 没有原生 Pod |
| 查看 Pod | podman pod ps | 列出所有 Pod |
| 生成 K8s YAML | podman generate kube | 导出为 K8s 配置 |
| 使用 K8s YAML | podman play kube | 从 K8s 配置创建 Pod |
| 系统重置 | podman system reset | 清除所有容器和镜像 |
| Rootless 检查 | podman unshare | 进入 user namespace |
第六部分:容器编排技术
6.1 从单容器到容器编排
在生产环境中,一个应用往往由多个微服务组成。手动管理数十甚至数百个容器是不现实的,因此容器编排技术应运而生。
容器编排解决的问题:
- 容器的调度和部署
- 服务发现和负载均衡
- 自动扩缩容
- 滚动更新和回滚
- 健康检查和自愈
- 存储和配置管理
- 密钥和证书管理
6.2 Kubernetes 的统治地位
6.2.1 Kubernetes 的诞生
- 2014 年 6 月:Google 开源 Kubernetes(代号 Project Seven,致敬星际迷航的 Borg)
- 2015 年 7 月:Kubernetes 1.0 发布
- 2015 年 7 月:Google 与 Linux 基金会成立 CNCF
- 2018 年 3 月:Kubernetes 从 CNCF 毕业
Kubernetes 的设计继承了 Google 内部 Borg 系统的经验。Borg 是 Google 从 2003 年就开始使用的集群管理系统,运行着 Google 的所有核心服务。
6.2.2 Kubernetes 架构
┌──────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Control Plane (Master) │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────────┐│ │
│ │ │ API │ │ Scheduler│ │ Controller ││ │
│ │ │ Server │ │ │ │ Manager ││ │
│ │ └──────────┘ └──────────┘ └──────────────┘│ │
│ │ ┌──────────────────────────────────────────┐│ │
│ │ │ etcd (数据存储) ││ │
│ │ └──────────────────────────────────────────┘│ │
│ └─────────────────────────────────────────────┘ │
│ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────┐ │
│ │ Worker Node │ │ Worker Node │ │ Worker │ │
│ │ │ │ │ │ Node │ │
│ │ ┌─────┐┌────┐│ │ ┌─────┐┌────┐│ │ ┌────┐ │ │
│ │ │Pod ││Pod ││ │ │Pod ││Pod ││ │ │Pod │ │ │
│ │ └─────┘└────┘│ │ └─────┘└────┘│ │ └────┘ │ │
│ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────┐ │ │
│ │ │ kubelet │ │ │ │ kubelet │ │ │ │kubelet│ │ │
│ │ │ kube-proxy│ │ │ │ kube-proxy│ │ │ │kube- │ │ │
│ │ └──────────┘ │ │ └──────────┘ │ │ │proxy │ │ │
│ │ ┌──────────┐ │ │ ┌──────────┐ │ │ └──────┘ │ │
│ │ │Container │ │ │ │Container │ │ │┌────────┐│ │
│ │ │Runtime │ │ │ │Runtime │ │ ││Container││ │
│ │ │(CRI-O/ │ │ │ │(CRI-O/ │ │ ││Runtime ││ │
│ │ │containerd│ │ │ │containerd│ │ │└────────┘│ │
│ │ └──────────┘ │ │ └──────────┘ │ └───────────┘ │
│ └───────────────┘ └───────────────┘ │
└──────────────────────────────────────────────────────────┘
6.2.3 Kubernetes 的成功因素
6.3 Docker Swarm 与 Kubernetes 的竞争
Docker Swarm 是 Docker 内置的编排方案,曾与 Kubernetes 展开激烈竞争:
| 易用性 | ⭐⭐⭐⭐⭐ 极其简单 | ⭐⭐⭐ 学习曲线陡峭 |
| 功能 | ⭐⭐⭐ 基础功能 | ⭐⭐⭐⭐⭐ 极其丰富 |
| 生态 | ⭐⭐ 有限 | ⭐⭐⭐⭐⭐ 极其丰富 |
| 扩展性 | ⭐⭐⭐ 中等 | ⭐⭐⭐⭐⭐ 万级节点 |
| 社区 | ⭐⭐ 缩小中 | ⭐⭐⭐⭐⭐ 活跃 |
| 云支持 | ⭐⭐ 有限 | ⭐⭐⭐⭐⭐ 全面 |
竞争结果:Kubernetes 在 2017-2018 年基本赢得了编排战争。Docker 在 2018 年的 Docker Enterprise 中也集成了对 Kubernetes 的支持。
6.4 Podman 与 Kubernetes 的天然契合
Podman 与 Kubernetes 之间有天然的亲和力:
1. 共同的运行时基础
Kubernetes ──> CRI ──> CRI-O ──> OCI Runtime (runc/crun)
Podman ─────────────────────> OCI Runtime (runc/crun)
两者都使用 OCI 标准运行时,共享相同的容器技术基础。
2. Pod 概念的一致性
# Podman 中的 Pod
$ podman pod create –name myapp
$ podman run –pod myapp –name web nginx
$ podman run –pod myapp –name cache redis
# 等价的 Kubernetes YAML
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
– name: web
image: nginx
– name: cache
image: redis
3. YAML 互转
# 从 Podman Pod 生成 Kubernetes YAML
$ podman generate kube myapp > myapp.yaml
# 从 Kubernetes YAML 创建 Podman Pod
$ podman play kube myapp.yaml
第七部分:容器生态全景
7.1 容器运行时
容器运行时是容器技术栈的最底层,负责容器的实际运行。
7.1.1 高级运行时(High-Level Runtime)
| containerd | Docker(后捐赠给 CNCF) | 最流行的容器运行时,Kubernetes 默认使用 |
| CRI-O | Red Hat | 专为 Kubernetes 设计的轻量级运行时 |
| podman | Red Hat | 无守护进程的容器引擎 |
7.1.2 低级运行时(Low-Level Runtime / OCI Runtime)
| runc | Docker(后捐赠给 OCI) | OCI 参考实现,最广泛使用 |
| crun | Red Hat | C 语言实现,比 runc 更快,Podman 默认使用 |
| gVisor (runsc) | 应用内核,提供额外的隔离层 | |
| Kata Containers | Intel/蚂蚁金服 | 轻量级虚拟机容器,硬件级隔离 |
| Firecracker | Amazon | 微虚拟机,用于 AWS Lambda |
| Nabla Containers | IBM | 基于 unikernel 的容器 |
┌──────────────────────────────────────────────────┐
│ 容器运行时层次结构 │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ High-Level Runtime (容器管理) │ │
│ │ containerd / CRI-O / podman │ │
│ └──────────────────┬──────────────────────────┘ │
│ │ │
│ ┌──────────────────┴──────────────────────────┐ │
│ │ OCI Runtime (容器执行) │ │
│ │ runc / crun / gVisor / Kata │ │
│ └──────────────────┬──────────────────────────┘ │
│ │ │
│ ┌──────────────────┴──────────────────────────┐ │
│ │ Linux Kernel │ │
│ │ Namespaces + Cgroups + Seccomp + SELinux │ │
│ └─────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘
7.2 容器镜像与仓库
7.2.1 镜像规范
容器镜像由多个只读层组成,遵循 OCI 镜像规范:
镜像结构:
├── manifest.json # 镜像清单,描述层和配置
├── config.json # 镜像配置(环境变量、CMD等)
├── layer1.tar.gz # 基础系统层
├── layer2.tar.gz # 安装依赖层
└── layer3.tar.gz # 应用代码层
7.2.2 主要镜像仓库
| Docker Hub | 公共 | 最大的容器镜像仓库 |
| GitHub Container Registry (ghcr.io) | 公共/私有 | GitHub 集成 |
| Quay.io | 公共/私有 | Red Hat 运营 |
| Google Container Registry | 云服务 | GCP 集成 |
| Amazon ECR | 云服务 | AWS 集成 |
| Azure Container Registry | 云服务 | Azure 集成 |
| Harbor | 私有部署 | CNCF 项目,企业级 |
| Nexus | 私有部署 | 企业制品仓库 |
7.3 容器构建工具
| Docker Build | Docker Inc. | 最流行的镜像构建工具 |
| Buildah | Red Hat | 无需 Daemon,支持 rootless |
| Kaniko | 在 K8s Pod 内构建镜像,无需 Docker Daemon | |
| BuildKit | Docker/Moby | Docker 的底层构建引擎,支持并行构建 |
| Bazel | 高性能构建系统,支持容器镜像 | |
| ko | 专为 Go 应用设计的容器构建工具 | |
| Jib | Java 应用的容器构建工具 | |
| Cloud Native Buildpacks | CNCF | 自动将源代码转换为容器镜像 |
7.4 容器安全工具
| Trivy | 容器镜像漏洞扫描(Aqua Security) |
| Clair | 容器镜像静态分析(CoreOS/Quay) |
| Anchore | 容器镜像分析和策略执行 |
| Snyk | 容器依赖漏洞检测 |
| Docker Scout | Docker 官方的安全扫描服务 |
| Falco | 运行时安全监控(CNCF 毕业项目) |
| Sysdig | 容器安全和监控 |
| Notary / Cosign | 镜像签名和验证 |
7.5 容器监控与日志
| Prometheus | 容器指标收集和告警(CNCF 毕业项目) |
| Grafana | 可视化监控面板 |
| Fluentd | 统一日志收集(CNCF 毕业项目) |
| ELK Stack | Elasticsearch + Logstash + Kibana 日志方案 |
| Jaeger | 分布式追踪(CNCF 毕业项目) |
| cAdvisor | Google 的容器资源监控工具 |
| Datadog | 商业容器监控方案 |
| New Relic | 商业 APM 和容器监控 |
第八部分:现代容器技术的前沿趋势
8.1 WebAssembly (Wasm) 容器
8.1.1 Wasm 的崛起
WebAssembly 最初是为浏览器设计的二进制格式,但正在向服务端扩展,成为容器技术的新方向。
Solomon Hykes(Docker 创始人)在 2019 年的推文:
“If WASM+WASI existed in 2008, we wouldn’t have needed to create Docker. That’s how important it is. WebAssembly on the server is the future.”
“如果 WASM+WASI 在 2008 年就存在,我们就不需要创建 Docker 了。它就是这么重要。服务器端的 WebAssembly 就是未来。”
8.1.2 Wasm vs 传统容器
| 启动时间 | 秒级 | 毫秒级 |
| 镜像大小 | MB-GB 级 | KB-MB 级 |
| 安全沙箱 | Namespace + Cgroup | 沙箱执行环境 |
| 跨平台 | 仅 Linux(主要) | 跨平台 |
| 语言支持 | 所有语言 | 支持多种语言 |
| 生态成熟度 | 非常成熟 | 快速发展中 |
8.1.3 Containerd 的 Wasm 支持
containerd 从 1.6 版本开始支持 Wasm 运行时(runwasi),这意味着 Kubernetes 可以同时运行 Linux 容器和 Wasm 容器:
┌─────────────────────────────────────────┐
│ containerd │
│ │
│ ┌─────────────┐ ┌─────────────────┐ │
│ │ shim-runc-v2│ │ shim-wasmedge │ │
│ │ (Linux容器) │ │ (Wasm容器) │ │
│ └─────────────┘ └─────────────────┘ │
└─────────────────────────────────────────┘
Wasm 运行时:
- Wasmtime:Mozilla/Fastly 开发的运行时
- WasmEdge:CNCF 项目,面向边缘计算
- Wasmer:通用 Wasm 运行时
- Spin:Fermyon 的 Wasm 微服务框架
8.2 无根容器(Rootless Containers)
8.2.1 为什么需要无根容器
传统容器以 root 权限运行存在严重安全风险:
传统容器安全威胁模型:
┌──────────────────────┐
│ Container │ ← 如果被攻破
│ (root 用户) │
├──────────────────────┤
│ Kernel Features │ ← Namespace Escape
│ (namespace/cgroup) │
├──────────────────────┤
│ Host System │ ← 获得 root 权限!
│ (root) │ 完全控制宿主机
└──────────────────────┘
无根容器通过 User Namespace 将容器内的 root 映射到宿主机的普通用户:
无根容器安全模型:
┌──────────────────────┐
│ Container │ ← 即使被攻破
│ (root 用户, UID 0) │
├──────────────────────┤
│ User Namespace │ ← UID 映射
│ (root -> 普通用户) │
├──────────────────────┤
│ Host System │ ← 只有普通用户权限
│ (user, UID 1000) │ 影响有限
└──────────────────────┘
8.2.2 无根容器的现状
| Podman | ✅ 默认支持 | 生产就绪 |
| Docker | ✅ 手动配置(v20.10+) | 基本可用 |
| containerd | ✅ 支持 | 进展中 |
| CRI-O | ✅ 支持 | 进展中 |
8.3 不可变基础设施
8.3.1 概念
不可变基础设施(Immutable Infrastructure)的核心思想是:一旦部署,就不再修改。需要更新时,用新的镜像替换旧的,而不是在原地修改。
传统方式(可变基础设施):
服务器 A ──> 部署 v1 ──> 打补丁 ──> 修改配置 ──> 升级 v2
(状态难以追踪,"配置漂移"问题)
不可变方式:
镜像 v1 ──> 部署到服务器 A
镜像 v2 ──> 部署到服务器 B ──> 流量切换 ──> 销毁服务器 A
(每次部署都是全新的、可预测的)
8.3.2 相关技术
| Container Linux (CoreOS) | 专为容器设计的不可变操作系统 |
| Flatcar Container Linux | CoreOS 的继任者 |
| Fedora CoreOS | Red Hat 的不可变容器操作系统 |
| Ubuntu Core | Ubuntu 的不可变版本 |
| Talos Linux | 专为 Kubernetes 设计的不可变 OS |
| NixOS | 函数式声明式操作系统 |
8.4 eBPF 与容器可观测性
8.4.1 eBPF 简介
eBPF(Extended Berkeley Packet Filter)是 Linux 内核的一项革命性技术,允许在内核中安全地运行沙箱程序,无需修改内核源码或加载内核模块。
8.4.2 eBPF 在容器领域的应用
| Cilium | 容器网络和安全 | 基于 eBPF 的 CNI 插件 |
| Falco | 运行时安全 | 利用 eBPF 进行系统调用监控 |
| Pixie | 可观测性 | 自动收集容器遥测数据 |
| Tetragon | 安全可观测 | Cilium 团队的安全监控工具 |
| Hubble | 网络可观测 | Cilium 的网络可视化工具 |
8.5 机密容器(Confidential Containers)
机密容器旨在保护容器中的数据不被宿主机、云提供商甚至操作系统内核访问:
| AMD SEV | AMD | CPU 级别的内存加密 |
| Intel SGX | Intel | 应用级安全飞地 |
| Intel TDX | Intel | 虚拟机级信任域 |
| ARM CCA | ARM | 机密计算架构 |
| Kata Containers | 开源社区 | 基于虚拟机的容器隔离 |
| Confidential Containers (CoCo) | CNCF | K8s 原生的机密容器 |
8.6 边缘计算与容器
容器技术正在从云端向边缘延伸:
| K3s | 轻量级 Kubernetes(<100MB),Rancher 开发 |
| KubeEdge | Kubernetes 原生边缘计算框架(CNCF) |
| MicroK8s | Canonical 的轻量级 K8s |
| WasmEdge | 面向边缘的 Wasm 运行时 |
| OpenYurt | 阿里巴巴的边缘计算框架 |
| Akri | 微软的边缘设备发现和管理 |
8.7 容器与 AI/ML 的融合
8.7.1 GPU 容器
# 使用 NVIDIA Container Toolkit 运行 GPU 容器
$ docker run –gpus all nvidia/cuda:12.0-base nvidia-smi
# Podman 也支持 GPU
$ podman run –device nvidia.com/gpu=all nvidia/cuda:12.0-base nvidia-smi
8.7.2 AI/ML 容器平台
| NVIDIA NGC | GPU 优化的 AI/ML 容器镜像仓库 |
| Kubeflow | Kubernetes 上的 ML 工作流平台 |
| MLflow | ML 生命周期管理 |
| Ray | 分布式 AI 计算框架 |
| KServe | K8s 上的模型服务 |
第九部分:新手实践指南
9.1 选择 Docker 还是 Podman?
建议决策流程:
你的需求是什么?
│
├── 学习容器技术入门 ──────> Docker(资料更多,社区更大)
│
├── 生产环境部署 ──────────> 根据已有技术栈选择
│ ├── 已有 RHEL/Fedora ─> Podman
│ ├── 使用 Kubernetes ──> 两者都可以(建议 Podman)
│ └── 一般 Linux ───────> 两者都可以
│
├── 安全要求高 ────────────> Podman(Rootless 更成熟)
│
├── 企业环境 ─────────────> Podman(无许可问题)
│
└── CI/CD 环境 ───────────> 都可以(建议 Buildah/Podman)
总结建议:
| 初学者入门 | Docker(学习资料更丰富) |
| 安全优先 | Podman(Rootless 原生支持) |
| 企业生产 | Podman(无许可风险,RHEL 默认) |
| 开发环境 | 都可以(Podman Desktop 或 Docker Desktop) |
| Kubernetes | Podman(与 K8s 更契合) |
9.2 环境搭建
9.2.1 Docker 安装
# Ubuntu/Debian
$ curl -fsSL https://get.docker.com | sh
$ sudo usermod -aG docker $USER
$ newgrp docker
# macOS: 下载 Docker Desktop
# https://www.docker.com/products/docker-desktop/
# Windows: 下载 Docker Desktop
# 需要 WSL2 支持
9.2.2 Podman 安装
# Ubuntu 22.04+
$ sudo apt update
$ sudo apt install podman
# Fedora/RHEL
$ sudo dnf install podman
# macOS
$ brew install podman
$ podman machine init
$ podman machine start
# Windows
# 下载 Podman Desktop
# https://podman-desktop.io/
# 或使用 WSL2
$ sudo apt install podman
9.3 从零开始的第一个容器
9.3.1 Hello World
# Docker
$ docker run hello-world
# Podman
$ podman run hello-world
9.3.2 运行 Nginx Web 服务器
# Docker
$ docker run -d -p 8080:80 –name myweb nginx
$ curl http://localhost:8080
# Podman
$ podman run -d -p 8080:80 –name myweb nginx
$ curl http://localhost:8080
9.3.3 编写 Dockerfile
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install –no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello from Container!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
# requirements.txt
flask==3.0.0
# 构建镜像
$ docker build -t myapp:v1 .
# 或
$ podman build -t myapp:v1 .
# 运行容器
$ docker run -d -p 5000:5000 myapp:v1
# 或
$ podman run -d -p 5000:5000 myapp:v1
9.3.4 Docker Compose / Podman Compose
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
– "5000:5000"
depends_on:
– redis
environment:
– REDIS_HOST=redis
redis:
image: redis:7–alpine
ports:
– "6379:6379"
# Docker Compose
$ docker-compose up -d
$ docker-compose ps
$ docker-compose logs -f
$ docker-compose down
# Podman Compose
$ pip install podman-compose
$ podman-compose up -d
$ podman-compose ps
$ podman-compose down
9.4 学习路径建议
初级阶段(1-2 周):
├── 理解容器 vs 虚拟机的概念
├── 学会基本的容器操作(run, ps, stop, rm)
├── 学会基本的镜像操作(pull, images, build)
├── 编写简单的 Dockerfile
└── 使用 Docker Compose 管理多容器应用
中级阶段(2-4 周):
├── 理解镜像分层和存储原理
├── 学习网络和卷管理
├── 理解容器安全(rootless, seccomp, SELinux)
├── 学习多阶段构建优化镜像大小
├── 了解 Podman 与 Docker 的差异
└── 学习容器镜像仓库(Docker Hub, Harbor)
高级阶段(1-3 月):
├── 学习 Kubernetes 基础
├── 理解 CRI, CNI, CSI 接口
├── 学习容器监控和日志方案
├── 了解 CI/CD 中的容器化最佳实践
├── 学习容器安全扫描和策略执行
└── 理解服务网格(Istio, Linkerd)
专家阶段(持续学习):
├── eBPF 和容器可观测性
├── WebAssembly 容器
├── 机密计算容器
├── 边缘计算与容器
└── 容器化 AI/ML 工作负载
推荐学习资源:
| Docker 官方文档 | 文档 | https://docs.docker.com |
| Podman 官方文档 | 文档 | https://podman.io/docs |
| Kubernetes 官方文档 | 文档 | https://kubernetes.io/docs |
| Play with Docker | 在线实验 | https://labs.play-with-docker.com |
| Docker Hub | 镜像仓库 | https://hub.docker.com |
| CNCF Landscape | 生态全景 | https://landscape.cncf.io |
| KodeKloud | 视频课程 | https://kodekloud.com |
第十部分:总结与展望
容器技术的发展脉络
1979 chroot
│
2000 FreeBSD Jails
│
2001 Linux VServer
│
2005 OpenVZ
│
2006 Google Cgroups
│
2008 LXC ──────────────────────────────┐
│ │
2013 Docker 发布 ←─────────────────────┘
│
2014 Rocket (rkt) 出现
│
2015 OCI 标准化 / Kubernetes 1.0
│
2016 containerd 独立
│
2017 CRI-O / Podman 开始开发
│
2018 Kubernetes 赢得编排之战
│
2019 Docker Enterprise 被收购
│
2020 Wasm 容器兴起
│
2021 Podman Desktop / eBPF 容器工具
│
2022 机密容器 / 边缘容器
│
2023 Podman 被主流框架优先推荐
│
2024 Wasm + Linux 容器混合运行
│
未来 AI 驱动的智能容器管理 / 自愈容器集群
核心要点回顾
Docker 是容器技术的普及者,但不是发明者。它让容器技术从少数人使用变成了开发者必备技能。
OCI 标准化 是容器技术最重要的里程碑之一,它确保了不同工具之间的互操作性。
Podman 代表了容器技术的进化方向:无守护进程、rootless 优先、与 Kubernetes 天然兼容。
容器技术正在从云端向边缘延伸,轻量级运行时和 WebAssembly 容器将发挥越来越重要的作用。
安全将成为容器技术的核心关注点,rootless 容器、机密容器、eBPF 安全监控等技术将持续发展。
AI/ML 工作负载正在推动容器技术的 GPU 支持和大规模调度能力。
最后的建议
对于新手来说,最重要的是动手实践。容器技术的核心概念并不复杂:
选择 Docker 或 Podman 作为起点都可以,它们的基本概念和操作几乎完全相同。掌握了基础之后,再逐步深入了解安全、网络、编排等高级主题。





