Cgroup與LXC簡介

一、DockerLXCCgroup的結構關係

根據Docker佈道師Jerome Petazzoni的說法,Docker約等於LXC+AUFS(之前只支持ubuntu時)(作者2015-10-22更新:Docker0.9.0版本開始引入libcontainer,可以視作LXC的替代品)。其中LXC負責資源管理,AUFS負責鏡像管理;而LXC包括cgroupnamespacechroot等組件,並通過cgroup進行資源管理。所以只從資源管理這條線來看的話,DockerLXCCgroup三者的關係是:Cgroup在最底層落實資源管理,LXCcgroup上封裝了一層,Docker又在LXC封裝了一層,關係圖如圖1b)所示。因此,要想玩轉Docker,有必要了解負責資源管理的CGroupLXC

wKiom1MBskzjI9ErAAFj5lAmO3Q417.jpgwKioL1MBsifiKhKiAADIayV7OHg252.jpg

(a)                                                                                    (b)

1 Docker-LXC-CGroup結構圖


二、Cgroup

1Cgroup基本概念

1Cgroup是什麼

Cgroupscontrol groups的縮寫,是Linux內核提供的一種可以限制、記錄、隔離進程組(process groups)所使用的物理資源(如:CPU, Memory, IO等)的機制。最初由Google的工程師提出,後來被整合進Linux內核。Cgroups也是LXC爲實現虛擬化所使用的資源管理手段,可以說沒有Cgroups就沒有LXC,也就沒有Docker

Cgroups最初的目標是爲資源管理提供的一個統一的框架,既整合現有的Cpuset等子系統,也爲未來開發新的子系統提供接口。現在的Cgroups適用於多種應用場景,從單個進程的資源控制,到實現操作系統層次的虛擬化(OS Level Virtualization)。Cgroups提供以下功能:

a)限制進程組可以使用的資源數量(Resource limiting )。比如:Memory子系統可以爲進程組設定一個Memory使用上限,一旦進程組使用的內存達到限額再申請內存,就會出發OOMout of  memory)。

b)進程組的優先級控制(Prioritization)。比如:可以使用CPU子系統爲某個進程組分配特定CPUshare

c)進程組隔離(Isolation)。比如:使用ns子系統可以使不同的進程組使用不同的namespace,以達到隔離的目的,不同的進程組有各自的進程、網絡、文件系統掛載空間。

d)記錄進程組使用的資源數量(Accounting)。比如:可以使用Cpuacct子系統記錄某個進程組使用的CPU時間

e)進程組控制(Control)。比如:使用freezer子系統可以將進程組掛起和恢復。


2Cgroup基本概念與術語

任務(task

Cgroups中,任務就是系統的一個進程。

控制族羣(control group

控制族羣就是一組按照某種標準劃分的進程,控制族羣通常按照應用劃分,即與某應用相關的一組進程,被劃分爲一個進程組,即控制族羣(control group)。Cgroups中的資源控制都是以控制族羣爲單位實現。一個進程可以加入到某個控制族羣,也可以從一個進程組遷移到另一個控制族羣。一個進程組的進程可以使用Cgroups以控制族羣爲單位分配的資源,同時受到Cgroups以控制族羣爲單位設定的限制。

層級(hierarchy

控制族羣可以組織成hierarchical的形式,既一顆控制族羣樹。控制族羣樹上的子節點控制族羣是父節點控制族羣的孩子,繼承父控制族羣的特定的屬性。控制族羣樹的示意圖如圖2所示。

wKioL1MBsumgSJooAAC8HGuob-w109.jpg

2 控制族羣樹結構示意圖

子系統(subsystem

一個子系統就是一個資源控制器,比如CPU子系統就是控制CPU時間分配的一個控制器。子系統必須附加(attach)到一個層級上才能起作用,一個子系統附加到某個層級以後,這個層級上的所有控制族羣都受到這個子系統的控制。


3Cgroup子系統介紹

a)blkio -- 這個子系統爲塊設備設定輸入/輸出限制,比如物理設備(磁盤,固態硬盤,USB等等)。

b)cpu -- 這個子系統使用調度程序提供對CPU Cgroup 任務訪問。

c)cpuacct -- 這個子系統自動生成Cgroup中任務所使用的 CPU 報告。

d)cpuset-- 這個子系統爲 Cgroup中的任務分配獨立CPU(在多核系統)和內存節點。

e)devices -- 這個子系統可允許或者拒絕Cgroup中的任務訪問設備。

f)freezer -- 這個子系統掛起或者恢復Cgroup中的任務。

g)memory -- 這個子系統設定Cgroup中任務使用的內存限制,並自動生成由那些任務使用的內存資源報告。

h)net_cls -- 這個子系統使用等級識別符(classid)標記網絡數據包,可允許Linux 流量控制程序(tc)識別從具體cgroup 中生成的數據包。

i)ns -- 名稱空間子系統。

Cgroup具有不同的掛載方法——“多掛載點”和“單掛載點”。子系統“多掛載點”掛載就是指不同子系統的文件掛載在不同的目錄下,每個子系統各有一個掛載點,目錄結構如圖3a)所示。cgroup對應服務cgconfig默認使用的就是“多掛載點”的方法。“單掛載點”則是指所有子系統的文件都掛載在同一個目錄下,所有子系統都統一掛載在一個掛載點,目錄結構如圖3b)所示。

wKioL1MBsq6wjiCsAAA8a6SxaGI637.jpg

3acgroup多掛載點目錄結構示意圖

wKiom1MBsujQSaqfAAQEMBSdJMs878.jpg

3bcgroup單掛載點目錄結構示意圖


2Cgroup安裝配置

1Cgroup安裝


安裝Cgroups需要libcap-devel和libcgroup兩個相關的包,CentOS上可以通過yum的方式下載安裝,具體的命令爲:

yum install gcc, libcap-devel,libcgroup, bridge-utils

2Cgroup掛載配置

Cgroup對應服務名稱爲cgconfigcgconfig默認採用“多掛載點”掛載。經過實際測試,發現在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)常用的Cgroup相關命令和配置文件

service cgconfig status|start|stop|restart    #查看已存在子系統

lssubsys –am    #查看已存在子系統

cgclear   # 清除所有掛載點內部文件,相當於service  cgconfig stop

cgconfigparser -l /etc/cgconfig.conf    #重新掛載


Cgroup默認掛載點(CentOS):/cgroup

cgconfig配置文件:/etc/cgconfig.conf


4libcgroup Man Page簡介

man 1 cgclassify -- cgclassify命令是用來將運行的任務移動到一個或者多個cgroup

man 1 cgclear -- cgclear 命令是用來刪除層級中的所有cgroup

man 5 cgconfig.conf -- cgconfig.conf文件中定義cgroup

man 8 cgconfigparser -- cgconfigparser命令解析cgconfig.conf文件和並掛載層級。


man 1 cgcreate -- cgcreate在層級中創建新cgroup

man 1 cgdelete -- cgdelete命令刪除指定的cgroup

man 1 cgexec -- cgexec命令在指定的cgroup中運行任務。

man 1 cgget -- cgget命令顯示cgroup參數。

man 5 cgred.conf -- cgred.confcgred服務的配置文件。

man 5 cgrules.conf -- cgrules.conf 包含用來決定何時任務術語某些  cgroup的規則。


man 8 cgrulesengd -- cgrulesengd  cgroup 中發佈任務。

man 1 cgset -- cgset 命令爲  cgroup 設定參數。

man 1 lscgroup -- lscgroup 命令列出層級中的  cgroup

man 1 lssubsys -- lssubsys 命令列出包含指定子系統的層級。


三、Linux ContainerLXC

1LXC基本概念

1LXC是什麼

LinuxContainer容器可以提供輕量級的虛擬化,以便隔離進程和資源,而且不需要提供指令解釋機制以及全虛擬化的其他複雜性。容器有效地將由單個操作系統管理的資源劃分到孤立的組中,以更好地在孤立的組之間平衡有衝突的資源使用需求。

LXC建立在CGroup基礎上,我們可以粗略的認爲LXC = Cgroup+ namespace + Chroot + veth +用戶態控制腳本。LXC利用內核的新特性(CGroup)來提供用戶空間的對象,用來保證資源的隔離和對於應用或者系統的資源控制。

根據LXC官網(http://linuxcontainers.org/)的描述,LXC具有以下特性:

Current LXC uses the following kernel features to  contain processes:


Kernel namespaces (ipc, uts, mount, pid, network and  user)

Apparmor and SELinux profiles

Seccomp policies

Chroots (using pivot_root)

Kernel capabilities

Control groups (cgroups)


1LXC的優勢

與虛擬化相比,它的優勢在於:

a)不需要指令級模擬;

b)不需要即時(Just-in-time)編譯;

c)容器可以在CPU核心的本地運行指令,而不需要任何專門的解釋機制;

d)避免了準虛擬化和系統調用替換中的複雜性。

總結來說,就是LXC更加輕量級,具有更小的性能開銷、更快的相應時間。


2LXC安裝與使用

1LXC安裝

sourceforge.net/projects/lxc/files/lxc下載lxc源碼

解壓後進入目錄,執行以下命令:

./configure

make

sudo make install


2LXC常用命令

參考:http://www.cnblogs.com/lisperl/archive/2012/04/13/2446179.html


lxc-checkconfig # 查看內核支持

lxc-create -n name -f config

lxc-start -n name -f config cmd

lxc-execute -n name -f config cmd

# 備註:lxc-start只啓動一個進程,即cmdlxc-execute  啓動兩個進程,lxc-initcmd


lxc-kill -n name #SIGNUM信號

lxc-stop -n name # 停止lxc內所有進程

lxc-destroy -n name # 銷燬進程

lxc-cgroup -n name subsys value #  控制資源,例如 lxc-cgroup -n name  cpuset.cpus 0,3


3)資源控制

Cores

lxc.cgroup.cpuset.cpus=1,2,3

CPU  share

lxc.cgroup.cpu.shares=1024 # default

Memory  usage (!Debian)

lxc.cgroup.memory.limit_in_bytes = 256M

lxc.cgroup.memory.memsw.limit_in_bytes = 1G

Disk  (blkio)

Disk  space – standard LVM, quota...

echo 100 > /cgroup/disk1/blkio.weight # XXX <  1000 !

echo "3:0 1048576" >/cgroup/disk1/blkio.throttle.read_bps_device

lxc.cgroup.blkio.weight = 100


4)配置文件樣例

lxc.utsname =  host_name

lxc.tty = 1

lxc.network.type = veth

lxc.network.flags = up

lxc.network.link = br0

lxc.network.ipv4 = 192.168.120.105/16

lxc.network.name = eth0

#lxc.mount = ./fstab

#lxc.rootfs = /rootfs

lxc.cgroup.cpuset.cpus = 0

lxc.cgroup.cpu.shares = 80


5)使用中的一些小問題

lxc-ls  #列出所有lxc,但是在centos下時常不好用。備註lxc-create之後lxc-ls才能看到。但是隻lxc-create,而不execute,則並未實際啓動congtainer,相應cgroup並未實際掛載。


lxc-ps # 列出指定container內的所有進程。備註:lxc-ps –n name或者lxc-ps –n name -- -ef


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