28 實現容器的底層技術

2022-08-20 14:03:15 字數 3023 閱讀 7089

為了更好地理解容器的特性,本節我們將討論容器的底層實現技術。

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

cgroup

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

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

檢視容器的 id:

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

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

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

namespace

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

linux 實現這種方式的技術是 namespace。namespace 管理著 host 中全域性唯一的資源,並可以讓每個容器都覺得只有自己在使用它。換句話說,namespace 實現了容器間資源的隔離

linux 使用了六種 namespace,分別對應六種資源:mount、uts、ipc、pid、network 和 user,下面我們分別討論。

mount namespace

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

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

uts namespace

簡單的說,uts namespace 讓容器有自己的 hostname。 預設情況下,容器的 hostname 是它的短id,可以通過-h--hostname引數設定。

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

pid namespace

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

通過ps axf可以檢視容器程序:

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

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

network namespace

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

user namespace

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

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

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

create      建立容器  

run         執行容器  

pause       暫停容器  

unpause     取消暫停繼續執行容器  

stop        傳送 sigterm 停止容器  

kill        傳送 sigkill 快速停止容器  

start       啟動容器  

restart     重啟容器  

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

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

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

rm          從磁碟中刪除容器

容器的底層實現與linux

程序組顧名思義,即是多個程序的集合。linux系統中每乙個程序都屬於乙個程序組,每乙個程序組都有唯一的乙個程序組標識號。1.當任意父程序呼叫fork 函式生成子程序時,子程序和父程序同屬於乙個程序組 2.每乙個程序組都有乙個組長程序,組長程序負責與其他程序組交換資料,但組長程序消亡,程序組並不會消失...

STL容器的區別及底層實現

在stl中基本容器有 vector list deque set map set 和map都是無序的儲存元素,只能通過它提供的介面對裡面的元素進行訪問 set 集合,用來判斷某乙個元素是不是在乙個組裡面,使用的比較少 map 對映,相當於字典,把乙個值對映成另乙個值,如果想建立字典的話使用它好了 底...

JAVA容器 模擬ArrayList的底層實現

arraylist實質上就是可變陣列的實現,著重理解 add get set remove iterator的實現,我們將關注一下問題。1 建立arraylist的時候,預設給陣列的長度設定為10。2 當set remove set的時候,如何解決越界問題?3 當add的時候,如何解決擴容問題?4 ...