作者:燒雞太子爺
來源:恒生LIGHT云社區
背景
最近在給組內新人講解一些docker容器化,大家都能夠理解,docker容器實際上就是運行的一個進程,只不過由于docker幫助我們包裝了這個進程,給這個進程加以一個可運行的微linux環境而已,讓我們感覺看起來"像"虛擬機而已。那么他是如何做到資源控制的呢,大家也都知道是用了namespace、cgroup。個人也比較好奇,所以也花了一點時間去學習了一下,也做一些筆記,可以和大家一起學習一下
Linux namespace
Linux namespace 是一種內核級別的資源隔離機制,用來讓運行在同一個操作系統上的進程互相不會干擾。
namespace 目的就是隔離,要做到的效果是:如果某個 namespace 中有進程在里面運行,它們只能看到該 namespace 的信息,無法看到 namespace 以外的東西。
我們來想一下:一個進程在運行的時候,它會知道哪些信息?
- 看到系統的 hostname
- 可用的網絡資源(bridge、interface、網絡端口的時候情況……)
- 進程的關系(有哪些進程,進程之間的父子關系等)、
- 系統的用戶信息(有哪些用戶、組,它們的權限是怎么樣的)
- 文件系統(有哪些可用的文件系統,使用情況)
- IPC(怎么實現進程間通信)
- …… 也就是說,如果要實現隔離,必須保證不同 namespace 中進程看到的上面這些東西是不同的。
如果讓我來做,首先的想法是每個 namespace 都實現一整套上述資源的隔離,但是實際上 linux 的實現中,上述的所有資源都是可以多帶帶隔離的。
目前 linux 內核主要實現了一下幾種不同的資源 namespace,官網有如下介紹:
名稱 | 宏定義 | 宏定義 |
---|---|---|
IPC | CLONE_NEWIPC | System V IPC, POSIX message queues (since Linux 2.6.19) |
Network | CLONE_NEWNET | network device interfaces, IPv4 and IPv6 protocol stacks, IP routing tables, firewall rules, the /proc/net and /sys/class/net directory trees, sockets, etc (since Linux 2.6.24) |
Mount | CLONE_NEWNS | Mount points (since Linux 2.4.19) |
PID | CLONE_NEWPID | Process IDs (since Linux 2.6.24) |
User | CLONE_NEWUSER | User and group IDs (started in Linux 2.6.23 and completed in Linux 3.8) |
UTS | CLONE_NEWUSER | Hostname and NIS domain name (since Linux 2.6.19) |
Cgroup | CLONE_NEWCGROUP | Cgroup root directory (since Linux 4.6) |
這些 namespace 基本上覆蓋了一個程序運行所需的環境,保證運行在的隔離的 namespace 中的,會讓程序不會受到其他收到 namespace 程序的干擾。但不是所有的系統資源都能隔離,時間就是個例外,沒有對應的 namespace,因此同一臺 Linux 啟動的容器時間都是相同的。
但是Namespace解決的問題主要是環境隔離的問題,這只是虛擬化中最最基礎的一步,我們還需要解決對計算機資源使用上的隔離。也就是說,雖然你通過Namespace把我加到一個特定的環境中去了,但是我在其中的進程使用用CPU、內存、磁盤等這些計算資源其實還是可以隨心所欲的。所以,我們希望對進程進行資源利用上的限制或控制。這就是Linux CGroup出來了的原因。
Linux cgroup
Linux CGroup全稱Linux Control Group, 是Linux內核的一個功能,用來限制,控制與分離一個進程組群的資源(如CPU、內存、磁盤輸入輸出等)。
Linux CGroupCgroup 可讓您為系統中所運行任務(進程)的用戶定義組群分配資源 — 比如 CPU 時間、系統內存、網絡帶寬或者這些資源的組合。您可以監控您配置的 cgroup,拒絕 cgroup 訪問某些資源,甚至在運行的系統中動態配置您的 cgroup。
它主要提供了如下功能:
- Resource limitation: 限制資源使用,比如內存使用上限以及文件系統的緩存限制。
- Prioritization: 優先級控制,比如:CPU利用和磁盤IO吞吐。
- Accounting: 一些審計或一些統計,主要目的是為了計費。
- Control: 掛起進程,恢復執行進程。 使用 cgroup,系統管理員可更具體地控制對系統資源的分配、優先順序、拒絕、管理和監控。可更好地根據任務和用戶分配硬件資源,提高總體效率。
cgroups 的作用:
- 資源限制
cgroups可以對任務使用的資源(內存,CPU,磁盤等資源)總額進行限制。 如 設定應用運行時使用的內存上限,一旦超過配額就發出OOM提示 - 優先級分配
通過分配的CPU時間片數量以及磁盤IO帶寬大小,實際上就相當于控制了任務運行的優先級 - 資源統計
cgroups可以統計系統的資源使用量 如CPU使用時長,內存用量等,這個功能非常適用于計費 - 任務控制
cgroups 可以對任務進行掛起、恢復等操作
總結
Docker容器的本質是宿主機上的一個進程。Docker通過namespace實現了資源隔離,通過cgroups實現了資源限制。 namespace技術實際上修改了應用進程看待整個計算機“視圖”,即它的“視線”被操作系統做了限制,只能“看到”默寫指定的內容,而這個進程能夠使用的資源量,則受cgroup配置的限制,但對于宿主機來說,這些被隔離和限制了的進程和其他進程并沒有太大的區別。
另外,namespace和cgroup雖然已經做的很好了,但是他們還是有很多不完善的地方,比如做不到時間的隔離,比如/proc文件系統的問題,這些后面有時間也可以和大家一起討論一下,本章不做具體的介紹了。