一、Docker、LXC、Cgroup的结构关系
根据Docker布道师Jerome Petazzoni的说法,Docker约等于LXC+AUFS(之前只支持ubuntu时)(作者2015-10-22更新:Docker0.9.0版本开始引入libcontainer,可以视作LXC的替代品)。其中LXC负责资源管理,AUFS负责镜像管理;而LXC包括cgroup、namespace、chroot等组件,并通过cgroup进行资源管理。所以只从资源管理这条线来看的话,Docker、LXC、Cgroup三者的关系是:Cgroup在最底层落实资源管理,LXC在cgroup上封装了一层,Docker又在LXC封装了一层,关系图如图1(b)所示。因此,要想玩转Docker,有必要了解负责资源管理的CGroup和LXC。
(a) (b)
图1 Docker-LXC-CGroup结构图
二、Cgroup
1、Cgroup基本概念
1)Cgroup是什么
Cgroups是control 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使用上限,一旦进程组使用的内存达到限额再申请内存,就会出发OOM(out of memory)。
b)进程组的优先级控制(Prioritization)。比如:可以使用CPU子系统为某个进程组分配特定CPUshare。
c)进程组隔离(Isolation)。比如:使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间。
d)记录进程组使用的资源数量(Accounting)。比如:可以使用Cpuacct子系统记录某个进程组使用的CPU时间
e)进程组控制(Control)。比如:使用freezer子系统可以将进程组挂起和恢复。
2)Cgroup基本概念与术语
任务(task)
在Cgroups中,任务就是系统的一个进程。
控制族群(control group)
控制族群就是一组按照某种标准划分的进程,控制族群通常按照应用划分,即与某应用相关的一组进程,被划分为一个进程组,即控制族群(control group)。Cgroups中的资源控制都是以控制族群为单位实现。一个进程可以加入到某个控制族群,也可以从一个进程组迁移到另一个控制族群。一个进程组的进程可以使用Cgroups以控制族群为单位分配的资源,同时受到Cgroups以控制族群为单位设定的限制。
层级(hierarchy)
控制族群可以组织成hierarchical的形式,既一颗控制族群树。控制族群树上的子节点控制族群是父节点控制族群的孩子,继承父控制族群的特定的属性。控制族群树的示意图如图2所示。
图2 控制族群树结构示意图
子系统(subsystem)
一个子系统就是一个资源控制器,比如CPU子系统就是控制CPU时间分配的一个控制器。子系统必须附加(attach)到一个层级上才能起作用,一个子系统附加到某个层级以后,这个层级上的所有控制族群都受到这个子系统的控制。
3)Cgroup子系统介绍
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具有不同的挂载方法——“多挂载点”和“单挂载点”。子系统“多挂载点”挂载就是指不同子系统的文件挂载在不同的目录下,每个子系统各有一个挂载点,目录结构如图3(a)所示。cgroup对应服务cgconfig默认使用的就是“多挂载点”的方法。“单挂载点”则是指所有子系统的文件都挂载在同一个目录下,所有子系统都统一挂载在一个挂载点,目录结构如图3(b)所示。
图3(a)cgroup多挂载点目录结构示意图
图3(b)cgroup单挂载点目录结构示意图
2、Cgroup安装配置
1)Cgroup安装
安装Cgroups需要libcap-devel和libcgroup两个相关的包,CentOS上可以通过yum的方式下载安装,具体的命令为:
yum install gcc, libcap-devel,libcgroup, bridge-utils |
2)Cgroup挂载配置
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)常用的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 |
4)libcgroup 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.conf是cgred服务的配置文件。 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 Container(LXC)
1、LXC基本概念
1)LXC是什么
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) |
1)LXC的优势
与虚拟化相比,它的优势在于:
a)不需要指令级模拟;
b)不需要即时(Just-in-time)编译;
c)容器可以在CPU核心的本地运行指令,而不需要任何专门的解释机制;
d)避免了准虚拟化和系统调用替换中的复杂性。
总结来说,就是LXC更加轻量级,具有更小的性能开销、更快的相应时间。
2、LXC安装与使用
1)LXC安装
从sourceforge.net/projects/lxc/files/lxc下载lxc源码
解压后进入目录,执行以下命令:
./configure make sudo make install |
2)LXC常用命令
参考: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只启动一个进程,即cmd;lxc-execute 启动两个进程,lxc-init和cmd 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 |