Docker技術基礎:cgroups

Github-blog
CSDN

cgroups簡介

cgroups(control groups)包含三個組件,分別爲cgroup、hierarchy,以及subsystem。

cgroup

cgroup是對進程分組管理的一種機制,cgroups中的資源控制都以cgroup爲單位實現。cgroup表示按某種資源控制標準劃分而成的任務組,包含一個或多個子系統。一個任務可以加入某個cgroup,也可以從某個cgroup遷移到另外一個cgroup。

subsystem

subsystem 是一組資源控制的模塊,主要包含cpuset, cpu, cpuacct, blkio, memory, devices, freezer, net_cls, net_prio, perf_event, hugetlb, pids。具體介紹如下:

cpuset     在多核機器上設置cgroup 中進程可以使用的CPU 和內存   
cpu        設置cgroup 中進程的CPU 被調度的策略  
cpuacct    可以統計cgroup 中進程的CPU 佔用  
blkio      設置對塊設備(比如硬盤)輸入輸出的訪問控制  
memory     用於控制cgroup 中進程的內存佔用  
devices    控制cgroup 中進程對設備的訪問  
freezer    用於掛起和恢復cgroup 中的進程  
net_cls    用於將cgroup 中進程產生的網絡包分類,以便Linux 的tc (traffic con位oller)可以根據分類區分出來自某個cgroup 的包並做限流或監控  
net_prio   設置cgroup 中進程產生的網絡流量的優先級  
perf_event 增加了對每group的監測跟蹤的能力,即可以監測屬於某個特定的group的所有線程以及運行在特定CPU上的線程  
hugetlb    限制HugeTLB(huge translation lookaside buffer)的使用,TLB是MMU中的一塊高速緩存(也是一種cache,是CPU內核和物理內存之間的cache),它緩存最近查找過的VA對應的頁表項   
pids       限制cgroup及其所有子孫cgroup裏面能創建的總的task數量    

查看kernel支持的subsystem可以使用lssubsys命令:

    root@xftony:~# lssubsys -a
    cpuset
    cpu,cpuacct
    blkio
    memory
    devices
    freezer
    net_cls,net_prio
    perf_event
    hugetlb
    pids   

同時可以在/sys/fs/cgroup/memory目錄下可以查看:

  root@xftony:/sys/fs/cgroup# ls
    blkio    cpu,cpuacct  freezer  net_cls           perf_event
    cpu      cpuset       hugetlb  net_cls,net_prio  pids
    cpuacct  devices      memory   net_prio          systemd

hierarchy

把一組cgroup串成一個樹狀的結構,一個這樣的樹便是一個hierarchy。一個系統可以有多個hierarchy。通過這種樹狀結構,cgroups可以做到繼承。
下面這個例子就是一顆hierarchy, 其中c0是其根節點,c1、c2是c0的子節點,會繼承c0的限制,c1、c2可以在cgroup-test的基礎上定製特殊的資源限制條件。

root@xftony:~/test/c0# tree
.
├── c1
│   ├── cgroup.clone_children
│   ├── cgroup.procs
│   ├── notify_on_release
│   └── tasks
├── c2
│   ├── cgroup.clone_children
│   ├── cgroup.procs
│   ├── notify_on_release
│   └── tasks
├── cgroup.clone_children
├── cgroup.procs
├── cgroup.sane_behavior
├── notify_on_release
├── release_agent
└── tasks

cgroup、subsystem、hierarchy三者關係

1、一個subsystem只能附加到一個hierarchy上面;
2、一個hierarcy可以附加多個subsystem;
3、一個進程可以作爲多個cgroup的成員,但是這些cgroup必須不在同一個hierarchy上。在不同的hierarchy上可以擁有多個subsystem,進行多個條件限制;
4、一個進程fork出來的子進程開始時一定跟父進程在同一個cgroup中,後面可以根據需要將其移動到其他cgroup中;
5、創建好一個hierarchy後,所有的進程都會加入這個hierarchy的根結點(暫時覺得很奇怪==);
6、cgroups裏面的task內放置遵循該cgroup的進行id(pid),同一個hierarchy裏面,只能有一個。

cgroups測試:

cgroup的創建

創建一個掛載點,即創建一個文件夾,存放cgroup文件:

#mkdir cgroup-test  

掛載一個hierachy,不關聯任何subsystem

#mount -t cgroup -o none,name=cgroup-root cgroup-root1 ./cgroup-test   
//此時使用mount查看可以看到   
root@pgw-dev-4:~/test/cgroup-test# mount |grep cgroup 
cgroup-root1 on /root/test/cgroup-test type cgroup (rw,relatime,name=cgroup-root)     

cgroup-test 目錄下會生成一組默認文件:

root@pgw-dev-4:~/test/cgroup-test# ls  
cgroup.clone_children  cgroup.procs cgroup.sane_behavior notify_on_release  release_agent  tasks   

cgroup.procs內爲樹中當前節點的所有進程ID;
tasks文件內存放所有隸屬於跟cgroup節點的線程ID;
cgroup.sane_behavior標記sane_behavior是否生效,”Linux 3.16-rc2”後,該flag在non-default模式下已刪除;
notify_on releaserelease_agent會一起使用,notify_on release標識當這個cgroup最後一個進程退出的時候是否執行了release_agent;
release_agent是一個路徑,通常用作進程退出之後自動清理掉不再使用的cgroup。

查看cgroup.procstasks,我們可以看到系統中正在運行的進程和線程ID;

此時我們在創建一個新的hierachy c0

 #mount -t cgroup -o cpuset,name=c0-cpuset c0 ./c0

所有的cgroup.procstasks也都會加到c0內的cgroup.procstasks

subsystem的掛載

subsystem默認的mount的位置是在/sys/fs/cgroup/XXX,可以使用lssubsys -am命令查看。因爲一個subsystem只能附加到一個hierarchy上面,因此在測試前,我們想將一些subsustem從原位置上umount,此處我們以memory和cpuset爲例:

umount subsystem
umount /sys/fs/cgroup/cpuset/cpuset
mount subsystem

然後我們在創建c0, c0上不綁subsustem,然後在c0下創建c1, c1上mount cpuset子系統:

mkdir c0
mount -t cgroup -o none c0 ./c0
mkdir c1; cd c1
mount -t cgroup -o cpuset  c0 ./c1

其得到的cgroup結構爲:

root@xftony:~/test# tree -L 3
.
└── c0
    ├── c1
    │   ├── cgroup.clone_children
    │   ├── cgroup.procs
    │   ├── cgroup.sane_behavior
    │   ├── cpuset.cpu_exclusive
    │   ├── cpuset.cpus
    │   ├── cpuset.effective_cpus
    │   ├── cpuset.effective_mems
    │   ├── cpuset.mem_exclusive
    │   ├── cpuset.mem_hardwall
    │   ├── cpuset.memory_migrate
    │   ├── cpuset.memory_pressure
    │   ├── cpuset.memory_pressure_enabled
    │   ├── cpuset.memory_spread_page
    │   ├── cpuset.memory_spread_slab
    │   ├── cpuset.mems
    │   ├── cpuset.sched_load_balance
    │   ├── cpuset.sched_relax_domain_level
    │   ├── notify_on_release
    │   ├── release_agent
    │   └── tasks
    ├── cgroup.clone_children
    ├── cgroup.procs
    ├── cgroup.sane_behavior
    ├── notify_on_release
    ├── release_agent
    └── tasks

cgroup的使用

在c1目錄下創建測試目錄cputest,然後設置cpu限制。

cd c1
mkdir cputest; cd cputest
//僅允許使用 Cpu1
echo 1 > cpuset.cpus

啓動測試程序:

root@xftony:~/test# cat test.sh
touch /root/test/my.lock
lock_file=/root/test/my.lock
x=0
while [ -f $lock_file ];do
    x=$x+1
done;
root@xftony:~/test#./test.sh

此時top查看其內存cpu佔用情況:

%Cpu0  : 75.0 us, 23.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  2.0 st
%Cpu1  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                     
32664 root      20   0   23268   5828   2228 R  99.3  0.1   1:13.56 bash  

我們將該腳本的pid:32664加入到cputesttasks下:

root@xftony:~/test/c0/c1/cputest#echo 32664 > tasks

此時在top中,該進程已經遷移到Cpu1中:

%Cpu0  :  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  : 77.1 us, 22.9 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                     
32664 root      20   0   25060   7636   2228 R 100.0  0.1   5:09.95 bash

top中cpu各參數含義:

us 用戶空間佔用CPU百分比
sy 內核空間佔用CPU百分比
ni 用戶進程空間內改變過優先級的進程佔用CPU百分比
id 空閒CPU百分比
wa 等待輸入輸出的CPU時間百分比
hi 硬件中斷
si 軟件中斷 
st: 實時

Github-blog
CSDN

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章