[mydocker]---Linux Cgroup

前言

Linux Cgroups提供了對(duì)一組進(jìn)程及將來子進(jìn)程的資源限制、控制和統(tǒng)計(jì)的能力,這些資源包括CPU、內(nèi)存、存儲(chǔ)、網(wǎng)絡(luò)等.

概念

tasks:cgroups中,任務(wù)就是系統(tǒng)的一個(gè)進(jìn)程.
cgroup(control group): 一組按照某種標(biāo)準(zhǔn)劃分的進(jìn)程.
hierarchy: 把一組cgroup串成一個(gè)樹狀的結(jié)構(gòu), 可以做到繼承. 比如系統(tǒng)對(duì)一組定時(shí)的任務(wù)進(jìn)程通過cgroup1限制了CPU的使用率,然后其中有一個(gè)定時(shí)dump日志的進(jìn)程還需要限制磁盤IO ,為了避免限制了磁盤IO之后影響到其他進(jìn)程,就可以創(chuàng)建cgroup2,使其繼承于cgroup1井限制磁盤的IO,這樣cgroup2 便繼承了cgroup1 中對(duì)CPU 使用率的限制,并且增加了磁盤IO的限制而不影響到cgroup1 中的其他進(jìn)程.
subsystem: 一個(gè)子系統(tǒng)就是一個(gè)資源控制器.

他們直接的相互關(guān)系如下:

1. 每次在系統(tǒng)中創(chuàng)建新層級(jí)時(shí),該系統(tǒng)中的所有任務(wù)都是那個(gè)層級(jí)的默認(rèn)cgroup(稱之為root cgroup,此cgroup在創(chuàng)建層級(jí)時(shí)自動(dòng)創(chuàng)建,后面在該層級(jí)中創(chuàng)建的cgroup都是此 cgroup 的后代)的初始成員.
2. 一個(gè)子系統(tǒng)最多只能附加到一個(gè)層級(jí).
3. 一個(gè)層級(jí)可以附加多個(gè)子系統(tǒng).
4. 一個(gè)任務(wù)可以是多個(gè)cgroup的成員,但是這些cgroup必須在不同的層級(jí).
5. 系統(tǒng)中的進(jìn)程創(chuàng)建子進(jìn)程時(shí),該子任務(wù)自動(dòng)成為其父進(jìn)程所在cgroup 的成員。然后可根據(jù)需要將該子任務(wù)移動(dòng)到不同的cgroup中,但開始時(shí)它總是繼承其父任務(wù)的cgroup.

如下所示:

hierarchy-subsystem-cgroup-task.png

CPUMemory 兩個(gè)子系統(tǒng)有自己獨(dú)立的層級(jí)系統(tǒng), 而又通過 Task 取得關(guān)聯(lián)關(guān)系, 該task既有CPU的限制又有Memory的限制.

本機(jī)支持的subsystem

root@nicktming:~# cd /sys/fs/cgroup/
root@nicktming:/sys/fs/cgroup# ls
systemd
root@nicktming:/sys/fs/cgroup# apt-get install cgroup-bin
root@nicktming:/sys/fs/cgroup# lssubsys -a
cpuset
cpu
cpuacct
memory
devices
freezer
blkio
perf_event
hugetlb
root@nicktming:/sys/fs/cgroup# ls
blkio  cpu  cpuacct  cpuset  devices  freezer  hugetlb  memory  perf_event  systemd

cgroup

root@nicktming:~# mkdir cgroup && cd cgroup
root@nicktming:~/cgroup# mkdir demo
root@nicktming:~/cgroup# mount -t cgroup -o none,name=demo demo ./demo
root@nicktming:~/cgroup# ls ./demo
cgroup.clone_children  cgroup.event_control  cgroup.procs  cgroup.sane_behavior  notify_on_release  release_agent  tasks
root@nicktming:~/cgroup# wc -l ./demo/cgroup.procs
80 ./demo/cgroup.procs
root@nicktming:~/cgroup# wc -l ./demo/tasks
95 ./demo/tasks

cgroup.clone_children: cpusetsubsystem 會(huì)讀取這個(gè)配置文件,如果這個(gè)值是1 (默認(rèn)是0 ), 子cgroup 才會(huì)繼承父cgroupcpuset 的配置.
cgroup.procs: 樹中當(dāng)前節(jié)點(diǎn)cgroup中的進(jìn)程組ID ,現(xiàn)在的位置是在根節(jié)點(diǎn),這個(gè)文件中會(huì)有現(xiàn)在系統(tǒng)中所有進(jìn)程組的ID.
tasks: 標(biāo)識(shí)該cgroup下面的進(jìn)程ID,如果把一個(gè)進(jìn)程ID寫到tasks文件中,便會(huì)將相應(yīng)的進(jìn)程加入到這個(gè)cgroup中.

創(chuàng)建和刪除子cgroup

root@nicktming:~/cgroup# cd demo/
root@nicktming:~/cgroup/demo# mkdir cgroup1
root@nicktming:~/cgroup/demo# ls cgroup1/
cgroup.clone_children  cgroup.event_control  cgroup.procs  notify_on_release  tasks
root@nicktming:~/cgroup/demo# mkdir cgroup2
root@nicktming:~/cgroup/demo# tree
.
|-- cgroup1
|   |-- cgroup.clone_children
|   |-- cgroup.event_control
|   |-- cgroup.procs
|   |-- notify_on_release
|   `-- tasks
|-- cgroup2
|   |-- cgroup.clone_children
|   |-- cgroup.event_control
|   |-- cgroup.procs
|   |-- notify_on_release
|   `-- tasks
|-- cgroup.clone_children
|-- cgroup.event_control
|-- cgroup.procs
|-- cgroup.sane_behavior
|-- notify_on_release
|-- release_agent
`-- tasks
root@nicktming:~/cgroup/demo# sh -c "echo $$ > cgroup1/tasks"
root@nicktming:~/cgroup/demo# cat cgroup1/tasks 
11749
14172
root@nicktming:~/cgroup/demo# cat cgroup2/tasks
// 刪除子cgroup 直接刪除其文件夾即可
root@nicktming:~/cgroup/demo# rmdir cgroup2
// 如果子cgroup中tasks中有進(jìn)程的時(shí)候刪除不了, 必須把進(jìn)程移到別的cgroup中才可以刪除
root@nicktming:~/cgroup/demo# rmdir cgroup1
rmdir: failed to remove ‘cgroup1’: Device or resource busy
// 將該進(jìn)程從cgroup1移到demo cgroup中
root@nicktming:~/cgroup/demo# sh -c "echo 11749 > tasks"
root@nicktming:~/cgroup/demo# cat cgroup1/tasks
root@nicktming:~/cgroup/demo# rmdir cgroup1
root@nicktming:~/cgroup/demo# tree
.
|-- cgroup.clone_children
|-- cgroup.event_control
|-- cgroup.procs
|-- cgroup.sane_behavior
|-- notify_on_release
|-- release_agent
`-- tasks

subsystem

memory

可以限制cgroup中所有進(jìn)程所能使用的物理內(nèi)存總量等等.

root@nicktming:/sys/fs/cgroup/memory# ls
cgroup.clone_children  memory.kmem.failcnt             memory.kmem.tcp.max_usage_in_bytes  memory.numa_stat            memory.usage_in_bytes
cgroup.event_control   memory.kmem.limit_in_bytes      memory.kmem.tcp.usage_in_bytes      memory.oom_control          memory.use_hierarchy
cgroup.procs           memory.kmem.max_usage_in_bytes  memory.kmem.usage_in_bytes          memory.pressure_level       notify_on_release
cgroup.sane_behavior   memory.kmem.slabinfo            memory.limit_in_bytes               memory.soft_limit_in_bytes  release_agent
memory.failcnt         memory.kmem.tcp.failcnt         memory.max_usage_in_bytes           memory.stat                 tasks
memory.force_empty     memory.kmem.tcp.limit_in_bytes  memory.move_charge_at_immigrate     memory.swappiness

了解一下幾個(gè)比較重要的概念

 memory.usage_in_bytes      #顯示當(dāng)前已用的內(nèi)存
 memory.limit_in_bytes      #設(shè)置/顯示當(dāng)前限制的內(nèi)存額度
 memory.failcnt             #顯示內(nèi)存使用量達(dá)到限制值的次數(shù)
 memory.max_usage_in_bytes  #歷史內(nèi)存最大使用量
 memory.swappiness          #設(shè)置和顯示當(dāng)前的swappiness
 memory.oom_control         #設(shè)置/顯示oom controls相關(guān)的配置

加入cgroup限制

當(dāng)物理內(nèi)存達(dá)到上限后,系統(tǒng)的默認(rèn)行為是killcgroup中繼續(xù)申請(qǐng)內(nèi)存的進(jìn)程. 通過memory.oom_control來控制.

root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# cat memory.oom_control 
oom_kill_disable 0  // 0表明該進(jìn)程達(dá)到其limit時(shí)會(huì)被kill, 1表明會(huì)暫停該進(jìn)程
under_oom 0          // 0表明未進(jìn)入oom狀態(tài), 1表明該進(jìn)程被暫停
例子 oom_kill_disable = 0
root@nicktming:~# cat memory.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MB (1024 * 1024)

int main(int argc, char *argv[])
{
    char *p;
    int i = 0;
    while(1) {
        p = (char *)malloc(MB);
        memset(p, 0, MB);
        printf("%dM memory allocated\n", ++i);
        sleep(1);
    }

    return 0;
}
root@nicktming:/sys/fs/cgroup/memory# mkdir test-limit-memory && cd test-limit-memory
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# sh -c "echo $$ > tasks"
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# sh -c "echo 5M > memory.limit_in_bytes"
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# cd /root
// 可以看到在加入5M的限制后 運(yùn)行程序在申請(qǐng)5M內(nèi)存時(shí)候被killed.
root@nicktming:~# gcc memory.c -o memory
root@nicktming:~# ./memory 
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
Killed
例子 oom_kill_disable = 1
------------------------------------打開終端0-------------------------------
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# sh -c "echo 0 > memory.swappiness"
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# sh -c "echo 1 >> memory.oom_control"
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# cat memory.oom_control 
oom_kill_disable 1
under_oom 0
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# cd /root
// 運(yùn)行到申請(qǐng)5M的時(shí)候會(huì)暫停該進(jìn)程
root@nicktming:~# ./memory 
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
------------------------------------打開終端1-------------------------------
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# cat memory.oom_control 
oom_kill_disable 1
under_oom 1
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# sh -c "echo 15M > memory.limit_in_bytes"
------------------------------------打開終端0-------------------------------
// 該進(jìn)程繼續(xù)運(yùn)行
root@nicktming:~# ./memory 
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
5M memory allocated
6M memory allocated
7M memory allocated
8M memory allocated
9M memory allocated
10M memory allocated
11M memory allocated
12M memory allocated
13M memory allocated
14M memory allocated
------------------------------------打開終端1-------------------------------
// 重新把oom_kill_disable打開
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# sh -c "echo 0 >> memory.oom_control"
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# cat memory.oom_control 
oom_kill_disable 0
under_oom 0
// 可以看到該進(jìn)程超過內(nèi)存限制的次數(shù)
root@nicktming:/sys/fs/cgroup/memory/test-limit-memory# cat memory.failcnt 
85194
------------------------------------打開終端0-------------------------------
// 由于oom_kill_disable被設(shè)置為0, 所以該進(jìn)程被kill.
root@nicktming:~# ./memory 
1M memory allocated
2M memory allocated
3M memory allocated
4M memory allocated
5M memory allocated
6M memory allocated
7M memory allocated
8M memory allocated
9M memory allocated
10M memory allocated
11M memory allocated
12M memory allocated
13M memory allocated
14M memory allocated
Killed

參考

1. https://segmentfault.com/a/1190000006917884
2. https://www.ibm.com/developerworks/cn/linux/1506_cgroup/
3. 自己動(dòng)手寫docker.(基本參考此書,加入一些自己的理解,加深對(duì)docker的理解)

全部?jī)?nèi)容

mydocker.png

1. [mydocker]---環(huán)境說明
2. [mydocker]---urfave cli 理解
3. [mydocker]---Linux Namespace
4. [mydocker]---Linux Cgroup
5. [mydocker]---構(gòu)造容器01-實(shí)現(xiàn)run命令
6. [mydocker]---構(gòu)造容器02-實(shí)現(xiàn)資源限制01
7. [mydocker]---構(gòu)造容器02-實(shí)現(xiàn)資源限制02
8. [mydocker]---構(gòu)造容器03-實(shí)現(xiàn)增加管道
9. [mydocker]---通過例子理解存儲(chǔ)驅(qū)動(dòng)AUFS
10. [mydocker]---通過例子理解chroot 和 pivot_root
11. [mydocker]---一步步實(shí)現(xiàn)使用busybox創(chuàng)建容器
12. [mydocker]---一步步實(shí)現(xiàn)使用AUFS包裝busybox
13. [mydocker]---一步步實(shí)現(xiàn)volume操作
14. [mydocker]---實(shí)現(xiàn)保存鏡像
15. [mydocker]---實(shí)現(xiàn)容器的后臺(tái)運(yùn)行
16. [mydocker]---實(shí)現(xiàn)查看運(yùn)行中容器
17. [mydocker]---實(shí)現(xiàn)查看容器日志
18. [mydocker]---實(shí)現(xiàn)進(jìn)入容器Namespace
19. [mydocker]---實(shí)現(xiàn)停止容器
20. [mydocker]---實(shí)現(xiàn)刪除容器
21. [mydocker]---實(shí)現(xiàn)容器層隔離
22. [mydocker]---實(shí)現(xiàn)通過容器制作鏡像
23. [mydocker]---實(shí)現(xiàn)cp操作
24. [mydocker]---實(shí)現(xiàn)容器指定環(huán)境變量
25. [mydocker]---網(wǎng)際協(xié)議IP
26. [mydocker]---網(wǎng)絡(luò)虛擬設(shè)備veth bridge iptables
27. [mydocker]---docker的四種網(wǎng)絡(luò)模型與原理實(shí)現(xiàn)(1)
28. [mydocker]---docker的四種網(wǎng)絡(luò)模型與原理實(shí)現(xiàn)(2)
29. [mydocker]---容器地址分配
30. [mydocker]---網(wǎng)絡(luò)net/netlink api 使用解析
31. [mydocker]---網(wǎng)絡(luò)實(shí)現(xiàn)
32. [mydocker]---網(wǎng)絡(luò)實(shí)現(xiàn)測(cè)試

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,860評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,025評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,421評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,642評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,177評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,970評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,157評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,410評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評(píng)論 1 289
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,896評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,157評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容