cgroup 介绍 与使用
一.cgroup介紹
1).限制進程組可以使用的資源數量(Resource limiting )。比如:memory子系統可以為進程組設定一個memory使用上限,一旦進程組使用的內存達到限額再申請內存,就會出發OOM(out of memory)。
2).進程組的優先級控制(Prioritization )。比如:可以使用cpu子系統為某個進程組分配特定cpu share。
3).記錄進程組使用的資源數量(Accounting )。比如:可以使用cpuacct子系統記錄某個進程組使用的cpu時間
4).進程組隔離(Isolation)。比如:使用ns子系統可以使不同的進程組使用不同的namespace,以達到隔離的目的,不同的進程組有各自的進程、網絡、文件系統掛載空間。
5).進程組控制(Control)。比如:使用freezer子系統可以將進程組掛起和恢復。
Cgroups相關概念及其關系
1).任務(task)。在cgroups中,任務就是系統的一個進程。
2).控制族群(control group)。控制族群就是一組按照某種標準劃分的進程。Cgroups中的資源控制都是以控制族群為單位實現。一個進程可以加入到某個控制族群,也從一個進程組遷移到另一個控制族群。一個進程組的進程可以使用cgroups以控制族群為單位分配的資源,同時受到cgroups以控制族群為單位設定的限制。
3).層級(hierarchy)。控制族群可以組織成hierarchical的形式,既一顆控制族群樹。控制族群樹上的子節點控制族群是父節點控制族群的孩子,繼承父控制族群的特定的屬性。
4).子系統(subsytem)。一個子系統就是一個資源控制器,比如cpu子系統就是控制cpu時間分配的一個控制器。子系統必須附加(attach)到一個層級上才能起作用,一個子系統附加到某個層級以后,這個層級上的所有控制族群都受到這個子系統的控制。
1).每次在系統中創建新層級時,該系統中的所有任務都是那個層級的默認 cgroup(我們稱之為 root cgroup ,此cgroup在創建層級時自動創建,后面在該層級中創建的cgroup都是此cgroup的后代)的初始成員。
2).一個子系統最多只能附加到一個層級。
3).一個層級可以附加多個子系統
4).一個任務可以是多個cgroup的成員,但是這些cgroup必須在不同的層級。
5).系統中的進程(任務)創建子進程(任務)時,該子任務自動成為其父進程所在 cgroup 的成員。然后可根據需要將該子任務移動到不同的 cgroup 中,但開始時它總是繼承其父任務的cgroup。
1)blkio 這個子系統為塊設備設定輸入/輸出限制,比如物理設備(磁盤,固態硬盤,USB 等等)。
2)cpu 這個子系統使用調度程序提供對 CPU 的 cgroup 任務訪問。
3)cpuacct 這個子系統自動生成 cgroup 中任務所使用的 CPU 報告。
4)cpuset 這個子系統為 cgroup 中的任務分配獨立 CPU(在多核系統)和內存節點。
5)devices 這個子系統可允許或者拒絕 cgroup 中的任務訪問設備。
6)freezer 這個子系統掛起或者恢復 cgroup 中的任務。
7)memory 這個子系統設定 cgroup 中任務使用的內存限制,并自動生成由那些任務使用的內存資源報告。
8)net_cls 這個子系統使用等級識別符(classid)標記網絡數據包,可允許 Linux 流量控制程序(tc)識別從具體 cgroup 中生成的數據包。
9)ns 名稱空間子系統。
二.使用
#yum install libcgroup
#cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
配置文件
#cat /etc/cgconfig.conf
- mount {
- cpuset = /cgroup/cpuset;
- memory = /cgroup/memory;
- net_cls = /cgroup/net_cls;
- freezer = /cgroup/freezer;
- }
- group httpd {
- memory {
- memory.limit_in_bytes = 10M;
- }
- }
配置介紹
- group name {
- [permissions]
- controller {
- param name = param value;
- …
- }
- …}?
name: 指定cgroup的名稱
permissions:可選項,指定cgroup對應的掛載點文件系統的權限,root用戶擁有所有權限。
controller:子系統的名稱
param name 和 param value:子系統的屬性及其屬性值
#cat /etc/cgrules.conf
auser:ab memory httpd
用戶或@組:命令 子系統 cgroup名稱
@auser:ab memory httpd
#systemctl restart cgconfig.service
#systemctl restart cgred.service
配置是限制auser用戶 執行ab時,當使用內存超過10M時,進程就會被殺。(默認配置)
內核相關的配置
由于memory subsystem比較耗資源,所以內核專門添加了一個參數cgroup_disable=memory來禁用整個memory subsystem,這個參數可以通過GRUB在啟動系統的時候傳給內核,加了這個參數后內核將不再進行memory subsystem相關的計算工作,在系統中也不能掛載memory subsystem。
上面提到的CONFIG_MEMCG_SWAP和CONFIG_MEMCG_KMEM都是擴展功能,在使用前請確認當前內核是否支持,
這里CONFIG_MEMCG_SWAP和CONFIG_MEMCG_KMEM等于y表示內核已經編譯了該模塊,即支持相關功能
$cat /boot/config-uname -r|grep CONFIG_MEMCG (我也是醉了,新版51,這引號自帶背影的)
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
#CONFIG_MEMCG_SWAP_ENABLED is not set
CONFIG_MEMCG_KMEM=y
CONFIG_MEMCG_SWAP控制內核是否支持Swap 擴展,而CONFIG_MEMCG_SWAP_ENABLED(3.6以后的內核新加的參數)控制默認情況下是否使用Swap 擴展,由于Swap 擴展比較耗資源,所以很多發行版(比如ubuntu)默認情況下會禁用該功能(這也是上面那行被注釋掉的原因),當然用戶也可以根據實際情況,通過設置內核參數swapaccount=0或者1來手動禁用和啟用Swap Extension。
測試
[auser@app ~]$ ab -c 10 -n 1000000?http://IP/index.html
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd,?http://www.zeustech.net/
Licensed to The Apache Software Foundation,?http://www.apache.org/
Benchmarking 192.168.90.177 (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
已殺死
#top 觀察auser使用ab命令時候內存使用情況,當使用超過10M大概持續2到3秒時,會發現進程被殺死。
一旦設置了內存限制,將立即生效,并且當物理內存使用量達到limit的時候,memory.failcnt的內容會加1,但這時進程不一定就會被kill掉,內核會盡量將物理內存中的數據移到swap空間上去,如果實在是沒辦法移動了(設置的limit過小,或者swap空間不足),默認情況下,就會kill掉cgroup里面繼續申請內存的進程。
當物理內存達到上限后,系統的默認行為是kill掉cgroup中繼續申請內存的進程,那么怎么控制這樣的行為呢?答案是配置memory.oom_control
這個文件里面包含了一個控制是否為當前cgroup啟動OOM-killer的標識。如果寫0到這個文件,將啟動OOM-killer,當內核無法給進程分配足夠的內存時,將會直接kill掉該進程;如果寫1到這個文件,表示不啟動OOM-killer,當內核無法給進程分配足夠的內存時,將會暫停該進程直到有空余的內存之后再繼續運行;同時,memory.oom_control還包含一個只讀的under_oom字段,用來表示當前是否已經進入oom狀態,也即是否有進程被暫停了。
#cat /cgroup/memory/httpd/memory.oom_control
oom_kill_disable 0
under_oom 0
#echo 0 > memory.swappiness 設置swappiness為0 禁止當前cgroup使用swap
當超過限額,會被直接殺掉,不會使用swap空間。
#echo 1 > /cgroup/memory/httpd/memory.oom_control 注意:不要vim編輯去寫,直接echo 1進去,雖然有兩行配置
oom_kill_disable等于1的時候內存達到限額的時候會暫停
當臨時修改擴大內存時,進程又繼續工作,當又不夠時,就會再次暫停工作。
進程遷移
當一個進程從一個cgroup移動到另一個cgroup時,默認情況下,該進程已經占用的內存還是統計在原來的cgroup里面,不會占用新cgroup的配額,但新分配的內存會統計到新的cgroup中(包括swap out到交換空間后再swap in到物理內存中的部分)。
我們可以通過設置memory.move_charge_at_immigrate讓進程所占用的內存隨著進程的遷移一起遷移到新的cgroup中
enable: echo 1 > memory.move_charge_at_immigrate
disable:echo 0 > memory.move_charge_at_immigrate
注意: 就算設置為1,但如果不是thread group的leader,這個task占用的內存也不能被遷移過去。換句話說,如果以線程為單位進行遷移,必須是進程的第一個線程,如果以進程為單位進行遷移,就沒有這個問題。
當memory.move_charge_at_immigrate為0時,就算當前cgroup中里面的進程都已經移動到其它cgropu中去了,由于進程已經占用的內存沒有被統計過去,當前cgroup有可能還占用很多內存,當移除該cgroup時,占用的內存需要統計到誰頭上呢?答案是依賴memory.use_hierarchy的值,如果該值為0,將會統計到root cgroup里;如果值為1,將統計到它的父cgroup里面。
相關參數:
1)force_empty :
當向memory.force_empty文件寫入0時(echo 0 > memory.force_empty),將會立即觸發系統盡可能的回收該cgroup占用的內存。該功能主要使用場景是移除cgroup前(cgroup中沒有進程),先執行該命令,可以盡可能的回收該cgropu占用的內存,這樣遷移內存的占用數據到父cgroup或者root cgroup時會快些。
memory.swappiness :
該文件的值默認和全局的swappiness(/proc/sys/vm/swappiness)一樣,修改該文件只對當前cgroup生效,其功能和全局的swappiness一樣
有一點和全局的swappiness不同,那就是如果這個文件被設置成0,就算系統配置的有交換空間,當前cgroup也不會使用交換空間。
2)memory.use_hierarchy:
該文件內容為0時,表示不使用繼承,即父子cgroup之間沒有關系;當該文件內容為1時,子cgroup所占用的內存會統計到所有祖先cgroup中。
如果該文件內容為1,當一個cgroup內存吃緊時,會觸發系統回收它以及它所有子孫cgroup的內存。
注意: 當該cgroup下面有子cgroup或者父cgroup已經將該文件設置成了1,那么當前cgroup中的該文件就不能被修改。
3)memory.soft_limit_in_bytes:
有了hard limit(memory.limit_in_bytes),為什么還要soft limit呢?hard limit是一個硬性標準,絕對不能超過這個值,而soft limit可以被超越,既然能被超越,要這個配置還有啥用?先看看它的特點
當系統內存充裕時,soft limit不起任何作用
當系統內存吃緊時,系統會盡量的將cgroup的內存限制在soft limit值之下(內核會盡量,但不100%保證)
從它的特點可以看出,它的作用主要發生在系統內存吃緊時,如果沒有soft limit,那么所有的cgroup一起競爭內存資源,占用內存多的cgroup不會讓著內存占用少的cgroup,這樣就會出現某些cgroup內存饑餓的情況。如果配置了soft limit,那么當系統內存吃緊時,系統會讓超過soft limit的cgroup釋放出超過soft limit的那部分內存(有可能更多),這樣其它cgroup就有了更多的機會分配到內存。
從上面的分析看出,這其實是系統內存不足時的一種妥協機制,給次等重要的進程設置soft limit,當系統內存吃緊時,把機會讓給其它重要的進程。
注意: 當系統內存吃緊且cgroup達到soft limit時,系統為了把當前cgroup的內存使用量控制在soft limit下,在收到當前cgroup新的內存分配請求時,就會觸發回收內存操作,所以一旦到達這個狀態,就會頻繁的觸發對當前cgroup的內存回收操作,會嚴重影響當前cgroup的性能。
CPU、內存、IO和網絡都能通過cgroup進行管控。通過資源再分配合理的優化虛擬化或者容器。
未完待續
? ? ? 本文轉自潘闊 51CTO博客,原文鏈接:http://blog.51cto.com/pankuo/2044862,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的cgroup 介绍 与使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 侧记戴尔的第三代虚拟化价值观
- 下一篇: Linux系统下常见性能分析工具的使用