2013 - Docker:把「機器」縮小成一個行程#
案件摘要#
2013 年,Solomon Hykes 在 PyCon 上展示 Docker——一個基於 LXC 的容器工具。它證明了:你不需要模擬硬體,只需用 Linux kernel 的 namespaces 與 cgroups,就能把一個「機器」縮小成一行 docker run。
前因 -- 為什麼會有這個案子#
- 系統虛擬機(VMware、KVM)模擬完整硬體,每台 VM 要帶一個客座作業系統:啟動以分鐘計、記憶體以 GB 計。
- 「在我的機器上能跑」(works on my machine) 是部署界的懸案——環境不一致。
- Linux 早有原料:chroot(1979)、jails(FreeBSD 2000)、LXC(2008),但沒人把它們包裝成好用的產品。dotCloud(PaaS 公司)內部專案 Docker 補上了這塊拼圖。
線索與推理 -- 數學式、程式、理論#
線索 1:OS 級虛擬化 vs 系統虛擬化對照表#
| 面向 | 系統虛擬化(VM) | OS 級虛擬化(容器) |
|---|---|---|
| 虛擬層 | hypervisor(模擬硬體) | 共用 host kernel |
| 每實例 OS | 完整客座 OS | 無,共用 kernel |
| 啟動時間 | 分鐘級(BIOS→boot→init) | 毫秒~秒級(直接 exec) |
| 記憶體開銷 | GB 級 | MB 級 |
| 隔離強度 | 強(硬體邊界) | 中(kernel 邊界) |
| 密度(單機實例數) | 十幾台 | 數百個 |
理論上,容器省去每台 VM 的 OS 開銷 \(M_{os}\) , \(n\) 個工作負載的總記憶體:
\[ M_{vm} = n(M_{os} + M_{app}), \qquad M_{container} = M_{os} + nM_{app} \]
密度提升比 \(\approx \dfrac{n(M_{os}+M_{app})}{M_{os}+nM_{app}}\) ,當 \(M_{os} \gg M_{app}\) 時趨近 \(n\) 倍以上。
線索 2:容器 = 隔離的行程群組#
容器不是「小型機器」,本質是一組被 namespace 隔離、被 cgroups 限量的普通行程。Docker 啟動容器約等於:
# Docker run 背後的核心操作(簡化版)
unshare --pid --net --mount --uts --ipc --fork /bin/sh # 1. namespaces 隔離
echo "cpu.max 50000 100000" > /sys/fs/cgroup/app/cpu.max # 2. cgroups 限量(0.5 CPU)
線索 3:映像檔分層(Layers 與 UnionFS)#
Docker 映像檔由唯讀層(layer)堆疊而成,容器寫入時在上層加一個可寫層(copy-on-write):
\[ \text{image} = L_1 + L_2 + \cdots + L_k, \qquad \text{container} = \text{image} + L_{rw} \]
UnionFS(AUFS、overlayfs2)把多層「合併」成一棵檔案樹。共用基底層(如同一個 ubuntu 基底)只存一份:
\[ \text{儲存總量} = |L_{base}| + \sum_i |L_i^{diff}| \ll n \cdot |image_{full}| \]
線索 4:Dockerfile 範例#
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "server.py"]
docker build -t myapp . # 每條指令 = 一層,並被快取
docker run -p 8000:8000 myapp # 毫秒級啟動
線索 5:chroot → jail → LXC → Docker 的演進#
\[ \text{chroot (1979)} \to \text{FreeBSD jail (2000)} \to \text{Solaris Zones (2004)} \to \text{LXC (2008)} \to \text{Docker (2013)} \]
chroot 只隔離檔案系統(易逃逸);jail 加入多重 namespace;LXC 提供完整容器工具但難用;Docker 加上映像檔格式 + Registry(Docker Hub)+ CLI,把容器變成可分發的「軟體貨櫃」。
線索 6:Kubernetes(2014)的誕生#
Docker 單機可用後,多機編排成為新案。Google 把內部 Borg 的經驗開源為 Kubernetes(2014):
\[ \text{K8s} = \text{排程(scheduler)} + \text{期望狀態(declarative)} + \text{控制迴圈(reconcile loop)} \]
kubectl scale deployment myapp --replicas=10
結案 -- 後果與影響#
- 容器啟動時間從 VM 的分鐘級降到毫秒級,微服務架構與 CI/CD 被徹底解放。
- Docker Hub 讓「映像檔」成為軟體分發的通用單位,等同一場部署界的標準化革命。
- 2014 年 Kubernetes 誕生,2015 年 CNCF 成立,直接鋪往雲端原生時代。
- Docker 公司本身後來式微,但「容器」的觀念已成為基礎設施的地基。
關鍵人物與文獻#
- Solomon Hykes:Docker 創辦人,2013 PyCon 演示者。
- 文獻:Kubernetes 官方文件;Docker: Lightweight Linux Containers for Consistent Development and Deployment (Merkel, LISA 2014);Linux kernel namespaces/cgroups 手冊。