Docker 运行时资源限制
Docker 基于 Linux 内核提供的 cgroups 功能,可以限制容器在运行时使用到的资源,比如内存、CPU、块 I/O、网络等。
内存限制
概述
Docker 提供的内存限制功能有以下几点:
- 容器能使用的内存和交换分区大小。
- 容器的核心内存大小。
- 容器虚拟内存的交换行为。
- 容器内存的软性限制。
- 是否杀死占用过多内存的容器。
- 容器被杀死的优先级
一般情况下,达到内存限制的容器过段时间后就会被系统杀死。
内存限制相关的参数
执行docker run
命令时能使用的和内存限制相关的所有选项如下。
选项 | 描述 |
---|---|
-m ,--memory |
内存限制,格式是数字加单位,单位可以为 b,k,m,g。最小为 4M |
--memory-swap |
内存+交换分区大小总限制。格式同上。必须必-m 设置的大 |
--memory-reservation |
内存的软性限制。格式同上 |
--oom-kill-disable |
是否阻止 OOM killer 杀死容器,默认没设置 |
--oom-score-adj |
容器被 OOM killer 杀死的优先级,范围是[-1000, 1000],默认为 0 |
--memory-swappiness |
用于设置容器的虚拟内存控制行为。值为 0~100 之间的整数 |
--kernel-memory |
核心内存限制。格式同上,最小为 4M |
用户内存限制
用户内存限制就是对容器能使用的内存和交换分区的大小作出限制。使用时要遵循两条直观的规则:-m,--memory
选项的参数最小为 4 M。--memory-swap
不是交换分区,而是内存加交换分区的总大小,所以--memory-swap
必须比-m,--memory
大。在这两条规则下,一般有四种设置方式。
你可能在进行内存限制的实验时发现
docker run
命令报错:WARNING: Your kernel does not support swap limit capabilities, memory limited without swap.这是因为宿主机内核的相关功能没有打开。按照下面的设置就行。
step 1:编辑
/etc/default/grub
文件,将GRUB_CMDLINE_LINUX
一行改为GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
step 2:更新 GRUB,即执行
$ sudo update-grub
step 3: 重启系统。
1. 不设置
如果不设置-m,--memory
和--memory-swap
,容器默认可以用完宿舍机的所有内存和 swap 分区。不过注意,如果容器占用宿主机的所有内存和 swap 分区超过一段时间后,会被宿主机系统杀死(如果没有设置--00m-kill-disable=true
的话)。
2. 设置-m,--memory
,不设置--memory-swap
给-m
或--memory
设置一个不小于 4M 的值,假设为 a,不设置--memory-swap
,或将--memory-swap
设置为 0。这种情况下,容器能使用的内存大小为 a,能使用的交换分区大小也为 a。因为 Docker 默认容器交换分区的大小和内存相同。
如果在容器中运行一个一直不停申请内存的程序,你会观察到该程序最终能占用的内存大小为 2a。
比如$ docker run -m 1G ubuntu:16.04
,该容器能使用的内存大小为 1G,能使用的 swap 分区大小也为 1G。容器内的进程能申请到的总内存大小为 2G。
3. 设置-m,--memory=a
,--memory-swap=b
,且b > a
给-m
设置一个参数 a,给--memory-swap
设置一个参数 b。a 时容器能使用的内存大小,b是容器能使用的 内存大小 + swap 分区大小。所以 b 必须大于 a。b -a 即为容器能使用的 swap 分区大小。
比如$ docker run -m 1G --memory-swap 3G ubuntu:16.04
,该容器能使用的内存大小为 1G,能使用的 swap 分区大小为 2G。容器内的进程能申请到的总内存大小为 3G。
4. 设置-m,--memory=a
,--memory-swap=-1
给-m
参数设置一个正常值,而给--memory-swap
设置成 -1。这种情况表示限制容器能使用的内存大小为 a,而不限制容器能使用的 swap 分区大小。
这时候,容器内进程能申请到的内存大小为 a + 宿主机的 swap 大小。
Memory reservation
这种 memory reservation 机制不知道怎么翻译比较形象。Memory reservation 是一种软性限制,用于节制容器内存使用。给--memory-reservation
设置一个比-m
小的值后,虽然容器最多可以使用-m
使用的内存大小,但在宿主机内存资源紧张时,在系统的下次内存回收时,系统会回收容器的部分内存页,强迫容器的内存占用回到--memory