首页 Docker教程docker-容器资源限制

Docker compse实战案例-实现单机版的Haproxy+Nginx+Tomcat

docker-可视化容器管理工具Portainer

运维派隶属马哥教育旗下专业运维社区,是国内成立最早的IT运维技术社区,欢迎关注公众号:yunweipai
领取学习更多免费Linux云计算、Python、Docker、K8s教程关注公众号:马哥linux运维

docker 的资源限制

docker 资源限制

容器资源限制介绍

官方文档:https://docs.docker.com/config/containers/resource_constraints/

默认情况下,容器没有资源限制,可以使用主机内核调度程序允
许的 尽可能多给定资源, Docker 提供了控制容器可以 限制 容器 使用多少内存或 CPU 的方法, 设置 docker run 命令的运行时配置标志。
其中许多功能都要求宿主机的内核支持 Linux 功能 ,要检查支持,可以使用docker info 命令 ,如果内核中禁用了某项功能 可能会在输出结尾处看到警告, 如下所示:

WARNING: No swap limit support

可通过修改内核参数消除以上警告

官方文档:https://docs.docker.com/install/linux/linux-postinstall/#your-kernel-does-not-support-cgroup-swap-limit-capabilities

范例:

[root@ubuntu1804 ~]#docker info 
Client:
 Debug Mode: false

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 1
 Server Version: 19.03.5
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339
 runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
 init version: fec3683
 Security Options:
  apparmor
  seccomp
   Profile: default
 Kernel Version: 4.15.0-29-generic
 Operating System: Ubuntu 18.04.1 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 1
 Total Memory: 962MiB
 Name: ubuntu1804.magedu.org
 ID: 4LUN:CS4Y:SGYQ:ZAXU:M7C5:JYSB:ZFTO:JZ6D:CD7Q:TOVD:JBFS:AQM3
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  10.0.0.102
  127.0.0.0/8
 Registry Mirrors:
  https://si7y70hh.mirror.aliyuncs.com/
 Live Restore Enabled: false

WARNING: No swap limit support
[root@ubuntu1804 ~]#vim /etc/default/grub
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1 net.ifnames=0" 
[root@ubuntu1804 ~]#update-grub
[root@ubuntu1804 ~]#reboot
[root@ubuntu1804 ~]#docker info
Client:
 Debug Mode: false

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 1
 Server Version: 19.03.5
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339
 runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
 init version: fec3683
 Security Options:
  apparmor
  seccomp
   Profile: default
 Kernel Version: 4.15.0-29-generic
 Operating System: Ubuntu 18.04.1 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 1
 Total Memory: 962MiB
 Name: ubuntu1804.magedu.org
 ID: 4LUN:CS4Y:SGYQ:ZAXU:M7C5:JYSB:ZFTO:JZ6D:CD7Q:TOVD:JBFS:AQM3
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  10.0.0.102
  127.0.0.0/8
 Registry Mirrors:
  https://si7y70hh.mirror.aliyuncs.com/
 Live Restore Enabled: false

[root@ubuntu1804 ~]#
OOM (Out of Memory Exception)

对于 Linux 主机,如果没有足够的内容来执行其他重要的系统任务,将会抛出OOM (Out of Memory Exception,内存溢出、内存泄漏、内存异常 ),随后系统会开始杀死进程以释放内存, 凡是运行在宿主机的进程都有可能被 kill ,包括 Dockerd和其它的应用程序, 如果重要的系统进程被 Kill,会导致和该进程相关的服务全部宕机。通常越消耗内存比较大的应用越容易被kill,比如:mysql数据库,java程序等

范例:OOM发生后的日志信息

docker-容器资源限制插图

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

OOM 优先级机制:

linux会为每个进程算一个分数,最终将分数最高的kill

  • /proc/PID/oom_score_adj #范围为 -1000 到 1000,值越高容易被宿主机 kill掉,如果将该值设置为 -1000 ,则进程永远不会被宿主机 kernel kill
  • /proc/PID/oom_adj #范围为 -17 到+15 ,取值越高越容易被干掉,如果是 -17 , 则表示不能被 kill ,该设置参数的存在是为了和旧版本的 Linux 内核兼容。
  • /proc/PID/oom_score #这个值是系统综合进程的内存消耗量、 CPU 时间 (utime + 、存活时间 (uptime – start time) 和 oom_adj 计算出的进程得分 ,消耗内存越多得分越高,容易被宿主机 kernel 强制杀死

范例:

#按内存排序
[root@ubuntu1804 ~]#top
top - 20:15:38 up  5:53,  3 users,  load average: 0.00, 0.00, 0.00
Tasks: 191 total,   1 running, 116 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :   985104 total,   310592 free,   448296 used,   226216 buff/cache
KiB Swap:  1951740 total,  1892860 free,    58880 used.   384680 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                          
 19674 2019      20   0 2241656  94684  12452 S  0.0  9.6   0:16.05 java                                                             
 19675 2019      20   0 2235512  74816  12440 S  0.0  7.6   0:14.89 java                                                             
 19860 99        20   0  183212  67748    960 S  0.0  6.9   0:01.15 haproxy                                                          
  4969 root      20   0  937880  49352  12612 S  0.0  5.0   0:46.07 dockerd                                                          
  2981 root      20   0  793072  13552   1808 S  0.0  1.4   0:13.78 containerd                                                       
   500 root      19  -1   78560   7552   7112 S  0.0  0.8   0:01.45 systemd-journal                                                  
   798 root      20   0  170416   6604   4084 S  0.0  0.7   0:00.77 networkd-dispat                                                  
     1 root      20   0   78036   6200   4416 S  0.0  0.6   0:05.39 systemd                                                          
  1011 root      20   0   24548   5496   3012 S  0.0  0.6   0:01.62 bash                                                             
   852 root      10 -10   25880   5264   4036 S  0.0  0.5   0:00.00 iscsid                                                           
   815 root      20   0  548292   4624   1224 S  0.0  0.5   0:01.89 snapd                                                            
 19586 root      20   0  109104   4532   3768 S  0.0  0.5   0:00.29 containerd-shim                                                  
 19779 root      20   0  405532   4224   2828 S  0.0  0.4   0:00.01 docker-proxy                                                     
 19784 root      20   0  107696   4204   3652 S  0.0  0.4   0:00.29 containerd-shim                                                  
 19424 root      20   0  109104   4084   3416 S  0.0  0.4   0:00.27 containerd-shim                                                  
 20064 root      20   0   44076   4036   3360 R  0.7  0.4   0:00.20 top                                                              
 19768 root      20   0  405532   4024   2644 S  0.0  0.4   0:00.01 docker-proxy                                                     
 19423 root      20   0  109104   3792   3064 S  0.0  0.4   0:00.31 containerd-shim                                                  
   490 root      20   0  193112   3316   2864 S  0.0  0.3   0:26.20 vmtoolsd                                                         
  7108 root      20   0  105688   3204   2504 S  0.0  0.3   0:00.11 sshd

[root@ubuntu1804 ~]#cat /proc/19674/oom_adj 
0
[root@ubuntu1804 ~]#cat /proc/19674/oom_score
32
[root@ubuntu1804 ~]#cat /proc/19674/oom_score_adj 
0
[root@ubuntu1804 ~]#cat /proc/7108/oom_adj 
0
[root@ubuntu1804 ~]#cat /proc/7108/oom_score
1
[root@ubuntu1804 ~]#cat /proc/7108/oom_score_adj 
0
[root@ubuntu1804 ~]#cat /proc/pidof dockerd/oom_adj
-8
[root@ubuntu1804 ~]#cat /proc/pidof dockerd/oom_score
0
[root@ubuntu1804 ~]#cat /proc/pidof dockerd/oom_score_adj
-500

容器的内存限制

Docker 可以强制执行硬性内存限制,即只允许容器使用给定的内存大小。可以强制执行硬性内存限制,即只允许容器使用给定的内存大小。
Docker 也可以执行非硬性内存限制,即容器可以使用尽可能多的内存,除非内也可以执行非硬性内存限制,即容器可以使用尽可能多的内存,除非内核检测到主机上的内存不够用了

内存相关选项

以下设置大部分的选项取正整数,跟着一个后缀bkmg,,表示字节,千字节,兆字节或千兆字节

选项 描述
-m--memory= 容器可以使用的最大内存量,硬限制,此选项最小允许值为4m(4 MB),此项较常用
--memory-swap* 允许此容器交换到磁盘的内存量
--memory-swappiness 设置容器使用交换分区的倾向性,值越高表示越倾向于使用swap分区,范围为0-100,0为能不用就不用,1000为能用就用
--memory-reservation 允许 指定小于 — memory 的软限制 ,当 Docker 检测到主 机上的争用 或内存不足时会激活该限制,如果使– memorymemory-reservationreservation,则必须 将其设置为低于 — memory 才能使其优先。 因为它是软限制,所以不能保证容器不超过限制
--kernel-memory 容器可以使用的最大内核内存量,最小为 4m,由于内核内存与用户空间内存隔离,因此无法与用户空间内存直接交换,因此内核内存不足的容器可能会阻塞宿主主机资源,这会对主机和其他容器或者其他服务进程产生影响,因此不要设置内核内存大小此项设置
--oom-kill-disable 默认情况下,如果发生内存不足(OOM)错误,则内核将终止容器中的进程。要更改此行为,请使用该--oom-kill-disable选项。仅在设置了该-m/--memory选项的容器上禁用OOM。如果-m未设置该标志,则主机可能会用完内存,内核可能需要终止主机系统的进程以释放内存

范例:

[root@ubuntu1804 ~]#docker run -e MYSQL_ROOT_PASSWORD=123456 -it --rm -m 1g --oom-kill-disable mysql:5.7.29
2020-02-04 13:11:54+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.29-1debian9 started.
2020-02-04 13:11:54+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2020-02-04 13:11:54+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.29-1debian9 started.
2020-02-04 13:11:54+00:00 [Note] [Entrypoint]: Initializing database files
......
Version: '5.7.29'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

范例:

[root@ubuntu1804 ~]#sysctl  -a |grep swappiness
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.docker0.stable_secret"
sysctl: reading key "net.ipv6.conf.eth0.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
vm.swappiness = 60
swap限制
--memory-swap #只有在设置了 --memory 后才会有意义。使用 Swap,可以让容器将超出限制部分的内存置换到磁盘上,WARNING:经常将内存交换到磁盘的应用程序会降低性能

不同的–memory-swap 设置会产生不同的效果:

-memory-swap #值为正数, 那么--memory 和--memory-swap 都必须要设置,--memory-swap 表示你能使用的内存和 swap 分区大小的总和,例如: --memory=300m, --memory-swap=1g, 那么该容器能够使用 300m 物理内存和 700m swap,即--memory 是实际物理内存大小值不变,而 swap 的实际大小计算方式为(--memory-swap)-(--memory)=容器可用 swap
--memory-swap #如果设置为 0,则忽略该设置,并将该值视为未设置,即未设置交换分区 
--memory-swap #如果等于--memory 的值,并且--memory 设置为正整数,容器无权访问 swap 
-memory-swap #如果未设置,如果宿主机开启了 swap,则实际容器的swap 值最大为 2x( --memory),即两倍于物理内存大小,例如,如果--memory="300m"与--memory-swap没有设置,该容器可以使用300m总的内存和600m交撒空间,但是并不准确(在容器中使用free 命令所看到的 swap 空间并不精确,毕竟每个容器都可以看到具体大小,宿主机的 swap 是有上限的,而且不是所有容器看到的累计大小)
--memory-swap #如果设置为-1,如果宿主机开启了 swap,则容器可以使用主机上 swap 的最大空间

注意:在容器中执行free命令看到的是宿主机的内存和swap使用,而非容器自身的swap使用情况

范例:

[root@ubuntu1804 ~]#free 
              total        used        free      shared  buff/cache   available
Mem:        3049484      278484     1352932       10384     1418068     2598932
Swap:       1951740           0     1951740
[root@ubuntu1804 ~]#docker run -it --rm -m 2G centos:centos7.7.1908 bash
[root@f5d387b5022f /]# free 
              total        used        free      shared  buff/cache   available
Mem:        3049484      310312     1320884       10544     1418288     2566872
Swap:       1951740           0     1951740
[root@f5d387b5022f /]#
stress-ng 压力测试工具

docker-容器资源限制插图(1)

stress-ng是一个压力测试工具,可以通过软件仓库进行安装,也提供了docker版本的容器

docker-容器资源限制插图(2)

范例:软件包方式安装

[root@centos7 ~]#yum -y install stress-ng
[root@ubuntu1804 ~]#apt -y install stress-ng

范例:容器安装

[root@ubuntu1804 ~]#docker pull lorel/docker-stress-ng
Using default tag: latest
latest: Pulling from lorel/docker-stress-ng
Image docker.io/lorel/docker-stress-ng:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
c52e3ed763ff: Pull complete 
a3ed95caeb02: Pull complete 
7f831269c70e: Pull complete 
Digest: sha256:c8776b750869e274b340f8e8eb9a7d8fb2472edd5b25ff5b7d55728bca681322
Status: Downloaded newer image for lorel/docker-stress-ng:latest
docker.io/lorel/docker-stress-ng:latest
[root@ubuntu1804 ~]#docker images 
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
lorel/docker-stress-ng   latest              1ae56ccafe55        3 years ago         8.1MB

范例:查看帮助

[root@ubuntu1804 ~]#docker run -it --rm lorel/docker-stress-ng
stress-ng, version 0.03.11

Usage: stress-ng [OPTION [ARG]]
 --h,  --help             show help
       --affinity N       start N workers that rapidly change CPU affinity
       --affinity-ops N   stop when N affinity bogo operations completed
       --affinity-rand    change affinity randomly rather than sequentially
       --aio N            start N workers that issue async I/O requests
       --aio-ops N        stop when N bogo async I/O requests completed
       --aio-requests N   number of async I/O requests per worker
......
       --zero-ops N       stop when N /dev/zero bogo read operations completed

Example: stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s

Note: Sizes can be suffixed with B,K,M,G and times with s,m,h,d,y
[root@ubuntu1804 ~]#

假如一个容器未做内存使用限制,则该容器可以利用到系统内存最大空间,默认创建的容器没有做内存资源限制。

范例:默认一个works 分配256M内存,2个即占512M内存

[root@ubuntu1804 ~]#docker run --name c1 -it --rm lorel/docker-stress-ng --vm 2 
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

#因上一个命令是前台执行,下面在另一个终端窗口中执行,可以看到占用512M左右内存
[root@ubuntu1804 ~]#docker stats 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
fd184869ff7e        c1                  91.00%              524.3MiB / 962MiB   54.50%              766B / 0B           860kB / 0B          5

范例:指定内存最大值

[root@ubuntu1804 ~]#docker run --name c1 -it --rm -m 300m lorel/docker-stress-ng --vm 2 
WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

[root@ubuntu1804 ~]#vim /etc/default/grub
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1  net.ifnames=0"
[root@ubuntu1804 ~]#update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.15.0-29-generic
Found initrd image: /boot/initrd.img-4.15.0-29-generic
done
[root@ubuntu1804 ~]#reboot
[root@ubuntu1804 ~]#docker run --name c1 -it --rm -m 300m lorel/docker-stress-ng --vm 2 
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

#在另一个终端窗口执行
[root@ubuntu1804 ~]#docker stats --no-stream
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
6a93f6b22034        c1                  27.06%              297.2MiB / 300MiB   99.07%              1.45kB / 0B         4.98GB / 5.44GB     5

范例:

[root@ubuntu1804 ~]#docker run --name c2 -it --rm  lorel/docker-stress-ng --vm 4 
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 vm
[root@ubuntu1804 ~]#docker stats --no-stream
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
fd5fff3c04f7        c2                  21.20%              591.1MiB / 962MiB   61.45%              1.31kB / 0B         1.07GB / 46.6MB     9
[root@ubuntu1804 ~]#

范例:OOM

[root@ubuntu1804 ~]#docker run -it --rm  lorel/docker-stress-ng --vm 6 
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 6 vm

#另一个终端窗中同时执行下面命令
[root@ubuntu1804 ~]#docker run  -it --rm  lorel/docker-stress-ng --vm 6
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 6 vm

[root@ubuntu1804 ~]#docker stats 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
f33cebf5b55d        c2                  --                  -- / --             --                  --                  --                  --
b14b597c5a4f        cool_banach         --                  -- / --             --                  --                  --                  --

#观察日志出现OOM现象
[root@ubuntu1804 ~]#tail  /var/log/syslog 
Feb  4 22:59:40 ubuntu1804 kernel: [  785.928835] [ 2575]     0  2575    67104    39218   544768    22906          1000 stress-ng-vm
Feb  4 22:59:40 ubuntu1804 kernel: [  785.928836] [ 2594]     0  2594    67104    37503   409600     7725          1000 stress-ng-vm
Feb  4 22:59:40 ubuntu1804 kernel: [  785.928837] [ 2601]     0  2601    67104    38815   438272     9779          1000 stress-ng-vm
Feb  4 22:59:40 ubuntu1804 kernel: [  785.928838] [ 2602]     0  2602     1568      861    49152        0          1000 stress-ng-vm
Feb  4 22:59:40 ubuntu1804 kernel: [  785.928839] [ 2610]     0  2610     1568      861    49152        0          1000 stress-ng-vm
Feb  4 22:59:40 ubuntu1804 kernel: [  785.928840] [ 2614]     0  2614     1157      174    53248        0             0 update-motd-hwe
Feb  4 22:59:40 ubuntu1804 kernel: [  785.928841] [ 2615]     0  2615     3100       15    61440        0             0 apt-config
Feb  4 22:59:40 ubuntu1804 kernel: [  785.928842] Out of memory: Kill process 2570 (stress-ng-vm) score 1090 or sacrifice child
Feb  4 22:59:40 ubuntu1804 kernel: [  785.929493] Killed process 2570 (stress-ng-vm) total-vm:268416kB, anon-rss:170352kB, file-rss:632kB, shmem-rss:28kB
Feb  4 22:59:40 ubuntu1804 kernel: [  786.018319] oom_reaper: reaped process 2570 (stress-ng-vm), now anon-rss:0kB, file-rss:0kB, shmem-rss:28kB

范例:查看内存限制

#启动两个工作进程,每个工作进程最大允许使用内存 256M,且宿主机不限制当前容器最大内存
[root@ubuntu1804 ~]#docker run  -it --rm  lorel/docker-stress-ng --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

[root@ubuntu1804 ~]#docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS               NAMES
13e46172e1ae        lorel/docker-stress-ng   "/usr/bin/stress-ng …"   24 seconds ago      Up 22 seconds                           gallant_moore

[root@ubuntu1804 ~]#ls /sys/fs/cgroup/memory/docker/
13e46172e1ae8593569f05a3bebc7b41b7839da44369d43b29102661364ac2cd  memory.kmem.tcp.limit_in_bytes      memory.numa_stat
cgroup.clone_children                                             memory.kmem.tcp.max_usage_in_bytes  memory.oom_control
cgroup.event_control                                              memory.kmem.tcp.usage_in_bytes      memory.pressure_level
cgroup.procs                                                      memory.kmem.usage_in_bytes          memory.soft_limit_in_bytes
memory.failcnt                                                    memory.limit_in_bytes               memory.stat
memory.force_empty                                                memory.max_usage_in_bytes           memory.swappiness
memory.kmem.failcnt                                               memory.memsw.failcnt                memory.usage_in_bytes
memory.kmem.limit_in_bytes                                        memory.memsw.limit_in_bytes         memory.use_hierarchy
memory.kmem.max_usage_in_bytes                                    memory.memsw.max_usage_in_bytes     notify_on_release
memory.kmem.slabinfo                                              memory.memsw.usage_in_bytes         tasks
memory.kmem.tcp.failcnt                                           memory.move_charge_at_immigrate                 

[root@ubuntu1804 ~]#cat /sys/fs/cgroup/memory/docker/13e46172e1ae8593569f05a3bebc7b41b7839da44369d43b29102661364ac2cd/memory.limit_in_bytes
9223372036854771712
[root@ubuntu1804 ~]#echo 2^63|bc
9223372036854775808

范例:内存限制200m

#宿主机限制容器最大内存使用: 
[root@ubuntu1804 ~]#docker run  -it --rm  -m 200M lorel/docker-stress-ng --vm 2 --vm-bytes 256M 
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
f69729b2acc1        sleepy_haibt        85.71%              198MiB / 200MiB     98.98%              1.05kB / 0B         697MB / 60.4GB      5
[root@ubuntu1804 ~]#

#查看宿主机基于 cgroup 对容器进行内存资源的大小限制 
[root@ubuntu1804 ~]#cat /sys/fs/cgroup/memory/docker/f69729b2acc16e032658a4efdab64d21ff97dcb6746d1cef451ed82d5c98a81f/memory.limit_in_bytes
209715200

[root@ubuntu1804 ~]#echo 209715200/1024/1024|bc
200

#动态修改内存限制
[root@ubuntu1804 ~]#echo 300*1024*1024|bc
314572800
[root@ubuntu1804 ~]#echo 314572800 > /sys/fs/cgroup/memory/docker/f69729b2acc16e032658a4efdab64d21ff97dcb6746d1cef451ed82d5c98a81f/memory.limit_in_bytes
[root@ubuntu1804 ~]#cat /sys/fs/cgroup/memory/docker/f69729b2acc16e032658a4efdab64d21ff97dcb6746d1cef451ed82d5c98a81f/memory.limit_in_bytes
314572800
[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
f69729b2acc1        sleepy_haibt        76.69%              297.9MiB / 300MiB   99.31%              1.05kB / 0B         1.11GB / 89.1GB     5

#通过echo 命令可以改内存限制的值,但是可以在原基础之上增大内存限制,缩小内存限制会报错write error: Device or resource busy 
[root@ubuntu1804 ~]#echo 209715200 > /sys/fs/cgroup/memory/docker/f69729b2acc16e032658a4efdab64d21ff97dcb6746d1cef451ed82d5c98a81f/memory.limit_in_bytes
-bash: echo: write error: Device or resource busy
[root@ubuntu1804 ~]#cat /sys/fs/cgroup/memory/docker/f69729b2acc16e032658a4efdab64d21ff97dcb6746d1cef451ed82d5c98a81f/memory.limit_in_bytes
314572800

范例:内存大小软限制:

[root@ubuntu1804 ~]#docker run -it --rm  -m 256m --memory-reservation 128m --name magedu-c1 lorel/docker-stress-ng --vm 2 --vm-bytes 256M 
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
aeb38acde581        magedu-c1           72.45%              253.9MiB / 256MiB   99.20%              976B / 0B           9.47GB / 39.4GB     5
#查看硬限制
[root@ubuntu1804 ~]#cat /sys/fs/cgroup/memory/docker/aeb38acde58155d421f998a54e9a99ab60635fe00c9070da050cc49a2f62d274/memory.limit_in_bytes 
268435456

#查看软限制
[root@ubuntu1804 ~]#cat /sys/fs/cgroup/memory/docker/aeb38acde58155d421f998a54e9a99ab60635fe00c9070da050cc49a2f62d274/memory.soft_limit_in_bytes 
134217728

#软限制不能高于硬限制
[root@ubuntu1804 ~]#docker run -it --rm  -m 256m --memory-reservation 257m --name magedu-c1 lorel/docker-stress-ng --vm 2 --vm-bytes 256M 
docker: Error response from daemon: Minimum memory limit can not be less than memory reservation limit, see usage.
See 'docker run --help'.

关闭OOM 机制:

# docker run -it --rm  -m 256m --oom-kill-disable --name magedu-c1  lorel/docker-stress-ng --vm 2 --vm-bytes 256M 
# cat /sys/fs/cgroup/memory/docker/容器 ID/memory.oom_control 
oom_kill_disable 1 
under_oom 1 
oom_kill 0 

范例:关闭OOM机制

#查看docker OOM机制默认值
[root@ubuntu1804 ~]#cat /sys/fs/cgroup/memory/docker/memory.oom_control 
oom_kill_disable 0
under_oom 0
oom_kill 0

#启动容器时关闭OOM机制 
[root@ubuntu1804 ~]#docker run -it --rm  -m 200m --oom-kill-disable   lorel/docker-stress-ng --vm 2 --vm-bytes 256M 
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
b655d88228c0        silly_borg          0.00%               197.2MiB / 200MiB   98.58%              1.31kB / 0B         1.84MB / 484MB      5
[root@ubuntu1804 ~]#c

[root@ubuntu1804 ~]#cat /sys/fs/cgroup/memory/docker/b655d88228c04d7db6a6ad833ed3d05d4cd596ef09834382e17942db0295dc0c/memory.oom_control 
oom_kill_disable 1
under_oom 1
oom_kill 0
[root@ubuntu1804 ~]#

交换分区限制:

# docker run -it --rm  -m 256m  --memory-swap 512m  --name magedu-c1  centos bash 
#宿主机cgroup验证: 
# cat /sys/fs/cgroup/memory/docker/容器 ID/memory.memsw.limit_in_bytes 536870912  #返回值 

范例:

[root@ubuntu1804 ~]#docker run -it --rm  -m 200m --memory-swap 512m  lorel/docker-stress-ng --vm 2 
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

[root@ubuntu1804 ~]#cat /sys/fs/cgroup/memory/docker/23733a0cafa21f3e94ca8c96110978b12e53076261f1b92fd2052bafe659c8ab/memory.memsw.limit_in_bytes 
536870912

kubernets 对swap的要求

K8s 1.8.3更新日志:
宿主机开启交换分区,会在安装之前的预检查环节提示相应错误信息: https://github.com/kubernetes/kubernetes/blob/release-1.8/CHANGELOG-1.8.md

docker-容器资源限制插图(3)

容器的CPU限制

容器的CPU限制介绍

官方文档说明:https://docs.docker.com/config/containers/resource_constraints/

一个宿主机,有几十个核心的CPU,但是宿主机上可以同时运行成百上千个不同的进程用以处理不同的任务,多进程共用一个 CPU 的核心依赖计数就是为可压缩资源,即一个核心的 CPU 可以通过调度而运行多个进程,但是同一个单位时间内只能有一个进程在 CPU 上运行,那么这么多的进程怎么在 CPU 上执行和调度的呢?

Linux kernel 进程的调度基于CFS(Completely Fair Scheduler),完全公平调度

服务器资源密集型

  • CPU 密集型的场景:优先级越低越好,计算密集型任务的特点是要进行大量的计算,消耗CPU 资源,比如计算圆周率、数据处理、对视频进行高清解码等等,全靠CPU 的运算能力。
  • IO 密集型的场景:优先级值高点,涉及到网络、磁盘IO 的任务都是IO 密集型任务,这类任务的特点是 CPU 消耗很少,任务的大部分时间都在等待 IO 操作完成(因为 IO 的速度远远低于 CPU 和内存的速度),比如 Web 应用,高并发,数据量大的动态网站来说,数据库应该为IO 密集型

CFS原理
cfs定义了进程调度的新模型,它给cfs_rq(cfs的run queue)中的每一个进程安排一个虚拟时钟,vruntime。如果一个进程得以执行,随着时间的增长,其vruntime将不断增大。没有得到执行的进程vruntime不变, 而调度器总是选择vruntime跑得最慢的那个进程来执行。这就是所谓的“完全公平”。为了区别不同优先级的进程,优先级高的进程vruntime增长得慢,以至于它可能得到更多的运行机会。
CFS的意义在于, 在一个混杂着大量计算型进程和IO交互进程的系统中,CFS调度器相对其它调度器在对待IO交互进程要更加友善和公平。

范例:查看磁盘调度算法

[root@ubuntu1804 ~]#cat /sys/block/sda/queue/scheduler 
noop deadline [cfq] 
配置默认的CFS调度程序

默认情况下,每个容器对主机的CPU周期的访问都是不受限制的。您可以设置各种约束,以限制给定容器对主机CPU周期的访问。大多数用户使用并配置 默认的CFS调度程序。在Docker 1.13及更高版本中,还可以配置 realtime scheduler

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

选项 描述
--cpus= 指定一个容器可以使用多少可用的CPU资源。例如,如果主机有两个CPU,如果设置了--cpus="1.5",则可以保证容器最多使用1.5个的CPU(如果是4核CPU,那么还可以是4核心上每核用一点,但是总计是1.5核心的CPU)。这相当于设置--cpu-period="100000"--cpu-quota="150000"。此设置可在Docker 1.13及更高版本中可用,目的是替代–cpu-period和–cpu-quota两个参数,从而使配置更简单,但是最大不能超出宿主机的CPU总核心数(在操作系统看到的CPU超线程后的数值),此项较常用
--cpu-period= 指定CPU CFS调度程序周期,必须与--cpu-quota一起使用 。默认为100微秒。大多数用户不会更改默认设置。如果您使用Docker 1.13或更高版本,请改用--cpus
--cpu-quota= 在容器上添加 CPU CFS 配额,计算方式为 cpu-quota / cpu-period的结果值,docker1.13 及以上版本通常使用–cpus 设置此值
--cpuset-cpus 用于指定容器运行的 CPU 编号,也就是所谓的CPU绑定。如果一个或多个CPU,则容器可以使用逗号分隔的列表或用连字符分隔的CPU范围。第一个CPU的编号为0。有效值可能是0-3(使用第一,第二,第三和第四CPU)或1,3(使用第二和第四CPU)
--cpu-shares 用于设置 cfs 中调度的相对最大比例权重,cpu-share 的值越高的容器,将会分得更多的时间片(宿主机多核 CPU 总数为 100%,假如容器 A 为1024,容器 B 为 2048,那么容器 B 将最大是容器 A 的可用 CPU 的两倍 ),默认的时间片 1024,最大 262144。这是一个软限制。
使用stress-ng测试cpu配置

范例:查看关于cpu的帮助

[root@ubuntu1804 ~]#docker run -it --rm  --name magedu-c1  lorel/docker-stress-ng  |grep cpu
 -c N, --cpu N            start N workers spinning on sqrt(rand())
       --cpu-ops N        stop when N cpu bogo operations completed
 -l P, --cpu-load P       load CPU by P %%, 0=sleep, 100=full load (see -c)
       --cpu-method m     specify stress cpu method m, default is all
Example: stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s
[root@ubuntu1804 ~]#

范例:不限制容器CPU

[root@ubuntu1804 ~]#lscpu |grep CPU
CPU op-mode(s):      32-bit, 64-bit
CPU(s):              6
On-line CPU(s) list: 0-5
CPU family:          6
Model name:          Intel(R) Core(TM) i7-4710HQ CPU @ 2.50GHz
CPU MHz:             2494.236
NUMA node0 CPU(s):   0-5

[root@ubuntu1804 ~]#docker run -it --rm   lorel/docker-stress-ng  --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm

[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
818a85e1da2f        frosty_taussig      595.57%             1.037GiB / 2.908GiB   35.64%              1.12kB / 0B         0B / 0B             13
[root@ubuntu1804 ~]#cat /sys/fs/cgroup/cpuset/docker/818a85e1da2f9a4ef297178a9dc09b338b2308108195ad8d4197a1c47febcbff/cpuset.cpus
0-5
[root@ubuntu1804 ~]#top

docker-容器资源限制插图(4)

范例:限制使用CPU

[root@ubuntu1804 ~]#docker run -it --rm  --cpus 1.5  lorel/docker-stress-ng  --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm

[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
9f8b2e693113        busy_hodgkin        147.71%             786.8MiB / 2.908GiB   26.42%              836B / 0B           0B / 0B             13
[root@ubuntu1804 ~]#top

docker-容器资源限制插图(5)

范例:限制CPU

[root@ubuntu1804 ~]#docker run -it --rm  --cpu-quota 2000 --cpu-period 1000  lorel/docker-stress-ng  --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm

[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                     CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
bd949bb6698e        affectionate_chebyshev   185.03%             1.037GiB / 2.908GiB   35.64%              836B / 0B           0B / 0B             13
[root@ubuntu1804 ~]#

范例:绑定CPU

#一般不建议绑在0号CPU上,因0号CPU一般会较忙
[root@ubuntu1804 ~]#docker run -it --rm  --cpus 1.5  --cpuset-cpus 2,4-5 lorel/docker-stress-ng  --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm

[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
585879094e73        hungry_albattani    154.35%             1.099GiB / 2.908GiB   37.79%              906B / 0B           0B / 0B             13
[root@ubuntu1804 ~]#cat /sys/fs/cgroup/cpuset/docker/585879094e7382d2ef700947b4454426eee7f943f8d1438fe42ce34df789227b/cpuset.cpus 
2,4-5
[root@ubuntu1804 ~]#top

docker-容器资源限制插图(6)

范例:多个容器的CPU利用率比例

#同时开两个容器
[root@ubuntu1804 ~]#docker run -it --rm  --name c1 --cpu-shares 1000  lorel/docker-stress-ng  --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm
[root@ubuntu1804 ~]#docker run -it --rm  --name c2 --cpu-shares 500  lorel/docker-stress-ng  --cpu 4 --vm 4
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 4 cpu, 4 vm

[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
a1d4c6e6802d        c2                  195.88%             925.3MiB / 2.908GiB   31.07%              726B / 0B           0B / 0B             13
d5944104aff4        c1                  398.20%             1.036GiB / 2.908GiB   35.64%              906B / 0B           0B / 0B             13
[root@ubuntu1804 ~]#

#查看c1容器的cpu利用比例
[root@ubuntu1804 ~]#cat /sys/fs/cgroup/cpu,cpuacct/docker/d5944104aff40b7b76f536c45a68cd4b98ce466a73416b68819b9643e3f49da7/cpu.shares 
1000

#查看c2容器的cpu利用比例
[root@ubuntu1804 ~]#cat /sys/fs/cgroup/cpu,cpuacct/docker/a1d4c6e6802d1b846b33075f3c1e1696376009e85d9ff8756f9a8d93d3da3ca6/cpu.shares 
500

#再打开新的容器,cpu分配比例会动态调整
[root@ubuntu1804 ~]#docker run -it --rm  --name c3 --cpu-shares 2000  lorel/docker-stress-ng  --cpu 4 --vm 4

[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
c2d54818e1fe        c3                  360.15%             664.5MiB / 2.908GiB   22.31%              726B / 0B           1.64GB / 150MB      13
a1d4c6e6802d        c2                  82.94%              845.2MiB / 2.908GiB   28.38%              936B / 0B           103MB / 4.54MB      13
d5944104aff4        c1                  181.18%             930.1MiB / 2.908GiB   31.23%              1.12kB / 0B         303MB / 19.8MB      13

范例:动态调整cpu shares值

[root@ubuntu1804 ~]#echo 2000 > /sys/fs/cgroup/cpu,cpuacct/docker/a1d4c6e6802d1b846b33075f3c1e1696376009e85d9ff8756f9a8d93d3da3ca6/cpu.shares
[root@ubuntu1804 ~]#docker stats --no-stream 
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
a1d4c6e6802d        c2                  389.31%             1.037GiB / 2.908GiB   35.64%              1.01kB / 0B         1.16GB / 14MB       13
d5944104aff4        c1                  200.28%             1.036GiB / 2.908GiB   35.63%              1.19kB / 0B         2.66GB / 26.7MB     13
[root@ubuntu1804 ~]#

本文链接:http://www.yunweipai.com/34981.html

Docker compse实战案例-实现单机版的Haproxy+Nginx+Tomcat

docker-可视化容器管理工具Portainer

网友评论comments

发表评论

邮箱地址不会被公开。

暂无评论

Copyright © 2012-2021 YUNWEIPAI.COM - 运维派 京ICP备16064699号-6
扫二维码
扫二维码
返回顶部