本篇讲的就是利用docker本身的参数进行CPU与内存资源的限制。
1、内存限制
默认docker内存限制可以使用-m参数进行限制,但如果只使用-m参数,不添加其他的,那么内存限制不会限制死,比如-m 256m内存,那么容器里程序可以跑到2*256m后才会被杀死。
原因就是:源码里 memory.memsw.limit_in_bytes 值是被设置成我们指定的内存参数的2倍。
源码地址: https://github.com/docker/libcontainer/blob/v1.2.0/cgroups/fs/memory.go#L39
内容:
// By default, MemorySwap is set to twice the size of RAM. // If you want to omit MemorySwap, set it to `-1'. if d.c.MemorySwap != -1 { if err := writeFile(dir, "memory.memsw.limit_in_bytes", strconv.FormatInt(d.c.Memory*2, 10)); err != nil { return err }
测试一下:
限制内存为2G
# docker run --privileged -d --cpuset-cpus="0,1" -m 2048m --name java101 javatest2:8 /sbin/init # docker exec -it d3e2982e6a7d bash
进入容器使用stress进行内存测试。
安装stress
stress是一个压力测试工具,可测试服务器负载情况
安装命令:
# rpm -Uvh http://pkgs.repoforge.org/stress/stress-1.0.2-1.el7.rf.x86_64.rpm
使用stress进行测试
[root@60fcca8ba4db ~]# stress --vm 1 --vm-bytes 4089M --vm-hang 0 这个命令是跑4089M的内存
参数说明:
--vm-bytes B 指定malloc时内存的字节数(默认256MB)
--vm-hang N 指定在free前的秒数
--vm 1 产生1个进程,每个进程不断调用内存分配malloc和内存释放free函数
[root@60fcca8ba4db ~]# stress --vm 1 --vm-bytes 4089M --vm-hang 0 stress: info: [674] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd stress: FAIL: [674] (420) <-- worker 675 got signal 9 stress: WARN: [674] (422) now reaping child worker processes stress: FAIL: [674] (456) failed run completed in 37s
可以看到程序死了,查看原因
[root@60fcca8ba4db ~]# cat /var/log/messages Mar 21 15:27:52 60fcca8ba4db kernel: Task in /system.slice/docker-60fcca8ba4dbd08c6f064e0bd7be2887bdb301c49360a8386f28bce9bee2201e.scope killed as a result of limit of /system.slice/docker-60fcca8ba4dbd08c6f064e0bd7be2887bdb301c49360a8386f28bce9bee2201e.scope Mar 21 15:27:52 60fcca8ba4db kernel: memory: usage 2097152kB, limit 2097152kB, failcnt 368074 Mar 21 15:27:52 60fcca8ba4db kernel: memory+swap: usage 3827916kB, limit 9007199254740991kB, failcnt 0 Mar 21 15:27:52 60fcca8ba4db kernel: kmem: usage 0kB, limit 9007199254740991kB, failcnt 0 Mar 21 15:27:52 60fcca8ba4db kernel: Memory cgroup stats for /system.slice/docker-60fcca8ba4dbd08c6f064e0bd7be2887bdb301c49360a8386f28bce9bee2201e.scope: cache:2516KB rss:2094636KB rss_huge:0KB mapped_file:2444KB swap:1730764KB inactive_anon:527536KB active_anon:1569412KB inactive_file:56KB active_file:20KB unevictable:0KB Mar 21 15:27:52 60fcca8ba4db kernel: [ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name Mar 21 15:27:52 60fcca8ba4db kernel: [ 1057] 0 1057 10208 94 24 143 0 systemd Mar 21 15:27:52 60fcca8ba4db kernel: [ 1079] 0 1079 11252 631 23 55 0 systemd-journal Mar 21 15:27:52 60fcca8ba4db kernel: [ 1091] 0 1091 10540 9 20 229 -1000 systemd-udevd Mar 21 15:27:52 60fcca8ba4db kernel: [ 1191] 0 1191 20638 1 42 213 -1000 sshd Mar 21 15:27:52 60fcca8ba4db kernel: [ 1193] 0 1193 57518 219 42 441 0 rsyslogd Mar 21 15:27:52 60fcca8ba4db kernel: [ 1194] 81 1194 6615 41 18 41 -900 dbus-daemon Mar 21 15:27:52 60fcca8ba4db kernel: [ 1203] 0 1203 80863 0 81 4219 0 firewalld Mar 21 15:27:52 60fcca8ba4db kernel: [ 1204] 0 1204 6599 30 16 45 0 systemd-logind Mar 21 15:27:52 60fcca8ba4db kernel: [ 1210] 0 1210 31583 4 18 151 0 crond Mar 21 15:27:52 60fcca8ba4db kernel: [ 2191] 0 2191 34288 22 68 295 0 sshd Mar 21 15:27:52 60fcca8ba4db kernel: [ 2194] 0 2194 2943 21 11 79 0 bash Mar 21 15:27:52 60fcca8ba4db kernel: [ 4536] 0 4536 31357 1 17 59 0 anacron Mar 21 15:27:52 60fcca8ba4db kernel: [ 5706] 0 5706 27508 0 10 30 0 agetty Mar 21 15:27:52 60fcca8ba4db kernel: [ 8006] 0 8006 1815 0 8 24 0 stress Mar 21 15:27:52 60fcca8ba4db kernel: [ 8007] 0 8007 1048600 519080 1858 427304 0 stress Mar 21 15:27:52 60fcca8ba4db kernel: Memory cgroup out of memory: Kill process 8007 (stress) score 877 or sacrifice child Mar 21 15:27:52 60fcca8ba4db kernel: Killed process 8007 (stress) total-vm:4194400kB, anon-rss:2076316kB, file-rss:4kB Mar 21 15:27:52 60fcca8ba4db root: [euid=root]:root pts/0 Mar 21 14:40 (192.168.7.173):[/root]2016-03-21 15:27:15 rootstress --vm 1 --vm-bytes 4089M --vm-hang 0 Mar 21 15:30:01 60fcca8ba4db systemd: Started Session 35096 of user root. Mar 21 15:30:01 60fcca8ba4db systemd: Starting Session 35096 of user root.
显示内存使用超过2倍限制的内存,所以进行oom kill掉stress的进程,但容器不会死,仍然能正常运行。
但如果你想写死内存,可以使用
-m 2048m --memory-swap=2048m这样就直接限制死,只要程序内存使用超过1024m,那么就会被oom给kill。
2、CPU限制
目前CPU限制可以使用绑定到具体的线程,或者是在绑定线程基础上对线程资源权重分配。
绑定线程可以使用参数--cpuset-cpus=7 ,分配线程呢可以使用参数-c 来给权重
例如:
docker run --privileged -d -c 1024 --cpuset-cpus="4,5" -m 2048m --name java52 javatest2:8 /sbin/init