前言
簡單的整理一下一些基本概念。
正文
簡單運行一個容器:
創建一個容器:
docker run -it busybox /bin/bash
然後看下進程:
ps -ef
做了一個障眼法,使用的是pid namespace方式,讓容器內部只能看到由容器創建的進程。
linux 還有一些其他的機制:
比如,Mount Namespace,用於讓被隔離進程只看到當前 Namespace 裏的掛載點信
息;Network Namespace,用於讓被隔離進程看到當前 Namespace 裏的網絡設備和配
置。
現在隔離了一些資源,似乎能讓新啓動的進程,只能使用被容器規範起來的資源。
但是有一個問題,那就是把資源分配出去了,到底分配多少資源。
主要是幾大塊吧,內存、cpu、磁盤。
Linux Cgroups 就是 Linux 內核中用來爲進程設置資源限制的一個重要功能。
Linux Cgroups 的全稱是 Linux Control Group。它最主要的作用,就是限制一個進程
組能夠使用的資源上限,包括 CPU、內存、磁盤、網絡帶寬等等。
舉個例子
查看cgroup 限制:
mount -t cgroup
有這些限制:
舉個限制cpu的例子:
進入限制cpu的目錄下:
創建一個組,比如mkdir container:
改下兩個參數:
echo 20000 > cpu.cfs_quota_us
限制100ms 內只能使用20ms。
現在運行一個進程:
看下cpu:
100% 了,現在限制一下這個進程的cpu。
echo 3121 > tasks
再看下cpu:
現在kill 3121
除 CPU 子系統外,Cgroups 的每一項子系統都有其獨有的資源限制能力,比如:
blkio,爲 塊 設 備 設 定 I/O 限 制,一般用於磁盤等設備;
cpuset,爲進程分配單獨的 CPU 核和對應的內存節點;
memory,爲進程設定內存使用的限制。
Linux Cgroups 的設計還是比較易用的,簡單粗暴地理解呢,它就是一個子系統目錄加上
一組資源限制文件的組合。而對於 Docker 等 Linux 容器項目來說,它們只需要在每個子
系統下面,爲每個容器創建一個控制組(即創建一個新目錄),然後在啓動容器進程之後,
把這個進程的 PID 填寫到對應控制組的 tasks 文件中就可以了。
例如:
docker run -it --cpu-period=100000 --cpu-quota=20000 busybox /bin/sh
這樣就限制了。
來看下限制:
進去查看:
結
大概就是這麼回事了。
linux 容器化優勢不多說,用的自然知道,節約能源,方便使用。
弊端:
- 在 Linux 內核中,有很多資源和對象是不能被 Namespace 化的,最典型的例子就
是:時間。 - 衆所周知,Linux 下的 /proc 目錄存儲的是記錄當前內核運行狀態的一系列特殊文件,用戶
可以通過訪問這些文件,查看系統以及當前正在運行的進程的信息,比如 CPU 使用情況、
內存佔用率等,這些文件也是 top 指令查看系統信息的主要數據來源。
但是,你如果在容器裏執行 top 指令,就會發現,它顯示的信息居然是宿主機的 CPU 和內
存數據,而不是當前容器的數據。
造成這個問題的原因就是,/proc 文件系統並不知道用戶通過 Cgroups 給這個容器做了什
麼樣的資源限制,即:/proc 文件系統不瞭解 Cgroups 限制的存在。
在生產環境中,這個問題必須進行修正,否則應用程序在容器裏讀取到的 CPU 核數、可用
內存等信息都是宿主機上的數據,這會給應用的運行帶來非常大的困惑和風險。這也是在企
業中,容器化應用碰到的一個常見問題,也是容器相較於虛擬機另一個不盡如人意的地方。