Cgroups----限制kvm虚拟机

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


Cgroups子系统介绍


blkio    这个子系统为块设备设定输入/输出限制,比如物理设备(磁盘,固态硬盘,USB 等等)。

cpu               这个子系统使用调度程序提供对 CPU cgroup 任务访问。

cpuacct   这个子系统自动生成 cgroup 中任务所使用的 CPU 报告。

cpuset     这个子系统为 cgroup 中的任务分配独立 CPU(在多核系统)和内存节点。

devices   这个子系统可允许或者拒绝 cgroup 中的任务访问设备。

freezer    这个子系统挂起或者恢复 cgroup 中的任务。

memory  这个子系统设定 cgroup 中任务使用的内存限制,并自动生成由那些任务使用的内存资源报告。

net_cls    这个子系统使用等级识别符(classid)标记网络数据包,可允许 Linux 流量控制程序(tc)识别从具体 cgroup 中生成的数据包。

ns          名称空间子系统。


安装kernel-doc查看帮助

# ls/usr/share/doc/kernel-doc-2.6.32/Documentation/cgroups/

00-INDEX                cpuacct.txt    freezer-subsystem.txt    net_prio.txt

blkio-controller.txt  cpusets.txt  memcg_test.txt              resource_counter.txt

cgroups.txt                  devices.txt     memory.txt



通过cgroup来限制KVM虚拟机使用的cpu和内存


启动cgconfig服务

# service cgconfig start


/cgroup 目录下可以看到libvirt目录

# ls /cgroup/cpuset/libvirt/qemu/

cgroup.event_control                puset.memory_spread_page

cgroup.procs                      cpuset.memory_spread_slab

cpuset.cpu_exclusive                 cpuset.mems

cpuset.cpus                       cpuset.sched_load_balance

cpuset.mem_exclusive        cpuset.sched_relax_domain_level

cpuset.mem_hardwall        notify_on_release

cpuset.memory_migrate      tasks

cpuset.memory_pressure


启动虚拟机

# virsh start rhel6u4-6

Domain rhel6u4-6 started


现在可以看到虚拟机rhel6u4-6目录了

# virsh list

Id    Name                           State

----------------------------------------------------

1    rhel6u4-6                     running


# ls /cgroup/cpuset/libvirt/qemu/

cgroup.event_control                cpuset.memory_spread_page

cgroup.procs                      cpuset.memory_spread_slab

cpuset.cpu_exclusive                 cpuset.mems

cpuset.cpus                       cpuset.sched_load_balance

cpuset.mem_exclusive        cpuset.sched_relax_domain_level

cpuset.mem_hardwall        notify_on_release

cpuset.memory_migrate      rhel6u4-6

cpuset.memory_pressure      tasks


# ls /cgroup/cpuset/libvirt/qemu/rhel6u4-6/

cgroup.event_control                     cpuset.memory_spread_slab

cgroup.procs                                  cpuset.mems

cpuset.cpu_exclusive                     cpuset.sched_load_balance

cpuset.cpus                                   cpuset.sched_relax_domain_level

cpuset.mem_exclusive                   emulator

cpuset.mem_hardwall                    notify_on_release

cpuset.memory_migrate                  tasks

cpuset.memory_pressure                  vcpu0

cpuset.memory_spread_page       vcpu1


查看虚拟机使用的cpu

# watch -n 1 virsh vcpuinfo rhel6u4-6


VCPU:                 0

CPU:                  1

State:             running

CPU time:       12.9s

CPU Affinity:   yyyy


VCPU:                 1

CPU:                  0

State:             running

CPU time:       7.0s

CPU Affinity:   yyyy



限制虚拟机只能使用CPU0

# cat/cgroup/cpuset/libvirt/qemu/rhel6u4-6/vcpu0/cpuset.cpus

0-3

# cat/cgroup/cpuset/libvirt/qemu/rhel6u4-6/vcpu1/cpuset.cpus  

0-3

# echo 0 > /cgroup/cpuset/libvirt/qemu/rhel6u4-6/vcpu0/cpuset.cpus

# echo 0 > /cgroup/cpuset/libvirt/qemu/rhel6u4-6/vcpu1/cpuset.cpus



# watch -n 1 virsh vcpuinfo rhel6u4-6

Every 1.0s: virsh vcpuinfo rhel6u4-6                    Wed Sep  4 21:16:27 2013


VCPU:                 0

CPU:                  0

State:             running

CPU time:      13.4s

CPU Affinity:   y---


VCPU:                 1

CPU:                  0

State:             running

CPU time:      7.5s

CPU Affinity:   y---


限制虚拟机使用的内存

# cat/cgroup/memory/libvirt/qemu/rhel6u4-6/memory.limit_in_bytes

1935147008

# cgset -r memory.limit_in_bytes=64Mlibvirt/qemu/rhel6u4-6

# cat/cgroup/memory/libvirt/qemu/rhel6u4-6/memory.limit_in_bytes

67108864


如果虚拟机使用的内存大于限制值,kvm进程将会被内核杀掉

# tail -f /var/log/messages

...

Sep 4 21:44:27 localhost kernel: Memory cgroup out of memory: Kill process9705 (qemu-kvm) score 1000 or sacrifice child

Sep 4 21:44:27 localhost kernel: Killed process 9705, UID 107, (qemu-kvm)total-vm:1471536kB, anon-rss:32708kB, file-rss:4776kB

....


配置文件配置方法

# vim /etc/cgconfig.conf

...

group libvirt/qemu/rhel6u4-6 {

      memory{

             memory.limit_in_bytes=512M;

      }

}


group libvirt {

      cpuset{

             cpuset.cpus=0;

      }

}

group libvirt/qemu {

      cpuset{

             cpuset.cpus=0;

      }

}

group libvirt/qemu/rhel6u4-6 {

      cpuset{

             cpuset.cpus=0;

      }

}

# service cgconfig restart

Stopping cgconfig service:                                 [  OK  ]

Starting cgconfig service:                                 [  OK  ]

# cat/cgroup/memory/libvirt/qemu/rhel6u4-6/memory.limit_in_bytes

536870912

# cat/cgroup/cpuset/libvirt/qemu/rhel6u4-6/cpuset.cpus

0