Docker 第九章 限制容器的资源

 

容器资源的限制

默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的尽可能多的给定资源。Docker提供了控制容器可以使用多少内存或CPU的方法,设置docker run命令的运行时配置标志。本节提供有关何时应设置此类限制以及设置这些限制的可能含义的详细信息。

其中许多功能都要求您的内核支持Linux功能。要检查支持,可以使用该 docker info命令。如果内核中禁用了某项功能,您可能会在输出结尾处看到警告,如下所示:

WARNING: No swap limit support

了解内存不足的风险

重要的是不要让正在运行的容器占用过多的主机内存。在Linux主机上,如果内核检测到没有足够的内存来执行重要的系统功能,它会抛出一个OOME或者 Out Of Memory Exception,并开始查杀进程以释放内存。任何进程都会被杀死,包括Docker和其他重要的应用程序。如果错误的进程被杀死,这可以有效地降低整个系统。

Docker尝试通过调整Docker守护程序上的OOM优先级来减轻这些风险,以便它比系统上的其他进程更不可能被杀死。容器上的OOM优先级未调整。这使得单个容器被杀死的可能性比Docker守护程序或其他系统进程被杀死的可能性更大。您不应试图通过--oom-score-adj在守护程序或容器上手动设置为极端负数或通过设置容器来绕过这些安全措施--oom-kill-disable。

* docker  通过cgroup  工具来限制容器的资源使用,对于资源最重要的就是cpu 和memory 的使用

 

cgroup  

groups(缩写为控制组)是Linux内核功能,用于限制,计算和隔离进程集合的资源使用情况(CPU,内存,磁盘I / O,网络等)。

Google的工程师(主要是Paul Menage和Rohit Seth)于2006年以“流程容器”的名义开始了这项功能的工作。[1] 在2007年末,命名法改为“控制组”,以避免由Linux内核上下文中“ 容器 ” 一词的多重含义引起的混淆,并且控制组功能在内核版本2.6中合并到Linux内核主线中.24,于2008年1月发布。[2]从那时起,开发人员增加了许多新功能和控制器,例如2014年对kernfs的支持,[3] 防火墙,[4]统一的层次结构。[5]
Cgroups提供:

资源限制
组可以设置为不超过配置的内存限制,其中还包括文件系统缓存[8] [9]
优先级
某些组可能获得更大的CPU利用率[10]或磁盘I / O吞吐量[11]
计费
测量组的资源使用情况,例如,可用于计费目的[12]
控制
冻结进程组,检查点和重新启动[12]
这些具体的资源管理功能称为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上的线程。

操作接口

  在linux系统中一皆文件,当然对CGroup的接口操作也是通过文件来实现的,我们可以通过mount命令查看其挂载目录:

[root@localhost ~]# mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
[root@localhost ~]# 

 以上目录都是可以限制的对象,

[root@localhost ~]# ls /sys/fs/cgroup/memory/docker/
2bf7818020607cd2cded3006c8bf6e76a4424175ddca76ca9bb372913b43bf24  memory.max_usage_in_bytes
aa843c370defc11c303473302caad3367600ad87127bbcd65989ef7cbe4eabad  memory.memsw.failcnt
cgroup.clone_children                                             memory.memsw.limit_in_bytes
cgroup.event_control                                              memory.memsw.max_usage_in_bytes
cgroup.procs                                                      memory.memsw.usage_in_bytes
memory.failcnt                                                    memory.move_charge_at_immigrate
memory.force_empty                                                memory.numa_stat
memory.kmem.failcnt                                               memory.oom_control
memory.kmem.limit_in_bytes                                        memory.pressure_level
memory.kmem.max_usage_in_bytes                                    memory.soft_limit_in_bytes
memory.kmem.slabinfo                                              memory.stat
memory.kmem.tcp.failcnt                                           memory.swappiness
memory.kmem.tcp.limit_in_bytes                                    memory.usage_in_bytes
memory.kmem.tcp.max_usage_in_bytes                                memory.use_hierarchy
memory.kmem.tcp.usage_in_bytes                                    notify_on_release
memory.kmem.usage_in_bytes                                        tasks
memory.limit_in_bytes
[root@localhost ~]# 
#标红的为容器ID 可以被限制的对象

  

 测试

[root@localhost ~]# cd /sys/fs/cgroup/cpu
[root@localhost cpu]# ls
cgroup.clone_children  cpuacct.stat          cpu.cfs_quota_us   cpu.stat           system.slice
cgroup.event_control   cpuacct.usage         cpu.rt_period_us   docker             tasks
cgroup.procs           cpuacct.usage_percpu  cpu.rt_runtime_us  notify_on_release  user.slice
cgroup.sane_behavior   cpu.cfs_period_us     cpu.shares         release_agent
[root@localhost cpu]# mkdir limit_cpu_demo        在 /sys/fs/cgroup/cpu 目录下创建文件默认会在文件下生成限制的配置文件
[root@localhost cpu]# ls
cgroup.clone_children  cpuacct.stat          cpu.cfs_quota_us   cpu.stat           release_agent
cgroup.event_control   cpuacct.usage         cpu.rt_period_us   docker             system.slice
cgroup.procs           cpuacct.usage_percpu  cpu.rt_runtime_us  limit_cpu_demo     tasks
cgroup.sane_behavior   cpu.cfs_period_us     cpu.shares         notify_on_release  user.slice
[root@localhost cpu]# cd limit_cpu_demo/
[root@localhost limit_cpu_demo]# ls
cgroup.clone_children  cpuacct.stat          cpu.cfs_period_us  cpu.rt_runtime_us  notify_on_release
cgroup.event_control   cpuacct.usage         cpu.cfs_quota_us   cpu.shares         tasks
cgroup.procs           cpuacct.usage_percpu  cpu.rt_period_us   cpu.stat
[root@localhost limit_cpu_demo]# 
[root@localhost limit_cpu_demo]# while :; do :; done &    #执行一个循环
[1] 17392
#top
top - 22:47:15 up  1:21,  1 user,  load average: 0.67, 0.21, 0.11
Tasks: 101 total,   2 running,  99 sleeping,   0 stopped,   0 zombie
%Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1863224 total,    81028 free,  1496044 used,   286152 buff/cache
KiB Swap:  4194300 total,  4185844 free,     8456 used.   157824 avail Mem 

如上可见,此时该进程使用的CPU1已经是100%,即%Cpu :100.0 us,我们先来查看我们刚才创建的cpu_limit_demo目录下这两个参数默认值是多少:  

[root@localhost limit_cpu_demo]# cat cpu.cfs_quota_us 
-1
[root@localhost limit_cpu_demo]# cat cpu.cfs_period_us 
100000

  

cpu.cfs_quota_us值为-1代表没有任何限制,cpu.cfs_period_us 则是默认的 100 ms,即100000us,下面将向cpu_limit_demo控制组的cpu.cfs_quota_us文件写入50ms即50000us,这表示在100ms周期内,cpu最多使用%50,同时将该进程的pid号为17406写入对应的tasks文件,表示对那个进程限制:  

 

[root@localhost limit_cpu_demo]# echo 50000 > cpu.cfs_quota_us 

[root@localhost limit_cpu_demo]# echo 17406 > tasks 

  

可以看到cpu 使用率为50% 左右,说明限制生效了。同样的道理,在/sys/fs/cgroup下的子系统都可以限制不通的资源使用如Block IO、Memory等。

  

猜你喜欢

转载自www.cnblogs.com/zy09/p/11075962.html