docker学习笔记-容器运行时的资源限制

Docker 基于 Linux 内核提供的 cgroups 功能,可以限制容器在运行时使用到的资源,比如内存、CPU、块 I/O、网络等。
控制组(cgroups)是 Linux 内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,
才能避免当多个容器同时运行时对系统资源的竞争。
控制组技术最早是由 Google 的程序员 2006 年起提出,Linux 内核自 2.6.24 开始支持。
控制组可以提供对容器的内存、CPU、磁盘 IO 等资源的限制和审计管理。

cgroup 本身是提供将进程进行分组化管理的功能和接口的基础结构,I/O 或内存的分配控制等具体的资源管理功能是通过这个功能来实现的。

这些具体的资源管理功能称为 cgroup 子系统,有以下几大子系统实现

blkio:设置限制每个块设备的输入输出控制。例如:磁盘,光盘以及 usb 等等。
cpu:使用调度程序为 cgroup 任务提供 cpu 的访问。
cpuacct:产生 cgroup 任务的 cpu 资源报告。
cpuset:如果是多核心的 cpu,这个子系统会为 cgroup 任务分配单独的 cpu 和内存。
devices:允许或拒绝 cgroup 任务对设备的访问。
freezer:暂停和恢复 cgroup 任务。
memory:设置每个 cgroup 的内存限制以及产生内存资源报告。
net_cls:标记每个网络包以供 cgroup 方便使用。
ns:命名空间子系统。
perf_event:增加了对每 group 的监测跟踪的能力,可以监测属于某个特定的 group 的所有线程以及运行在特定CPU上的线程
目前 docker 只是用了其中一部分子系统,实现对资源配额和使用的控制
有关 Linux cgroups 相关的知识查看这篇文章
https://www.cnblogs.com/sammyliu/p/5886833.html

在默认的情况下,docker没有对容器进行硬件资源的限制,当容器负载过高时会尽肯能第占用宿主机资源。
在这基础上,docker提供了针对容器的内存,CPU,IO资源的控制方式。(真正可以控制的只有内存和cpu)
Docker内存控制OOME在linxu系统上,如果内核探测到当前宿主机已经没有可用内存使用,那么会抛出一个OOME(Out Of Memory Exception:内存异常 ),
并且会开启killing去杀掉一些进程。一旦发生OOME,任何进程都有可能被杀死,包括docker daemon在内,
为此,docker特地调整了docker daemon的OOM_Odj优先级,以免他被杀掉,但容器的优先级并未被调整。
经过系统内部复制的计算后,每个系统进程都会有一个OOM_Score得分,OOM_Odj越高,得分越高,
(在docker run的时候可以调整OOM_Odj)得分最高的优先被kill掉,
当然,也可以指定一些特定的重要的容器禁止被OMM杀掉,在启动容器时使用 –oom-kill-disable=true指定。

内存限制的部分参数
容器能使用的内存和交换分区大小。
容器的核心内存大小。
容器虚拟内存的交换行为。
容器内存的软性限制。
是否杀死占用过多内存的容器。
容器被杀死的优先级

-m : 指定容器内存

--memory-swap : 设置容器交换分区大小,设置交换分区必须要设置 -m:依赖前者,容器内与交换分区的关系比较特别,如下:


--memory-swap     --memory     功能

正数S              正数M        容器可用总空间为S,其中ram为M,swap为(S-M),若S=M,则无可用swap资源
O                  正数M        相当于未设置swap (unset)
unset              正数M        若主机(Docker Host)启用了swap,则容器的可用swap为2*M
-l               正数M        若主机(Docker Host)启用了swap,则容器的可使用最大值主机上的所有swap空间的swap资源

注意:在容器内使用free命令可以看到的swap空间并不具有其所展现出的空间指示意义

--oom-kill-disable=true : 禁止容器被oom杀掉,使用该参数要与-m一起使用
CPU的限制
默认情况下,每一个容器可以使用宿主机上的所有cpu资源,但大多数系统使用的资源调度算法是CFS(完全公平调度器),它公平调度每一个工作进程。
进程分cpu密集型和io密集型两类。系统内核会实时监测系统进程,当某个进程占用cpu资源时间过长时,内核会调整该进程的优先级。CPU资源分配策略
共享cpu资源
--cpu-shares: cpu资源提供给一组容器使用,组内的容器按比例使用cpu资源,当容器处于空闲状态时,
cpu资源被负载大的容器占用,(按压缩方式比例分配),当空闲进行运行起来时,cpu资源会被分配到其他容器
--cpus= value : 指定 cpu的核心数量,这种方式直接限定了容器可用的cpu资源
--cpuset-cpus: 指定容器只能运行在哪个cpu核心上(绑定cpu);核心使用0,1,2,3编号;–cpu-share会随机指定cpu
启动一个容器并限制资源
启动容器后,可以使用docker 的监控指令查看容器的运行状态
dockerhub 上下载一个专门的压力测试镜像
docker pull lorel/docker-stess-ng
#模拟出4个繁忙的进程消耗cpu,然后使用-m 模拟进程最大使用的内存数256,使用--vm 指定进程数
#更多参数使用 stress --help查看
docker run --name stress -it --rm -m 256 lorel/docker-stess-ng stess --help
docker run --name stress -it --rm -m 256 lorel/docker-stess-ng stess --vm 2
lscpu
我测试的虚拟机只要2核
docker run --name stress -it --rm -cpus lorel/docker-stess-ng stess --cpu 4
docker run --name stress -it --rm -cpuset-cpus 0,1 lorel/docker-stess-ng stess --cpu 4
docker run --name stress -it --rm -cpu-shares 1024 lorel/docker-stess-ng --cpu 4
docker run --name stress1 -it --rm -cpu-shares 512 lorel/docker-stess-ng --cpu 4
使用docker指令查看容器运行状态,可以容器的内存和cpu都得到了限制,即使给压测时超出了最大内存,也不会额外占用资源
docker top 容器名: 查看容器的进程,不加容器名即查看所有
docker stats 容器名:查看容器的CPU,内存,IO 等使用信息
同样可以在启动的centos 容器中安装相应的工具测试
在容器中安装docker容器压测工具 stress
#先安装一些基础工具
[root@f9420cbbd2a9 /]# yum install wget gcc gcc-c++ make -y
[root@f9420cbbd2a9 ~]# wget http://people.seas.harvard.edu/~apw/stress/stress-1.0.4.tar.gz
[root@f9420cbbd2a9 ~]# tar zxf stress-1.0.4.tar.gz
[root@f9420cbbd2a9 ~]# cd stress-1.0.4
[root@f9420cbbd2a9 stress-1.0.4]./configure
[root@f9420cbbd2a9 stress-1.0.4]# make
[root@f9420cbbd2a9 stress-1.0.4]# make install
在容器使用stress指令进行负载压测
[root@f9420cbbd2a9 ~]# stress  -m 1204m --vm 2

说明:
1. cgroup 只能限制 CPU 的使用,而不能保证CPU的使用。也就是说, 使用 cpuset-cpus,可以让容器在指定的CPU或者核上运行,
但是不能确保它独占这些CPU;cpu-shares 是个相对值,只有在CPU不够用的时候才其作用。也就是说,
当CPU够用的时候,每个容器会分到足够的CPU;不够用的时候,会按照指定的比重在多个容器之间分配CPU。
2. 对内存来说,cgroups 可以限制容器最多使用的内存。使用 -m 参数可以设置最多可以使用的内存
更多详细的内容可以参考这些文章
https://blog.csdn.net/candcplusplus/article/details/53728507
https://blog.51cto.com/wzlinux/2046566

转载于:https://www.cnblogs.com/centos-python/articles/10470842.html

你可能感兴趣的:(docker学习笔记-容器运行时的资源限制)