容器技术进化链路
容器技术的发展其实像一条很有意思的“进化链”,每一代技术都试图解决上一代的局限。不是简单替代,而是叠加能力。
一、chroot(1979)— 最原始的“假根目录”
chroot
最早出现在 Unix V7。
核心思想非常朴素:
让一个进程看到的
/根目录变成另一个目录。
换句话说:
真实系统
/
chroot /tmp/rootfs后
/tmp/rootfs -> /
运行效果:
1 | chroot /opt/container_root /bin/bash |
进程看到的世界:
/
├── bin
├── lib
└── etc
但现实是安全性几乎没有。
原因:
- 没有 PID 隔离
- 没有网络隔离
- 没有资源限制
- root 可以逃逸
所以很多人调侃:
chroot 不是容器,只是“换个目录玩”。
二、Jail(2000)— 第一次真正隔离
FreeBSD Jail来自 FreeBSD这是一个巨大进步。
Jail 在 chroot 基础上增加:
| 隔离 | 说明 |
|---|---|
| 进程 | PID 隔离 |
| 网络 | 独立 IP |
| 文件系统 | 独立 root |
| 权限 | 限制 root |
简单理解:
Host
├─ Jail A
│ └─ nginx
└─ Jail B
└─ mysql
但仍然缺:
- 资源限制
- namespace 完整隔离
不过 Jail 的思想影响了整个容器世界。
三、LXC(2008)— Linux 原生容器
LXC Linux 社区把多个内核能力组合在一起:
namespace + cgroup + chroot
于是诞生了真正意义上的 Linux 容器。
核心组件:
| 技术 | 作用 |
|---|---|
| Namespace | 资源视图隔离 |
| Cgroup | 资源限制 |
| Capabilities | 权限削减 |
| AppArmor/SELinux | 安全 |
容器结构:
flowchart TD
A[Linux Kernel]
A --> B[Namespaces]
A --> C[Cgroups]
A --> D[Capabilities]
B --> E[LXC Container]
C --> E
D --> E
E --> F[init]
F --> G[Services]
LXC 的理念:
容器 = 轻量级虚拟机
所以它可以运行:
- systemd
- sshd
- 完整 Linux
四、Docker(2013)— 容器真正爆发
Docker 并没有发明容器。Docker 做了三件革命性的事情:
1 镜像分层
Image
├─ Layer1
├─ Layer2
└─ Layer3
好处:
- 共享层
- 快速分发
2 Dockerfile
软件第一次可以这样描述:
FROM ubuntu
RUN apt install nginx
COPY app /
基础设施第一次变成代码。
3 Docker Hub
软件分发像 npm 一样简单:
docker pull nginx
容器从运维工具变成:
开发工具
五、containerd(2017)— 容器运行时拆分
Docker 最初架构很大:
Docker Engine
├─ API
├─ Image
├─ Network
└─ Runtime
后来社区提出:runtime 应该独立。 于是 Docker 拆分:
Docker
↓
containerd
↓
runc
结构:
flowchart TD
A[Kubernetes / Docker]
A --> B[containerd]
B --> C[runc]
C --> D[Linux Kernel]
注意:内核是宿主机系统的内核
六、Kubernetes(2014)— 容器操作系统
Google 把内部系统 Borg 的理念开源。
Kubernetes 解决的是:
“一万台机器跑容器怎么办?”
它负责:
| 功能 | 说明 |
|---|---|
| 调度 | Pod 放哪 |
| 自愈 | 容器挂了重启 |
| 扩缩容 | 自动扩容 |
| 服务发现 | service |
| 滚动升级 | 无停机部署 |
架构:
flowchart TD
A[Kubernetes API]
A --> B[Scheduler]
A --> C[Controller]
A --> D[etcd]
B --> E[Node1]
B --> F[Node2]
E --> G[containerd]
F --> H[containerd]
G --> I[runc]
H --> J[runc]
七、容器技术完整演化
把整个技术链放一起就很清晰:
flowchart LR
A[chroot 1979]
B[Jail 2000]
C[LXC 2008]
D[Docker 2013]
E[containerd 2017]
F[Kubernetes]
A --> B
B --> C
C --> D
D --> E
E --> F
每一步解决的问题:
| 技术 | 解决问题 |
|---|---|
| chroot | 文件隔离 |
| jail | 基础安全隔离 |
| LXC | Linux 原生容器 |
| Docker | 软件分发 |
| containerd | 运行时标准 |
| Kubernetes | 集群管理 |
八、一个非常反直觉的事实
很多人不知道:今天 Kubernetes 运行容器,其实只依赖 两个东西:
OCI runtime
Linux kernel
OCI runtime 就是:runc
所以现代容器的最小栈其实是:
Kubernetes
↓
containerd
↓
runc
↓
Linux namespace + cgroup
而这套机制的核心,其实还是 2006 年 Linux namespace 的设计。