一、定義:
Cgroup是Control Groups的縮寫,是Linux內核提供一種可以限制、記錄、隔離進程組所使用的物理資源的機制。
二、組成:
Cgroup是將任意進程進行分組化管理的Linux內核功能。Ggroup提供將進程進行分組化管理的功能和接口的基礎結構,用於實現I/O或者內存的分配控制等具體的資源管理。這些具體的資源管理功能稱爲Ggroup子系統或控制器。
1、task 任務:在cgroup中任務就是系統的一個進程。
2、control group=cgroup 控制組羣:控制族羣就是一組按照某種標準劃分的進程。cgroup中的資源控制都是以控制組羣爲單位實現。cfoup綁定一個進程集合到一個或多個子系統。
3、subsystem 子系統:一個通過cgroup提供的工具和接口來管理進程集合的模塊。一個子系統就是一個典型的“資源控制器”,用來調度資源或控制資源使用的上限。其實每種資源就是一個子系統。
4、hierarchy 層級樹:多個cgroup的集合。可以認爲這是一個資源樹,附着在這上面的進程可以使用的資源上限必須收樹上節點(cgroup)的控制。hierarchy上的層次關係通過cgroupgs虛擬文件系統顯示。系統允許多個hierarchy同時存在,每個hierachy包含系統中的部分或者全部進程集合。
5、cgroupfs是用戶管理操作cgroup的主要接口:通過在cgroupfs文件系統中創建目錄,實現cgroup的創建;通過向目錄下的屬性文件寫入內容,設置cgroup對資源的控制;向task屬性文件寫入進程ID,可以將進程綁定到某個cgroup,以此達到控制進程資源使用的目的;也可以列出cgroup包含的進程pid。這些操作影響的sysfs關聯的hierarchy,對其他hierarchy沒有影響。
相互關係:
1、每次在系統中創建新層級時,該系統的所有任務都是那個層級默認cgroup(root cgroup)的初始成員。
2、一個子系統最多附加一個層級。
3、一個層級可以附加多個子系統。
4、一個任務可以是多個cgroup的成員,但這些cgroup必須在不同層級。
5、系統中的進程(任務)創建子進程(任務)時,改子系統自動成爲其父進程所在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子系統可以將進程組掛起和恢復。
四、安裝配置:(默認有裝)
1、安裝Cgroups需要libcap-devel和libcgroup兩個相關的包:
yum install gcc libcap-devel
2、Cgroups掛載配置:
Cgroup對應服務名稱爲cgconfig,cgconfig默認採用“多掛載點”掛載。經過實際測試,發現在CentOS環境中應採用“單掛載點”進行掛載,因此應當卸載原有cgroup文件系統,並禁用cgconfig。
cgclear或者sudo service cgconfig stop # 停止cgconfig,卸載cgroup目錄
sudo chkconfig cgconfig off # 禁用cgconfig服務,避免其開機啓動
然後採用“單掛載點”方式重新掛載cgroup。
可以直接手動掛載,這樣僅當次掛載成功。
mount -t cgroup none /cgroup
然後編輯/etc/fstab/,輸入下列內容。這樣每次開機後都會自動掛載。
none /cgroup cgroup defaults 0 0
3、相關命令和配置文件:
service cgconfig status|start|stop|restart #查看已存在子系統
lssubsys –am #查看已存在子系統
cgclear # 清除所有掛載點內部文件,相當於service cgconfig stop
cgconfigparser -l /etc/cgconfig.conf #重新掛載
Cgroup默認掛載點(CentOS):/cgroup
cgconfig配置文件:/etc/cgconfig.conf
五、實際例子:
1、cgroup管理進程資源:
跑一個耗cpu的腳本:
x=0 while [ True ];do x=$x+1 done;
top可以看到腳本基本佔了100%的cpu資源:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 30142 root 20 0 104m 2520 1024 R 99.7 0.1 14:38.97 sh
下面用cgoup控制整個進程cpu資源
mkdir -p /cgroup/cpu/foo/ #新建一個控制組foo echo 50000 > /cgroup/cpu/foo/cpu.cfs_quota_us #將cpu.cfs_quota_us設爲50000,相對於cpu.cfs_period_us的100000是50% echo 30142 > /cgroup/cpu/foo/tasks
然後再top試試統計,cpu佔了將近50%。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 30142 root 20 0 105m 2884 1024 R 49.4 0.2 23:32.53 sh
2、cgroup管理進程內存資源:
跑一個耗內存的腳本,內存不斷增長:
x="a" while [ True ];do x=$x$x done;
top可以看到該腳本內存佔用逐步上升:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 30215 root 20 0 871m 501m 1036 R 99.8 26.7 0:38.69 sh
用cgroup控制整個進程的內存資源:
mkdir -p /cgroup/memory/foo echo 1048576 > /cgroup/memory/foo/memory.limit_in_bytes #分配1MB的內存給這個控制組 echo 30215 > /cgroup/memory/foo/tasks
發現之前的腳本被kill掉,當進程試圖佔用內存超過cgroup限制。就會觸發OOM,導致進程被kill掉。實際情況對進程有一個評估,然後對該進程限制超配50%,比如發生內存泄漏等異常情況,纔會因爲cgroup的限制被kill掉。
也可以通過配置關掉cgroups oom kill進程,通過memory.oom_control來實現(oom_kill_disable 1),但是儘管進程不會被直接殺死,但進程也進入了休眠狀態,無法繼續執行,仍讓無法服務。
3、cgroup管理進程io資源:
跑一個耗io的腳本:
dd if=/dev/sda of=/dev/null &
通過iotop看io佔用情況:
30252 be/4 root 284.71 M/s 0.00 B/s 0.00 % 0.00 % dd if=/dev/sda of=/dev/null
用cgroup控制這個進程的io資源:
mkdir -p /cgroup/blkio/foo echo '8:0 1048576' > /cgroup/blkio/foo/blkio.throttle.read_bps_device #8:0對應主設備號和副設備號,可以通過ls -l /dev/sda查看 echo 30252 > /cgroup/blkio/foo/tasks
在用iotop看,讀速度降到1M/s:
30252 be/4 root 993.36 K/s 0.00 B/s 0.00 % 0.00 % dd if=/dev/sda of=/dev/null
轉載:
https://blog.csdn.net/kwame211/article/details/78730705
https://www.cnblogs.com/yanghuahui/p/3751826.html
https://www.jianshu.com/p/dc3140699e79
https://blog.csdn.net/huang987246510/article/details/80765628