天天看點

實作容器的底層技術 - 每天5分鐘玩轉 Docker 容器技術(30)

為了更好地了解容器的特性,本節我們将讨論容器的底層實作技術。

cgroup 和 namespace 是最重要的兩種技術。cgroup 實作資源限額, namespace 實作資源隔離。

cgroup 全稱 Control Group。Linux 作業系統通過 cgroup 可以設定程序使用 CPU、記憶體 和 IO 資源的限額。相信你已經猜到了:前面我們看到的<code>--cpu-shares</code>、<code>-m</code>、<code>--device-write-bps</code> 實際上就是在配置 cgroup。

cgroup 到底長什麼樣子呢?我們可以在 /sys/fs/cgroup 中找到它。還是用例子來說明,啟動一個容器,設定 <code>--cpu-shares=512</code>:

檢視容器的 ID:

在 /sys/fs/cgroup/cpu/docker 目錄中,Linux 會為每個容器建立一個 cgroup 目錄,以容器長ID 命名:

目錄中包含所有與 cpu 相關的 cgroup 配置,檔案 cpu.shares 儲存的就是 <code>--cpu-shares</code> 的配置,值為 512。

同樣的,/sys/fs/cgroup/memory/docker 和 /sys/fs/cgroup/blkio/docker 中儲存的是記憶體以及 Block IO 的 cgroup 配置。

在每個容器中,我們都可以看到檔案系統,網卡等資源,這些資源看上去是容器自己的。拿網卡來說,每個容器都會認為自己有一塊獨立的網卡,即使 host 上隻有一塊實體網卡。這種方式非常好,它使得容器更像一個獨立的計算機。

Linux 實作這種方式的技術是 namespace。namespace 管理着 host 中全局唯一的資源,并可以讓每個容器都覺得隻有自己在使用它。換句話說,namespace 實作了容器間資源的隔離。

Linux 使用了六種 namespace,分别對應六種資源:Mount、UTS、IPC、PID、Network 和 User,下面我們分别讨論。

Mount namespace 讓容器看上去擁有整個檔案系統。

容器有自己的 <code>/</code> 目錄,可以執行 <code>mount</code> 和 <code>umount</code> 指令。當然我們知道這些操作隻在目前容器中生效,不會影響到 host 和其他容器。

簡單的說,UTS namespace 讓容器有自己的 hostname。 預設情況下,容器的 hostname 是它的短ID,可以通過 <code>-h</code> 或 <code>--hostname</code> 參數設定。

IPC namespace 讓容器擁有自己的共享記憶體和信号量(semaphore)來實作程序間通信,而不會與 host 和其他容器的 IPC 混在一起。

我們前面提到過,容器在 host 中以程序的形式運作。例如目前 host 中運作了兩個容器:

通過 <code>ps axf</code> 可以檢視容器程序:

所有容器的程序都挂在 dockerd 程序下,同時也可以看到容器自己的子程序。 如果我們進入到某個容器,<code>ps</code> 就隻能看到自己的程序了:

而且程序的 PID 不同于 host 中對應程序的 PID,容器中 PID=1 的程序當然也不是 host 的 init 程序。也就是說:容器擁有自己獨立的一套 PID,這就是 PID namespace 提供的功能。

Network namespace 讓容器擁有自己獨立的網卡、IP、路由等資源。我們會在後面網絡章節詳細讨論。

User namespace 讓容器能夠管理自己的使用者,host 不能看到容器中建立的使用者。

在容器中建立了使用者 cloudman,但 host 中并不會建立相應的使用者。

本章首先通過大量實驗學習了容器的各種操作以及容器狀态之間如何轉換,然後讨論了限制容器使用 CPU、記憶體和 Block IO 的方法,最後學習了實作容器的底層技術:cgroup 和 namespace。

下面是容器的常用操作指令:

create      建立容器  

run         運作容器  

pause       暫停容器  

unpause     取消暫停繼續運作容器  

stop        發送 SIGTERM 停止容器  

kill        發送 SIGKILL 快速停止容器  

start       啟動容器  

restart     重新開機容器  

attach      attach 到容器啟動程序的終端  

exec        在容器中啟動新程序,通常使用 "-it" 參數  

logs        顯示容器啟動程序的控制台輸出,用 "-f" 持續列印  

rm          從磁盤中删除容器

到這裡,我們已經學習完了容器章節。下一節開始讨論容器網絡。

本文轉自CloudMan6 51CTO部落格,原文連結:http://blog.51cto.com/cloudman/1939589

繼續閱讀