容器系列之docker系统资源限制及验证

Docker的系统资源限制
分析:docker可以实现主要依赖于namespace,control group,默认情况下,一个容器中没有资源限制的,所以它可以几乎消耗完docker主机上所分配的所有资源,在此基础上,docker提供了可控制memory,CPU,内存是非可压缩性资源,CPU是可压缩性资源,当一个容器内的进程消耗完它的内存后,可能会因为OOM被kill掉,而CPU则不影响,kernel可以压缩它不受影响

资源限制


内存:OOME
linux主机上kernel探测到主机内存不足使用,就会发出一个异常,并且开始杀死一些进程一旦发生OOME,任何进程都有可能被杀死,包括docker daemon在内为此,Docker特地的调整了docker daemon的OOM优先级,以免它被内核"正法”,但容器的优先级并未被调整
工作逻辑:在宿主机上,运行了很多的容器中,包括系统级有很多的进程,也包括docker daemon自身的进程,如果内核要执行一些系统管理级的操作,发现内存没有了,启动评估,那个进程是memory hogs(消耗内存最多的进程),一般认为那个比较消耗内存,就会把那个的进程kill,比较快释放内存,但是不一样应该被杀,如A可以消耗内存10G,B可消耗内存1G,A只消耗10分之一,B已经消耗完了,不一定要Kill, 如果没有标准,就以那个进程消耗多,就杀那个进程。
  内核会对进程排优先级,自从到下逆序,一个个的杀掉,直接内存足够使用为止。
  每个进程可以分配OOM obj,每个进程计算好后可以有一个OOM score,得分越高就应该被杀掉的,得分是对它的申请和占用的空间使用一系列复杂的计算来做的,如果计算出后,某个进程是最高的,但是不应该被杀掉,如docker daemon这个进程可以调整优先级处理。每个进程有一个oom adj,也就是权重,优先级越低,得分就变得越少,可以把docker daemon的优先级调低,得分就少,就不会被杀。
  如果一个容器在生产提供重要的服务,它却被杀掉,就很严重,应该开启就要调整它的优先级。而且也可以定义容器的策略,一旦被kill掉,可以restart,

限制容器的访问内存
注:ram是物理内存,swap是交换内存


-m 限制容器的物理内存空间,如4m
--memory-swap * 限制交换内存空间使用,要让它生效,必须先设定-m选项的使用,没有设置物理内存,就不能设置交换分区的
--memory-swappiness 使用memory的倾向性
--memory-reservation 预留的内存空间
--oom-kill-disable 禁止OOM被KILL掉,如容器很消耗内存,又很重要

CPU
默认情况下,每个容器是不限制使用宿主机上CPU资源,可以自行限制,不过大多数用户使用默认的CFS调度,CPU的核心数量是小于进程数的,一个系统上可能运行很多进程,需要运行进程数量大于核心数量时,那个应该优先运行?所以需要调度器来操作,因此内核中进程管理最重要的一个组件是进程调度器,调度进程运行在本地CPU核心上的,那个进程应该被优先运行,非实时的优先级是100-139,实时是0-99,使用nice值来调整[-20,19]非实时的,使用CFS(完全公平调度器),是分配每个进程使用的CPU的,进程还分为两类批处理的和交互式的,交互式的优先级比较高,用户点击mouse就要执行,不然就感觉很慢,但是交互界面使用的CPU的时间都比较短的,但是批处理进程比较消耗CPU,但是通常不需要立刻做出响应,优先级比较低。
  CPU密集型表示对资源占用很大,I/O密集型的是对于I/O资源占用比较大的,对于CPU资源应该尽可能调低它的优先级,因为给它它就会尽可能的使用,内核有算法对这些进程做计算和惩罚,动态调低调高。
选项:
--cpu-shares CPU资源共享,按比例切分系统上所有可用的CPU资源,如当前系统上一共运行了两个容器,权重比是1024:512的值,假设两个容器不需要尽可能多的使用CPU,CPU资源假设有100份,两个容器的比例是2:1,如果第二个容器一启动几乎都不需要CPU资源,这时第一个容器可以占用所有的CPU资源,就是需要就按比例分,不需要就给要用的。CPU是可压缩资源,随时按比例运行。
  还有一个特点:假设有四个核心,有四个容器,各自占用一个,如果其他的三个都不使用,其中一个可以占用四个核心来使用,就是400%的CPU使用率,但是可以限制它们所使用的量
但是限制可以灵活限制,如可以强行运行在那个核心上,或者使用多少的比例(不强制在那颗核心上,总数达到就可以)
--cpus=<value> 一个容器可以使用几核心,可以使用小数,如1.5核(限制数量)
--cpuset-cpus 进程只能运行在那个核心上(限制范围)

[root@node1 ~]# lscpu 
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                2
On-line CPU(s) list:   0,1

下载压力测试docker
https://hub.docker.com/r/lorel/docker-stress-ng/
[root@node1 ~]# docker pull lorel/docker-stress-ng
测试内存
[root@node1 ~]# docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest stress --vm 2
#-m指定可使用的内存大小,--vm启动的子进程,每个进程默认是256MB,所以两个进程是512M,会超出
[root@node1 ~]# docker top stress
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                62910               62884               0                   19:30               pts/0               00:00:00            /usr/bin/stress-ng stress --vm 2
root                62942               62910               0                   19:30               pts/0               00:00:00            /usr/bin/stress-ng stress --vm 2
root                62943               62910               0                   19:30               pts/0               00:00:00            /usr/bin/stress-ng stress --vm 2
root                62965               62942               0                   19:30               pts/0               00:00:00            /usr/bin/stress-ng stress --vm 2
[root@node1 ~]# docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
2dc8f3c34779        stress              28.08%              256MiB / 256MiB     100.01%             648B / 0B           465MB / 16.5GB      5

测试CPU
[root@node1 ~]# docker run --name stress -it --rm --cpus 1 lorel/docker-stress-ng:latest stress --cpu 4
#限制使用1颗核心,启动4个进程来操作
[root@node1 ~]# docker stats
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
5a006d928b2c        stress              99.97%              7.938MiB / 3.686GiB   0.21%               508B / 0B           0B / 0B             5
不限制,它会使用完,因为是两核心,差不多200%
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
abb5cf0e98f9        stress              199.06%             7.934MiB / 3.686GiB   0.21%               578B / 0B           0B / 0B             5

指定使用那个核心
[root@node1 ~]# docker run --name stress -it --rm --cpuset-cpus 1 lorel/docker-stress-ng:latest stress --cpu 4

尽可能使用
[root@node1 ~]# docker run --name stress -it --rm --cpu-shares 1024 lorel/docker-stress-ng:latest stress --cpu 4

  

posted @ 2018-12-02 09:37  Reid21  阅读(610)  评论(0编辑  收藏  举报