7.2 cgroups、namespaces 與 LXC:利用核心隔離技術打造輕量級容器#
隔離需要回答的四個問題#
一台機器上跑多個互不信任的應用,核心必須回答:
Q1 你看得到什麼? → namespaces(視野隔離)
Q2 你能用多少資源? → cgroups(資源配額)
Q3 你的檔案在哪裡? → 聯合檔案系統(檔案系統視圖)
Q4 別人能碰你嗎? → 權限/安全模組(存取控制)
第一支柱:namespaces——「你的世界只有這些」#
Linux namespace 的思想源頭可追溯到 1979 年 Unix v7 的 chroot(改變行程的根目錄視圖)。Linux 核心逐步把「視圖隔離」系統化,每種 namespace 隔離一類資源的視野:
| Namespace | 隔離什麼 | 加入主線 |
|---|---|---|
| Mount (2002) | 檔案系統掛載點 | 2.4.19 |
| UTS (2006) | 主機名稱與域名 | 2.6.19 |
| IPC (2006) | System V IPC、訊息佇列 | 2.6.19 |
| PID (2008) | 程序編號空間(每個容器自己 PID 1) | 2.6.24 |
| Network (2008) | 網路堆疊(自己的網卡、路由、防火牆) | 2.6.24 |
| User (2012) | UID/GID 映射(容器內 root ≠ host root) | 3.5/3.8 |
| Cgroup (2016) | cgroup 視圖 | 4.6 |
本質:namespaces 讓同一顆核心為每個行程群組呈現「專屬的系統假象」。容器裡的程序以為自己是 PID 1、以為擁有整塊網路——這是另一場「幻覺」,只是舞台從硬體換成了核心。
第二支柱:cgroups——「你的配額只有這些」#
Control Groups 由 Google 工程師(Paul Menage、Rohit Seth 等)於 2006 年以「process containers」名義提出,2007 年併入核心 2.6.24。功能:把程序分組,對每組精確配額:
cgroups 能控制的資源(節選):
cpu :CPU 時間份額、core 綁定
memory :實體記憶體上限、swap 限制、OOM 優先序
blkio :磁碟 I/O 頻寬與 IOPS
devices :可存取的裝置白名單
pids :可建立的程序數上限(防 fork 炸彈)
net_cls :網路流量標記
namespaces 管「看得見什麼」,cgroups 管「用得掉多少」——視野與配額雙管齊下,才構成完整的資源隔離。
第三支柱:聯合檔案系統——「映像的分層魔法」#
容器的秒級啟動與小體積,靠聯合檔案系統(Union FS):
Docker 映像的分層結構(OverlayFS 範例):
┌────────────────────────────┐
│ 可寫層(容器執行時的修改) │ ← 每個容器獨有
├────────────────────────────┤
│ 層4:COPY config /etc/app/ │
│ 層3:RUN apt-get install … │ ← 各層唯讀、可共享
│ 層2:COPY . /app │
│ 層1:基礎映像 ubuntu:22.04 │
└────────────────────────────┘
唯讀層在所有容器間共享 → 100 個容器共用一份 ubuntu 基礎層
寫入時複製(Copy-on-Write):修改唯讀層的檔案時才複製到可寫層。這正是 VM 映像(整塊複製)與容器映像(分層共享)體積差異的根源。
第四支柱:LXC 與 Docker 的關係#
LXC(Linux Containers)(2008 前後,由 Daniel Lezcano 等人推動,IBM、Canonical 參與)是第一個把 cgroups+namespaces 包裝成易用介面的正規工具,讓「Linux 上的 Solaris Zones」成為現實。但 LXC 的使用者體驗仍偏系統管理員導向(建立一個「迷你系統」)。
Docker 的差異化在於哲學:
LXC:容器 ≈ 一台迷你的虛擬系統(跑 init、SSH、多服務)
Docker:容器 ≈ 一個行程的包裝(單一職責、可拋棄、immutable)
Docker 雖初期借用 LXC,2014 年起改用自己的 libcontainer
(後演進為開放的 runC 標準,成為 OCI 規範的基準實作)
「一容器一行程」的哲學直接塑造了後來 Kubernetes 的 Pod 模型與微服務架構的文化——工具的介面設計,最終決定了架構的形態。
標準化的政治:OCI 與 CNCF#
容器生態的爆發引發「一家公司掌控標準」的疑慮。2015 年,Docker、Google、Red Hat、微軟、AWS 等成立 OCI(Open Container Initiative),把映像格式與執行期介面標準化;同年 CNCF(Cloud Native Computing Foundation)成立,接管 Kubernetes。開放治理制度確保容器沒有重蹈單一廠商霸權的覆轍——這是科技史上少見的「先有霸權陰影、先行制度防禦」的案例。
歷史關聯:cgroups 出自 Google 的規模化需求,namespaces 源自 Unix 四十年的視圖隔離傳統,Docker 則是體驗層的集大成者。當所有支柱就緒,「隔離」的成本降到接近零,一場關於安全邊界的哲學辯論隨之而來。