Docker 资源限制

882 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

资源限制

  默认情况下, Docker 是没有对容器做资源限制的, 如果不对容器做任何限制, 容器能够占用当前系统能给容器提供的所有资源. 当耗光宿主机所有资源时就会导致 OOM, OOM 一旦发生, 任何进程都有可能被系统杀掉. 所以在启动 Docker 容器时最好是指定 CPU, 内存, 硬盘大小等硬件配额.

  Docker 通过 cgroup 来控制这些资源配额, CGroup 是 _ControlGroups 的缩写, 是 Linux 内核提供的一种可以限制, 记录, 隔离进程组(process groups)所使用的物理资源(如 cpu memory i/o等等)的机制.

CGroups 不是全新创造的, 它将进程管理从 cpuset 中剥离出来. 也就是说下面讲到的命令其实都是在配置 cgroup. 比如调整了 CPU 的限制后, 在 /sys/fs/cgroup/cpu/docker/container_id/ 可以看到设置的值. cgroup 分配的结果取决于当时主机和其他容器的运行状况, 如果 A 容器很空闲, 那么即使给它分配了更多份额, 也会被其他忙碌的容器抢夺资源, 是一种动态分配. 设置好配额后可以在容器中用压力工具 stress来测试.

内存限制

  在启动容器时, 使用如下参数可以限制其内存使用.

-m:设置容器可用内存大小, 支持单位有 b, k, m 和 g.

--memory-swap:设置内存+swap的总大小, 配合 -m 一起使用, 该选项不指定的话默认是 -m 的 2 倍大小.

--oom-kill-disable:不允许容器因为 OOM 被系统杀掉, 建议配合 -m 选项使用, 避免宿主内存被耗光.

比如:

# 容器使用的内存上限为1G, 虚拟内存500M, 超过该内存限制就会停止容器
docker run -itd -m 1024m --memoery-swap=1524m --oom-kill-disable docker.io/centos  

在没有设置 -m 的时候这个值为 -1, 表示容器使用的内存不受限制.

如果设置了 -m 参数, 通常情况下如果容器使用内存量超过了设置的硬水线, 那么 linux 的 oom-killer 触发, 它将根据 oom-score 对容器内部进程进行 oom kill. 但是不影响宿主机上其他进程.

使用 docker stats 容器ID 可以查看当前容器的信息.

CPU限制

  Docker 提供的 CPU 资源限制选项可以在多核系统上限制容器能够利用哪些 vCPU. 而对容器最多能使用的 CPU 时间有两种限制方式 :

  • 一是有多个 CPU 密集型的容器竞争 CPU 时, 设置各个容器能使用的 CPU 时间相对比例.
  • 二是以绝对的方式设置容器在每个调度周期内最多能使用的 CPU 时间.

  参数 :

-c | --cpu-share:CPU 权重设置, Docker 会把 CPU 资源分成 1024 份, 如果对一个容器设置了 1024 意味它独占所有 CPU 资源, 如果多个容器同时进行了设置, 那么每个容器最后会通过各自占有的百分比来分配 CPU 资源.

--cpus:限制CPU核数. CPU 个数, 并且还可以指定如 1.5 之类的小数.

--cpuset-cpus:设置CPU亲和, 让容器绑定在指定的CPU上.

比如:

docker run -it --name test  --cpu-shares 1024 docker.io/centos /bin/bash

docker run -it --name test  --cpu-shares  512 docker.io/centos /bin/bash

CPU 亲和设置, 比如物理机有 16 个核心, 创建的容器只能用 0, 1, 2 这三个内核.

docker run -itd --name testcpu --cpuset-cpus 0-2 docker.io/centos

cat /sys/fs/cgroup/cpuset/docker/dockerid/cpuset.cpus

硬盘 IO限制

  参数 :

--device-read-bps:限制读某个设备的bps

--device-write-bps:限制写某个设备的bps

--device-read-iops:限制读某个设备的iops

--device-write-iops:限制写某个设备的iops

比如:

# 限制最高写速度为 30M/S
docker run -it --name iotest --device-write-bps /dev/sda1:30M docker centos

测试 Docker 配额限制

内存压测, 如下代表启动一个线程, 每个线程分配 500M 内存. 由于超过了容器最大内存会报错退出:

docker run -it -m 200m --memory-swap=300m progium/stress --vm 1 --vm-bytes 400m

CPU 测试. 分配权重为 2:1, 容器启动后在宿主机执行 top 命令可以看到占比为 66%, 33%.

docker run --name "test1" -c 1024 centos
docker run --name "test2" -c 512 centos

\