Linux Cgroups(Linux Control Group)是 Linux 內核中用來爲進程設置資源限制的一個功能。它最主要的做用就是限制一個進程組可以使用的資源上限,包括 CPU、內存、磁盤、網絡帶寬等。此外,Cgroups 還可以對進程進行優先級設置、審計,以及將進程掛起和恢復等操做。web
那麼爲何除了 Namespace 以外還須要 Cgroups 呢?由於雖然容器裏的 1 號進程只能看到容器裏的狀況,可是在宿主機上,它做爲 100 號進程(好比宿主機上它的 PID 是 100)與其餘全部進程之間依然是平等的競爭關係。也就是說,雖然 100 號進程表面上被隔離了起來,可是它可以使用的資源(好比 CPU、內存)是所有的,它可能把全部資源耗光。那麼這樣顯然不是一個容器應該表現出來的合理行爲。docker
在 Linux 中,Cgroups 給用戶暴露出來的操做接口是文件系統,即操做接口是以文件和目錄的方式組織在操做系統的 /sys/fs/cgroup
路徑下。咱們能夠經過 mount 命令來查看一下,能夠發現輸出結果是一系列文件系統目錄。安全
![](http://static.javashuo.com/static/loading.gif)
咱們查看 /sys/fs/cgroup
的時候還能夠看到一系列子目錄,這些子目錄又被稱爲子系統。這些都是我這臺機器上當前能夠被 Cgroups 進行限制的資源種類。好比:微信
-
cpu 只要限制 CPU 的使用時間 -
cpuset 爲進程分配單獨的 CPU 核和對應的內存節點 -
memory 爲進程設定內存使用的限制 -
blkio 塊設備設定 IO 限制,通常用於磁盤等設備
![](http://static.javashuo.com/static/loading.gif)
而在子目錄下面能夠看到該子系統對應的資源能夠被限制的方法,好比對於 CPU 子系統來講,咱們能夠看到以下幾個配置文件。網絡
![](http://static.javashuo.com/static/loading.gif)
其中 cpu.cfs_period_us 和 cpu.cfs_quota_us 這兩個文件組合使用能夠限制進程在長度爲 cfs_period 的一段時間內,只能被分配到總量爲 cfs_quota 的 CPU 時間。app
Cgoups 配置示例
下面基於 Cgroups 提供的操做接口進行配置,咱們先在相應的子系統中再建立一個目錄,好比 container
,這個目錄就被稱爲「控制組」。當將這個目錄建立好了以後,你會發現這個目錄已經生成了該子系統對應的資源限制文件。編輯器
![](http://static.javashuo.com/static/loading.gif)
接下去,咱們經過修改 container
中的文件內容來設置限制。好比向 container 中的 cpu.cfs_quota_us
中寫入 20 ms,也就是 20000,就表示每 cpu_period_us (100ms)被控制組限制的進程只能使用 20ms 的 CPU 時間。微服務
接下去咱們把要限制的進程 PID 寫入 container 目錄中的 tasks 文件中,那麼該設置對要限制的進程就有效了。性能
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
Docker 實現
對於 Docker 等 Linux 容器項目來講,它們只須要在每一個子系統下面,爲每一個容器建立一個控制組(也就是建立一個新目錄),而後在啓動容器進程以後,把這個進程的 PID 寫入到這個控制組的 tasks 文件中便可。而控制組中的資源限制要填上什麼值,就要看用戶執行 docker run 時指定的參數內容。在 Docker 主機中,每一個子系統下面都有 docker 控制組。學習
![](http://static.javashuo.com/static/loading.gif)
下面咱們來演示 docker 進行設置的效果,就會在 CPU 子系統的 docker 控制組中進行相關的設置。
docker run -it --rm --cpu-period=100000 --cpu-quota=20000 -d alpine sleep 500s
以下所示,docker 還會在 docker 控制組建立一個新的目錄,在這個目錄中對資源進行設置,從而達到限制資源使用的效果。
![](http://static.javashuo.com/static/loading.gif)
總結
跟 Namespace 狀況相似,Cgoups 對資源的限制能力也有不少不完善的地方,其中被說起最多的是 /proc 文件系統的問題。/proc 目錄存儲着當前內核運行狀態的一系列特殊文件,用戶能夠經過訪問這些文件,查看系統以及當前正在運行的進程的信息,好比 CPU 使用狀況、內存佔用率等,這些文件也是 top 指令查看系統信息的主要數據來源。
可是,若是你在容器裏執行 top 指令,就會發現,它顯示的信息竟然仍是宿主機的 CPU 和內存數據。這是由於 /proc 文件系統並不知道用戶經過 Cgroups 給這個容器作了什麼樣的資源限制,因此它返回的仍是整個宿主機的。那麼這個問題會致使,容器內的應用程序讀取到的 CPU 核數、可用內存等信息仍是宿主機的,而不是作了限制以後的。這就是容器相比較於虛擬機另外一個不盡如人意的地方。
固然,爲了解決上面的那個問題。直觀的作法就是容器不掛載宿主機的該目錄就能夠了,那麼實際上能夠經過 lxcfs 來實現隔離,lxcfs 在宿主機上維護進程組的信息,而後容器啓動的時候將 lxcfs 維護的進程組信息所在的目錄掛載到容器的 /proc 目錄,當容器中獲取 /proc 信息時,實際上獲取宿主機上對該容器的進程組信息。
★20201008理解:/proc 存的是當前宿主機內核運行狀態的狀況,好比 CPU 使用狀況、內存佔用率等。容器在它看來其實就是一個作了限制的進程而已,它作計算仍是針對整個內核的狀況。可是,容器內的實際使用狀況應該是根據容器中的相關限制來得出的,好比已經對容器作了 CPU 使用的限制,那麼 top 命令獲得的應該是在這個限制下,容器內進程的實際使用狀況。
」
後臺回覆「加羣」,帶你進入高手如雲交流羣
推薦閱讀:
10大高性能開發利器
10T 技術資源大放送!包括但不限於:雲計算、虛擬化、微服務、大數據、網絡、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公衆號內回覆「1024」,便可免費獲取!!
本文分享自微信公衆號 - Linux雲計算網絡(cloud_dev)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。