八、docker资源限制
默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的尽可能多的给定资源,Docker提供了可以限制容器使用多少内存或CPU的方法,通过设置docker run命令的运行参数进行限制。
其中许多功能都要求宿主机的内核支持Linux功能,要检查支持,可以使用
docker info命令,如果内核中禁用了某项功能,可能会在输出结尾处看到警告,如下所示:
WARNING: No sWap limit support
官网:https://docs.docker.com/engine/containers/resource_constraints/
8.1 容器的内存限制
Docker可以强制执行硬性内存限制,即只允许容器使用给定的内存大小。
Docker 也可以执行非硬性内存限制,即容器可以使用尽可能多的内存,除非内核检测到主机上的内存不够用了。
如果容器没有做内存使用限制,则该容器可以利用到系统内存最大空间,默认创建的容器没有做内存资源限制。
docker run参数说明:
-m或者–memory #表示容器可以使用的最大内存量,硬限制
–memory-reservation #指定小于–memory的软限制,当docker检测到主机上的内存不足时会激活该限制,该值不能超过。
#运行容器,未指定内存限制
[root@localhost stress-ng]# docker run --rm -it --name busybox busybox:latest /bin/sh/ ##在另外一个终端查看当前容器的内存限制,可以看到未做任何限制和物理机可使用大小一致
[root@localhost ~]# docker stats busybox
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
cab5f5417a55 busybox 0.00% 892KiB / 3.532GiB 0.02% 2.42kB / 0B 0B / 0B 1#使用-m选项设定硬限制
[root@localhost stress-ng]# docker run -m 256m --rm -it --name busybox busybox:latest /bin/sh
/ #
#另一个终端查看当前容器的内存限制,可以看到限制为256MB
[root@localhost ~]# docker stats busybox
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
ed4193744afb busybox 0.00% 892KiB / 256MiB 0.34% 2.42kB / 0B 0B / 0B 1
#容器的硬限制不能比软限制小
[root@localhost stress-ng]# docker run -m 128m --memory-reservation 256m --rm -it --name busybox busybox:latest /bin/sh
docker: Error response from daemon: Minimum memory limit can not be less than memory reservation limit, see usage.
See 'docker run --help'.
[root@localhost stress-ng]# docker run -m 256m --memory-reservation 256m --rm -it --name busybox busybox:latest /bin/sh#查看容器内存限制
[root@localhost ~]# docker stats busybox
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
07a467461a60 busybox 0.00% 884KiB / 256MiB 0.34% 2.49kB / 0B 0B / 0B 1
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
07a467461a60 busybox 0.00% 884KiB / 256MiB 0.34% 2.49kB / 0B 0B / 0B 1
8.2 容器的CPU限制
一个宿主机,有几十个核心的CPU,但是宿主机上可以同时运行成百上千个不
同的进程用以处理不同的任务,多进程共用一个CPU的核心依赖技术就是为可
压缩资源,即一个核心的CPU可以通过调度而运行多个进程,但是同一个单位
时间内只能有一个进程在CPU上运行,那么这么多的进程怎么在CPU上执行
和调度的呢?
实时进程:动态优先级为0-99的进程,采用实时调度算法调度。
普通进程:动态优先级为100-139的进程采用完全公平调度算法调度(CFS,Completely Fair Scheduler)。
nice值:-20-19,用于调整普通进程优先级的参数,对应100-139的进程优先级。
默认情况下,每个容器对主机CPU周期的访问权限是不受限制的,但是我们可
以设置各种约束来限制给定容器访问主机的CPU周期,大多数用户使用的是默
认的CFS调度方式,在Docker1.13及更高版本中,还可以配置实时优先级。
docker run参数说明:
–cpus #指定容器可以使用多少可用CPU资源,最大不能超过宿主机的核心数。如果主机有两个CPU,并且设置了–cpus=1.5,那么该容器将保证最多可以访问1.5个CPU(如果是4核CPU,那么可以每个核心上用一点,总计还是1.5核心)
使用 –cpu-period 和 --cpu-quota 参数 #这两个参数用于更精细的 CPU 资源控制。–cpu-period 设置评估周期(单位为微秒),范围在1000(1毫秒)到1000000(1秒)之间;–cpu-quota 设置在这个评估周期内的 CPU 配额(单位也为微秒)。cpu-quota/cpu-period 的结果即为实际分配给容器的 CPU 量,如果是小数表示分配的 CPU 量不足一个 vCPU,如果大于1则表示分配的 CPU 量超过一个 vCPU。
--cpuset-cpus
参数:通过该参数可以指定容器能够运行在哪些 CPU 核心上。参数值可以是一个逗号分隔的 CPU 编号列表,或者是一个范围(如"0-3"表示第0、1、2和3核心)。设置 CPU 权重(
--cpu-shares
参数):该参数用于设置容器使用 CPU 的相对权重,默认值为1024。当多个容器竞争 CPU 资源时,权重较高的容器会获得更多的 CPU 时间。但只有在 CPU 资源紧张的情况下,这种按权重分配 CPU 的方式才会生效。
#创建有压测工具的容器
#压测工具源码下载地址https://fossies.org/linux/privat/stress-ng-0.18.05.tar.bz2
[root@localhost stress-ng]# ll
总用量 6272
-rw-r--r-- 1 root root 318 11月 13 15:22 dockerfile
-rw-r--r-- 1 root root 6415003 11月 13 15:11 stress-ng-0.18.05.tar.bz2
[root@localhost stress-ng]# cat dockerfile
FROM alpine:latest
ENV RELEASE_VERSION=0.18.05
ADD stress-ng-0.18.05.tar.bz2 /tmp
RUN \apk add --update bash g++ make && \cd /tmp/stress-ng-${RELEASE_VERSION} && \make && make install && \apk del g++ make && \rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*CMD ["stress-ng", "-c 1"]
[root@localhost stress-ng]# docker build -t stress-ng:v1 .
#默认情况下容器的cpu限额是宿主机的核数
[root@localhost stress-ng]# docker run -it --rm --name stress-ng stress-ng:v1 /bin/sh
/ # stress-ng --cpu 4
stress-ng: info: [36] defaulting to a 1 day run per stressor
stress-ng: info: [36] dispatching hogs: 4 cpu
#在两一个终端查看容器进程信息
[root@localhost ~]# docker top stress-ng
UID PID PPID C STIME TTY TIME CMD
root 31870 31846 0 15:24 pts/0 00:00:00 /bin/sh
root 37242 31870 0 15:36 pts/0 00:00:00 stress-ng --cpu 4
root 37243 37242 99 15:36 pts/0 00:00:49 stress-ng --cpu 4
root 37244 37242 99 15:36 pts/0 00:00:49 stress-ng --cpu 4
root 37245 37242 99 15:36 pts/0 00:00:49 stress-ng --cpu 4
root 37246 37242 99 15:36 pts/0 00:00:49 stress-ng --cpu 4
#查看宿主机cpu占用信息
#执行top后按1查看4个cpu的使用率
[root@localhost ~]# top
top - 15:38:07 up 1:20, 3 users, load average: 4.56, 4.67, 3.23
Tasks: 304 total, 5 running, 299 sleeping, 0 stopped, 0 zombie
%Cpu0 : 94.4 us, 4.2 sy, 0.0 ni, 0.0 id, 0.0 wa, 1.4 hi, 0.0 si, 0.0 st
%Cpu1 : 96.9 us, 1.5 sy, 0.0 ni, 0.0 id, 0.0 wa, 1.5 hi, 0.0 si, 0.0 st
%Cpu2 : 87.5 us, 12.5 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 98.5 us, 1.5 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3616.4 total, 1751.5 free, 1167.2 used, 1017.9 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 2449.2 avail MemPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND37243 root 20 0 37032 4328 1832 R 99.7 0.1 1:37.94 stress-ng-cpu37246 root 20 0 37032 4328 1832 R 99.7 0.1 1:37.74 stress-ng-cpu37244 root 20 0 37032 4332 1832 R 99.3 0.1 1:37.87 stress-ng-cpu37245 root 20 0 37032 4332 1832 R 99.3 0.1 1:37.81 stress-ng-cpu
#限制容器使用cpu数量
[root@localhost stress-ng]# docker run -it --cpus 2 --rm --name stress-ng stress-ng:v1 /bin/sh
/ # stress-ng --cpu 2
stress-ng: info: [8] defaulting to a 1 day run per stressor
stress-ng: info: [8] dispatching hogs: 2 cpu
#查看宿主机cpu使用情况
[root@localhost ~]# top
top - 15:40:53 up 1:22, 3 users, load average: 0.74, 3.10, 2.88
Tasks: 311 total, 3 running, 308 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0 us, 0.7 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 98.5 us, 0.0 sy, 0.0 ni, 1.0 id, 0.0 wa, 0.5 hi, 0.0 si, 0.0 st
%Cpu2 : 88.4 us, 7.2 sy, 0.0 ni, 4.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 0.0 us, 0.7 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3616.4 total, 1717.5 free, 1197.3 used, 1022.7 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 2419.1 avail MemPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND39332 root 20 0 37024 4928 1892 R 99.0 0.1 0:05.44 stress-ng-cpu39331 root 20 0 37024 4928 1892 R 98.7 0.1 0:05.42 stress-ng-cpu
[root@localhost stress-ng]# docker run -it --cpu-period 1000 --cpu-quota 2000000 --rm --name stress-ng stress-ng:v1 /bin/sh
/ # stress-ng --cpu 2
stress-ng: info: [7] defaulting to a 1 day run per stressor
stress-ng: info: [7] dispatching hogs: 2 cpu#查看宿主机的cpu使用情况
[root@localhost ~]# top
top - 15:51:19 up 1:33, 3 users, load average: 1.05, 1.39, 2.10
Tasks: 310 total, 3 running, 307 sleeping, 0 stopped, 0 zombie
%Cpu0 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 0.0 us, 0.7 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3616.4 total, 1745.5 free, 1171.7 used, 1020.3 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 2444.7 avail MemPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND43648 root 20 0 37024 5376 2100 R 99.3 0.1 0:18.17 stress-ng-cpu43649 root 20 0 37024 5376 2100 R 99.3 0.1 0:18.17 stress-ng-cpu
#设定使用0号cpu
[root@localhost stress-ng]# docker run -it --cpuset-cpus 0 --rm --name stress-ng stress-ng:v1 /bin/sh
/ # stress-ng --cpu 2
stress-ng: info: [7] defaulting to a 1 day run per stressor
stress-ng: info: [7] dispatching hogs: 2 cpu#查看宿主机cpu使用情况
top - 15:54:17 up 1:36, 3 users, load average: 1.02, 1.33, 1.95
Tasks: 311 total, 3 running, 308 sleeping, 0 stopped, 0 zombie
%Cpu0 : 98.8 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 1.2 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.3 hi, 0.0 si, 0.0 st
%Cpu2 : 0.0 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
%Cpu3 : 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 3616.4 total, 1757.8 free, 1159.8 used, 1019.9 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 2456.6 avail MemPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND45160 root 20 0 37024 4840 1808 R 50.0 0.1 0:05.38 stress-ng-cpu45161 root 20 0 37024 4840 1808 R 49.7 0.1 0:05.37 stress-ng-cpu