Docker集群—— Docker资源管理                                                       

【摘要】本文介绍在多核CPU下管理docker对主机资源的使用。通常我们关心的是cpu和内存的使用,本文主要介绍这两个。

1   工具stress

为了测试CPU、内存的使用,需要有一个工具。已经有好心人做好了stress镜像,我直接pull下来了。Stress是一个压力测试工具,简单给出stress的命令参数,以便大家使用:

-? 显示帮助信息

-v 显示版本号

-q 不显示运行信息

-n 显示已完成的指令情况

-t --timeout N 指定运行N秒后停止

--backoff N 等待N微妙后开始运行

-c 产生n个进程  每个进程都反复不停的计算随机数的平方根

-i 产生n个进程  每个进程反复调用sync(),sync()用于将内存上的内容写到硬盘上

-m --vm n 产生n个进程,每个进程不断调用内存分配malloc和内存释放free函数

--vm-bytes B 指定malloc时内存的字节数  (默认256MB)

--vm-hang N 指定在free钱的秒数

-d --hadd n 产生n个执行write和unlink函数的进程

-hadd-bytes B 指定写的字节数

--hadd-noclean 不unlink

时间单位可以为秒s,分m,小时h,天d,年y,文件大小单位可以为K,M,G

一会我就启动一个叫stress的镜像,并给一些参数来测试。

2   Docker 的CPU使用管理

先查看下我的CPU信息:cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq –c

viener@viener-01:~$ cat /proc/cpuinfo | grep name | cut -f2 -d: |  uniq -c

       4  Intel Xeon E312xx (Sandy  Bridge)

这是一个4CPU

cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

4

 

 Centos 系统:

查看逻辑cpu个数:cat /proc/cpuinfo | grep "processor" | wc–l

查看物理cpu个数:cat /proc/cpuinfo | grep "physical id" |sort | uniq | wc -l

如果所有物理cpu的cores个数加起来小于逻辑cpu的个数,则该cpu使用了超线程技术。查看每个物理cpu中逻辑cpu的个数:cat /proc/cpuinfo | grep"siblings"

 

 

 

 

2.1 Docker的亲核

Docker命令可以设置跑在那个核上面。比如:

docker run -it  eminguez/docker-stress-c 3

这条命令表示我启动一个eminguez/docker-stress镜像,命令参数-c 3表示里面产生3个进程。可以看到在4个核上面,3个进程是漂的:

通过top -d 1命令,点f增加Last used cpu信息,用空格增加选中的列:

                                                                                 

PID    USER      PR  NI     VIRT     RES    SHR S %MEM  TIME+    P COMMAND    %CPU 

18516 root      20    0    7268     96       0 R  0.0   3:11.61 3 stress      100.0

18517 root      20    0    7268     96       0 R  0.0   3:11.37 0 stress      100.0

18518 root      20    0    7268     96       0 R  0.0   3:12.07 1 stress       99.1

 

                                                                                 

PID    USER      PR  NI     VIRT     RES    SHR S %MEM  TIME+    P COMMAND    %CPU 

18516 root      20    0    7268     96       0 R  0.0   3:11.61 2 stress      100.0

18517 root      20    0    7268     96       0 R  0.0   3:11.37 3 stress      100.0

18518 root      20    0    7268     96       0 R  0.0   3:12.07 0 stress       99.1

 

通过docker run -it --cpuset=0 eminguez/docker-stress -c 1指定容器启动在cpu0上面

                                                                                 

PID   USER       PR  NI    VIRT      RES    SHR S %MEM  TIME+    P COMMAND    %CPU 

18589  root      20   0     7268     92      0 R   0.0   1:15.92          0 stress  100.0  

可以看到stress进程固定跑在cpu0上面。占用了这个核的全部100%

 

2.2 CPU share

之所以叫share,是因为Docker无法限制一个容器使用CPU的多少。比如只能限制使用20%,超过了就不给用了,无法做到这样。他只能限制一个比例(配额),通过docker run –c 参数。

每个新的容器默认的将有1024CPU配额,当我们单独讲它的时候,这个值并不意味着什么。但是如果我们启动两个容器并且两个都将使用 100%CPUCPU时间将在这两个容器之间平均分割,因为它们两个都有同样的CPU配额(为了简单起见,假设没有任何其他进程在运行)。如果我们设置容器的CPU配额是512,相对于另外一个容器,它将使用一半的CPU时间。但这不意味着它仅仅能使用一半的CPU时间。如果另外一个容器(1024配额的)是空闲的 - 我们的容器将被允许使用100%CPU

比如我使用-c给一个容器256的配额(默认是1024),但是他不会仅使用1/4CPU

docker run -it --cpuset=0 -c 256 eminguez/docker-stress -c 1

                                                                                 

PID    USER      PR  NI     VIRT     RES    SHR S %MEM  TIME+    P COMMAND    %CPU 

18656  root       20   0    7268      92      0 R  0.0    1:15.92          0 stress  100.0  

我们看到他还是使用了CPU 0 100%CPU

 

但是,当我再启动一个容器,也绑定在CPU0上面并且给他768的配额:

dockerrun -it --cpuset=0 -c 768 eminguez/docker-stress -c 1

                                                                                 

PID   USER       PR  NI    VIRT      RES    SHR S %MEM  TIME+    P COMMAND    %CPU 

18753  root      20   0    7268      92      0 R  0.0    0:18.74 0  75.3 stress                                                        

18656  root      20   0     7268     92      0 R   0.0   3:15.27 0  25.8 stress

有趣的事情发生了,刚才的18656进程仅使用到了25.8%CPU,因为他被配额更高的容器抢了CPU使用。

注意:这是将他们绑定到一个cpu上面,如果他们各自使用一个核的话,仍然可以占用全部的CPU

 

3   内存的使用

通过docker run  -m 参数可以控制容器使用的内存大小。

比如,通过docker run -it -m 10m eminguez/docker-stress -m 1 --vm-bytes 19M--vm-hang 1命令启动stress,申请19M的内存,同时限制容器最多使用10M的内存。这时他应该启动不了。

viener@viener-01:~$  docker run -it -m 10m eminguez/docker-stress -m 1 --vm-bytes 19M --vm-hang 1

stress:  info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd

stress:  dbug: [1] using backoff sleep of 3000us

stress:  dbug: [1] --> hogvm worker 1 [6] forked

stress:  dbug: [6] allocating 19922944 bytes ...

stress:  dbug: [6] touching bytes in strides of 4096 bytes ...

stress:  dbug: [6] sleeping for 1s with allocated memory

stress:  dbug: [6] freed 19922944 bytes

stress:  dbug: [6] allocating 19922944 bytes ...

但是他却成功了

因为linux中内存的限制有两块: memory swap 这意味着 Docker 将分配给容器 -m内存值以及 -m swap 值。是限定容器内存的两倍。所以,当我们限制容器10m,并且申请21M的内存时,就运行不了了。

viener@viener-01:~$  docker run -it -m 10m eminguez/docker-stress -m 1 --vm-bytes 21M --vm-hang 1

stress:  info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd

stress:  dbug: [1] using backoff sleep of 3000us

stress:  dbug: [1] --> hogvm worker 1 [5] forked

stress:  dbug: [5] allocating 22020096 bytes ...

stress:  dbug: [5] touching bytes in strides of 4096 bytes ...

stress:  FAIL: [1] (420) <-- worker 5 got signal 9

stress:  WARN: [1] (422) now reaping child worker processes

stress:  FAIL: [1] (426) kill error: No such process

stress:  FAIL: [1] (456) failed run completed in 0s

 

有的机器会出现:WARNING: Yourkernel does not support swap limit capabilities, memory limited without swap.

同时,不管申请多少资源都可以启动,就好像-m参数限制内存没有起作用一样。原因是因为没有限制swap内存使用。可以通过:在/etc/default/grub文件中增加GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1”,之后sudo update-grub并且重启系统,就会发现-m参数生效了。

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐