• docker容器资源限制:限制容器对内存/CPU的访问


    一.系统环境

    服务器版本 docker软件版本 CPU架构
    CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 x86_64

    二.前言

    默认情况下,容器没有资源限制,并且可以使用主机内核调度程序允许的尽可能多的给定资源。Docker 提供了控制容器可以使用多少内存或 CPU 的方法。

    三.docker对于CPU和内存的限制

    3.1 限制容器对内存的访问

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

    Docker 可以强制执行内存硬限制,允许容器使用不超过给定数量的用户或系统内存,或软限制,允许容器根据需要使用尽可能多的内存,除非满足某些条件,例如何时内核检测到主机内存不足或争用。其中一些选项在单独使用或设置多个选项时具有不同的效果。这些选项中的大多数采用正整数,后跟b, k, m, g, 后缀来表示字节、千字节、兆字节或千兆字节。

    常用的参数有

    参数 参数解释
    -m或者--memory= 容器可以使用的最大内存量。如果设置此选项,则允许的最小值为6m(6 兆字节)。也就是说,您必须将该值设置为至少 6 兆字节。
    --memory-swap* 允许此容器交换到磁盘的内存量。
    --memory-swappiness 默认情况下,主机内核可以换出容器使用的一定百分比的匿名页面。您可以设置--memory-swappiness为 0 到 100 之间的值,以调整此百分比。
    --memory-reservation 允许您指定一个小于--memory在 Docker 检测到主机上的争用或内存不足时激活的软限制。如果使用--memory-reservation,则必须将其设置为低于--memory它才能优先。因为是软限制,所以不保证容器不超过限制。
    --kernel-memory 容器可以使用的最大内核内存量。允许的最小值是4m。因为内核内存不能被换出,内核内存不足的容器可能会阻塞主机资源,这会对主机和其他容器产生副作用。
    --oom-kill-disable 默认情况下,如果发生内存不足 (OOM) 错误,内核会终止容器中的进程。要更改此行为,请使用该--oom-kill-disable选项。仅在您还设置了该-m/--memory选项的容器上禁用 OOM kill。如果-m未设置该标志,主机可能会耗尽内存,内核可能需要终止主机系统的进程以释放内存。

    本次主要使用hub.c.163.com/library/centos:latest镜像测试,没有该镜像需要自己docker pull一下

    [root@k8smaster harbor]# docker images
    REPOSITORY                                                        TAG        IMAGE ID       CREATED         SIZE
    hub.c.163.com/library/centos                                      latest     328edcd84f1b   4 years ago     193MB
    

    上传memload-7.0-1.r29766.x86_64.rpm安装包,用于模拟内存的使用

    [root@k8smaster ~]# mkdir /memload
    
    [root@k8smaster ~]# mv memload-7.0-1.r29766.x86_64.rpm /memload/
    

    使用centos创建一个临时容器,-v /memload:/memload进行数据卷挂载,使容器/memload目录下有memload-7.0-1.r29766.x86_64.rpm安装包

    [root@k8smaster ~]# docker run -it --rm -v /memload:/memload hub.c.163.com/library/centos:latest
    
    #在容器里安装memload
    [root@3c9083a7b318 /]# rpm -ivh /memload/memload-7.0-1.r29766.x86_64.rpm 
    Preparing...                          ################################# [100%]
    Updating / installing...
       1:memload-7.0-1.r29766             ################################# [100%]
    
    #memload 1000使内存使用1000M
    [root@3c9083a7b318 /]# memload 1000
    Attempting to allocate 1000 Mebibytes of resident memory...
    ^C
    
    [root@3c9083a7b318 /]# exit
    exit
    

    当在容器执行memload 1000时,打开另外一个Linux终端,使用docker stats查看该容器的内存使用,发现此容器使用了1013MiB内存,3.32GiB表示物理机的最大内存

    CONTAINER ID   NAME                                                                                                            CPU %     MEM USAGE / LIMIT    MEM %     NET I/O           BLOCK I/O         PIDS
    3c9083a7b318   friendly_roentgen                                                                                               100.71%   1013MiB / 3.32GiB    29.79%    648B / 0B         32.5MB / 19.5MB   2
    
    

    使用-m对容器的内存进行限制,-m 512m:表示容器内存最大使用512M,这时如果我们执行memload 1000,使用docker stats查看,最大内存也只能是512M

    [root@k8smaster ~]# docker run -it --rm -m 512m -v /memload:/memload hub.c.163.com/library/centos:latest
    [root@a81686360ba1 /]# 
    [root@a81686360ba1 /]# exit
    exit
    

    3.2 限制容器对CPU的访问

    默认情况下,每个容器对主机 CPU 周期的访问是无限制的。您可以设置各种约束来限制给定容器对主机 CPU 周期的访问。大多数用户使用和配置 默认的 CFS 调度程序。您还可以配置实时调度程序。

    CFS 是用于普通 Linux 进程的 Linux 内核 CPU 调度程序。几个运行时标志允许您配置对容器拥有的 CPU 资源的访问量。当您使用这些设置时,Docker 会修改主机上容器的 cgroup 的设置。

    常用的参数有

    参数 参数解释
    --cpus= 指定容器可以使用多少可用 CPU 资源。例如,如果主机有两个 CPU,并且您设置--cpus="1.5"了 ,则容器最多可以保证一个半的 CPU。这相当于设置--cpu-period="100000"和--cpu-quota="150000"。
    --cpu-period= 指定 CPU CFS 调度程序周期,它与 --cpu-quota. 默认为 100000 微秒(100 毫秒)。大多数用户不会更改默认设置。对于大多数用例,--cpus是一种更方便的选择。
    --cpu-quota= 对容器施加 CPU CFS 配额。--cpu-period容器在被限制之前被限制的每微秒数。因此充当有效上限。对于大多数用例,--cpus是一种更方便的选择。
    --cpuset-cpus 限制容器可以使用的特定 CPU 或内核。如果您有多个 CPU,则容器可以使用的逗号分隔列表或连字符分隔的 CPU 范围。第一个 CPU 编号为 0。有效值可能是0-3(使用第一个、第二个、第三个和第四个 CPU)或1,3(使用第二个和第四个 CPU)。
    --cpu-shares 将此标志设置为大于或小于默认值 1024 的值,以增加或减少容器的重量,并允许它访问或多或少比例的主机 CPU 周期。这仅在 CPU 周期受到限制时才会强制执行。当有足够多的 CPU 周期可用时,所有容器都会根据需要使用尽可能多的 CPU。这样,这是一个软限制。--cpu-shares不会阻止容器以 swarm 模式调度。它优先考虑可用 CPU 周期的容器 CPU 资源。它不保证或保留任何特定的 CPU 访问权限。

    对CPU的限制一般是设置CPU的亲和性,查看cpu信息:两个CPU:On-line CPU(s) list: 0,1

    [root@k8smaster ~]# 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
    Thread(s) per core:    1
    Core(s) per socket:    2
    座:                 1
    NUMA 节点:         1
    厂商 ID:           GenuineIntel
    CPU 系列:          6
    型号:              142
    型号名称:        Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
    步进:              10
    CPU MHz:             1991.381
    BogoMIPS:            3984.01
    超管理器厂商:  VMware
    虚拟化类型:     完全
    L1d 缓存:          32K
    L1i 缓存:          32K
    L2 缓存:           256K
    L3 缓存:           8192K
    NUMA 节点0 CPU:    0,1
    Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec arat
    

    使用centos镜像创建容器,里面运行5个cat进程

    [root@k8smaster ~]# docker run -it --rm  -v /memload:/memload hub.c.163.com/library/centos:latest
    [root@1a4fff793014 /]# 
    [root@1a4fff793014 /]# cat /dev/zero > /dev/null &
    [1] 15
    [root@1a4fff793014 /]# cat /dev/zero > /dev/null &
    [2] 16
    [root@1a4fff793014 /]# cat /dev/zero > /dev/null &
    [3] 17
    [root@1a4fff793014 /]# cat /dev/zero > /dev/null &
    [4] 18
    [root@1a4fff793014 /]# cat /dev/zero > /dev/null &
    [5] 19
    [root@1a4fff793014 /]# exit 
    exit
    

    当在容器执行5个cat进程之后,打开另外一个Linux终端,查看每个cat进程运行在哪个CPU上,可以看到cat进程都运行在0号和1号CPU上

    [root@k8smaster ~]# ps mo pid,comm,psr `pgrep cat`
       PID COMMAND         PSR
    130120 cat               -
         - -                 0
    130143 cat               -
         - -                 1
    130144 cat               -
         - -                 0
    130145 cat               -
         - -                 1
    130146 cat               -
         - -                 1
    

    --cpuset-cpus=0 设置容器里的进程都运行在0号CPU上

    [root@k8smaster ~]# docker run -it --rm  --cpuset-cpus=0 -v /memload:/memload hub.c.163.com/library/centos:latest
    [root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
    [1] 15
    [root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
    [2] 16
    [root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
    [3] 17
    [root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
    [4] 18
    [root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
    [5] 19
    [root@0c3b37f8e679 /]# 
    [root@0c3b37f8e679 /]# exit
    exit
    

    --cpuset-cpus=1 设置容器里的进程都运行在1号CPU上

    [root@k8smaster ~]# docker run -it --rm  --cpuset-cpus=1 -v /memload:/memload hub.c.163.com/library/centos:latest
    [root@dac513abce35 /]# 
    [root@dac513abce35 /]# cat /dev/zero > /dev/null &
    [1] 15
    [root@dac513abce35 /]# cat /dev/zero > /dev/null &
    [2] 16
    [root@dac513abce35 /]# 
    [root@dac513abce35 /]# cat /dev/zero > /dev/null &
    [3] 17
    [root@dac513abce35 /]# cat /dev/zero > /dev/null &
    [4] 18
    [root@dac513abce35 /]# exit
    exit
    

    --cpuset-cpus=0,1 设置容器里的进程都运行在0,1号CPU上

    [root@k8smaster ~]# docker run -it --rm  --cpuset-cpus=0,1 -v /memload:/memload hub.c.163.com/library/centos:latest
    [root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
    [1] 15
    [root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
    [2] 16
    [root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
    [3] 17
    [root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
    [4] 18
    [root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
    [5] 19
    [root@244fe7eb8707 /]# 
    [root@244fe7eb8707 /]# exit
    exit
    

    --cpuset-cpus=0-7,14 设置容器里的进程都运行在0-7,14号CPU上,由于没有那么多CPU所以报错

    [root@k8smaster ~]# docker run -it --rm  --cpuset-cpus=0-7,14 -v /memload:/memload hub.c.163.com/library/centos:latest
    docker: Error response from daemon: Requested CPUs are not available - requested 0-7,14, available: 0-1.
    See 'docker run --help'.
    

    注意:还可以设置容器对NVIDIA GPU 的访问,不过目前暂时没用到。

  • 相关阅读:
    2563. 统计公平数对的数目
    安装selenium
    智能漏电断路器主要有哪些功能?
    百度百科词条编辑要求,怎样创建百度百科之实操篇
    传输线的阻抗和反射到底是什么关系?
    使用fastlane match自动化管理证书和描述文件
    Intel汇编-内联汇编使用全局变量
    SAP ABAP BDC录屏 保姆级教程
    声明式调用 —— SpringCloud OpenFeign
    Java毕业设计-在线点餐系统
  • 原文地址:https://www.cnblogs.com/renshengdezheli/p/16662622.html