docker 的资源限制
docker 资源限制
容器资源限制介绍
官方文档:https://docs.docker.com/config/containers/resource_constraints/
默认情况下,容器没有资源限制,可以使用主机内核调度程序允
许的 尽可能多给定资源, Docker 提供了控制容器可以 限制 容器 使用多少内存或 CPU 的方法, 设置 docker run 命令的运行时配置标志。
其中许多功能都要求宿主机的内核支持 Linux 功能 ,要检查支持,可以使用docker info 命令 ,如果内核中禁用了某项功能 可能会在输出结尾处看到警告, 如下所示:
WARNING: No swap limit support
可通过修改内核参数消除以上警告
范例:
[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发生后的日志信息
产生 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 也可以执行非硬性内存限制,即容器可以使用尽可能多的内存,除非内也可以执行非硬性内存限制,即容器可以使用尽可能多的内存,除非内核检测到主机上的内存不够用了
内存相关选项
以下设置大部分的选项取正整数,跟着一个后缀b
,k
, m
,g
,,表示字节,千字节,兆字节或千兆字节
选项 | 描述 |
---|---|
-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 压力测试工具
stress-ng是一个压力测试工具,可以通过软件仓库进行安装,也提供了docker版本的容器
范例:软件包方式安装
[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
容器的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
范例:限制使用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
范例:限制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
范例:多个容器的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
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/52688.html