docker高级应用(CPU与内存资源限制)

mfbz0886 9年前

来自: http://www.jixuege.com/?id=55

本篇讲的就是利用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
</div>