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