一. 引言:?
??大家都知道,在一臺機器上,可以運行任意(根據系統資源)個容器實例。且各容器間是相互獨立,不做任何關聯的。那么,docker是通過什么方式來實現容器隔離的呢? 接下來我們了解下。
二. 關于容器隔離機制:
? ?容器的隔離機制是實現 “輕量級虛擬化” 的核心,通過Linux 內核原生技術與容器運行時(如 docker、containerd)的封裝,在共享宿主機內核的同時,為每個容器提供獨立的資源、網絡、文件系統等環境,避免容器間相互干擾。其本質是 “在同一內核中為進程組劃定資源與權限邊界”,而非像虛擬機那樣完全隔離操作系統。
? ?主要分為一下三個大方向:?
Namespace ?可實現容器間的隔離
Cgroups ? ?可限制容器的資源使用
Chroot ? ? 文件系統的隔離(掛載到物理根目錄(文件系統)下的子目錄(虛擬文件系統))
?1. 關于namespace:
?? ?Linux 內核從版本 2.4.19 開始陸續引入了 namespace 的概念。其目的是將某個特定的全局系統資源(global system resource)通過抽象方法使得namespace 中的進程看起來擁有它們自己的隔離的全局系統資源實例。Linux 內核中實現了六種 namespace,按照引入的先后順序,列表如下:
namespace | 引入的相關內核版本 | 被隔離的全局系統資源 | 在容器語境下的隔離效果 |
---|---|---|---|
Mount? | Linux 2.4.19 | 文件系統掛接點 | 每個容器能看到不同的文件系統層次結構 |
?UTS? | Linux 2.6.19 | 主機名和域名 | 每個容器可以有自己的 hostname 和 domainame |
IPC? | Linux 2.6.19 | System V IPC:消息隊列,信號量,共享內存 | 每個容器有其自己的?System V IPC 和消息隊列文件系統,因此,只有在同一個 IPC namespace 的進程之間才能互相通信 |
PID? | Linux 2.6.24 | 進程?ID(編號)? | 每個 PID namespace 中的進程可以有其獨立的 PID; 每個容器可以有其 PID 為 1 的root 進程;也使得容器可以在不同的 host 之間遷移,因為 namespace 中的進程 ID 和 host 無關了。這也使得容器中的每個進程有兩個PID:容器中的 PID 和 host 上的 PID。 |
Network? | 始于Linux 2.6.24 完成于 Linux 2.6.29 | 網絡相關的系統資源 | 每個容器用有其獨立的網絡設備,IP 地址,IP 路由表,/proc/net 目錄,端口號等等。這也使得一個 host 上多個容器內的同一個應用都綁定到各自容器的 80 端口上。 |
User? | 始于 Linux 2.6.23 完成于 Linux 3.8) | 用戶和組 ID 空間 | ?在 user namespace 中的進程的用戶和組 ID 可以和在 host 上不同;?每個 container 可以有不同的 user 和 group id;一個 host 上的非特權用戶可以成為 user namespace 中的特權用戶; ? |
Linux內核實現namespace的主要目的就是為了實現輕量級虛擬化(容器)服務。在同一個namespace下的進程可以感知彼此的變化,而對外界的進程一無所知。這樣就可以讓容器中的進程產生錯覺,仿佛自己置身于一個獨立的系統環境中,以此達到獨立和隔離的目的。
2.?Cgroups:
? ?容器通過namespace機制實現了環境上的隔離。但只有運行環境隔離還不夠,因為這些進程還是可以不受限制地使用系統資源,比如網絡、磁盤、CPU以及內存 等。一方面,是為了防止它占用了太多的資源而影響到其它進程;另一方面,在系統資源耗盡的時候,linux 內核會觸發 OOM,這會讓一些被殺掉的進程成了無辜的替死鬼。因此,為了讓容器中的進程更加可控,Docker 使用 Linux cgroups 來限制容器中的進程允許使用的系統資源。?
?Linux Cgroup 可為系統中所運行任務(進程)的用戶定義組群分配資源 — 比如 CPU 時間、系統內存、網絡帶寬或者這些資源的組合。可以監控您配置的 cgroup,拒絕 cgroup 訪問某些資源,甚至在運行的系統中動態配置您的 cgroup。它以一組進程為目標進行系統資源分配和控制。
它主要提供了以下功能:
Resource limitation: 限制資源使用,比如內存使用上限以及文件系統的緩存限制。
Prioritization: 優先級控制,比如:CPU利用和磁盤IO吞吐。
Accounting: 資源統計,一些審計或一些統計,主要目的是為了計費。
Control: 進程控制,掛起進程,恢復執行進程。
使用 cgroup,系統管理員可更具體地控制對系統資源的分配、優先順序、拒絕、管理和監控。可更好地根據任務和用戶分配硬件資源,提高總體效率。在實際中,系統管理員一般會利用CGroup做下面這些事:
隔離一個進程集合(比如:nginx的所有進程),并限制他們所消費的資源,比如綁定CPU的核。
為這組進程分配其足夠使用的內存
為這組進程分配相應的網絡帶寬和磁盤存儲限制
限制訪問某些設備(通過設置設備的白名單)
? 3.?Chroot:?
? ??是容器的 “獨立文件系統根目錄”,通過分層掛載(UnionFS)?實現,核心作用是:
1. 隔離性:容器內的/目錄與宿主機完全獨立,修改容器內文件(如/etc/passwd)不會影響宿主機。
2. 輕量性:采用 “基礎鏡像層 + 容器層” 的分層結構,多個容器可共享基礎鏡像層。
3. 一致性:每個容器啟動時都基于相同的基礎鏡像,確保運行環境一致(避免 “本地能跑,線上跑不了”)。
? 關鍵技術:?UnionFS(聯合文件系統)
??常用的 UnionFS 實現包括overlay2(Docker 默認)、aufs、btrfs等,以overlay2為例,其分層結構如下:
lowerdir:基礎鏡像層(可多層,如 “操作系統層 + Nginx 層”),僅可讀;
upperdir:容器層,容器運行時的所有寫操作(如創建 / 修改文件)都在這一層;
merged:容器內看到的 “根目錄”,是lowerdir和upperdir的聯合掛載結果;
workdir:臨時工作目錄,用于 UnionFS 的內部操作(用戶不可見)。
三. 容器隔離 vs 虛擬機隔離:?
對比維度 | 容器 | 虛擬機 |
---|---|---|
隔離核心 | 共享宿主機內核,通過 namespace/cgroup 隔離進程 | 完全隔離操作系統(含內核),通過 hypervisor 虛擬化硬件 |
資源開銷 | 輕量(MB 級內存,秒級啟動),共享宿主機資源 | 重量級(GB 級內存,分鐘級啟動),每個 vm 需獨立分配資源 |
安全性 | 較弱(共享內核,存在 “內核漏洞突破隔離” 風險) | 較強(完全隔離內核,VM 內攻擊難以影響宿主機) |
兼容性 | 依賴宿主機內核版本(如容器內無法運行與宿主機內核不兼容的程序) | 兼容性強(VM 內可運行任意操作系統,與宿主機內核無關) |
四. 無法隔離的資源:?
- 內核版本:容器內的內核版本與宿主機完全一致,無法在容器內升級內核;
- 內核模塊:容器無法加載 / 卸載宿主機內核模塊(需宿主機提前加載);
- 系統時間:默認情況下,容器內修改系統時間會同步修改宿主機時間。
- 硬件資源:部分硬件資源(如 CPU 緩存、NUMA 節點)無法精細隔離,可能存在 “緩存側信道攻擊” 風險;
- 內核漏洞:若宿主機內核存在漏洞(如 Dirty COW),容器內的惡意進程可能利用漏洞突破隔離,獲取宿主機權限。
- ?--------------------------------------------------------------------------------------------------------------------------
? ? ? ? ? ? ? ? ? ? ? ? ?深耕運維行業多年,擅長運維體系建設,方案落地。歡迎交流!
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?“V-x”: ywjw996
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?《 運維經緯 》
?