Docker run参考(10) – 资源使用限制

下面是可用于限制容器资源使用的选项:

限制指定设备读取速率(每秒IO操作数)[格式::]。number为正整数。

选项 描述
-m, –memory=”” 内存限制[格式:[]]。number是正整数。unit可以是b,k,m或g。最小4M。
–memory-swap=”” 总内存限制[memory+swap,格式:[]]。number是正整数。unit可以是b,k,m或g。
–memory-reservation=”” 内存软限制[格式:[]]。number是正整数。unit可以是b,k,m或g。
–kernel-memory=”” 内核内存限制[格式:[]]。number是正整数。unit可以是b,k,m或g。
-c, –cpu-shares=0 CPU share(相对权重)
–cpu-period=0 限制CPU CFS(完全公平调度程序)周期
–cpuset-cpus=”” 允许执行的CPU(0-3,0,1)
–cpuset-mems=”” 允许执行的内存节点(MEMs)(0-3,0,1)。 仅在NUMA系统上有效。
–cpu-quota=0 限制CPU CFS(完全公平调度程序)配额
–blkio-weight=0 块IO权重(相对权重)接受10和1000之间的权重值。
–blkio-weight-device=”” 块IO权重(相对设备权重,格式:DEVICE_NAME:WEIGHT)
–device-read-bps=”” 限制指定设备的读取速率[格式::[]]。number是一个正整数。unit可以是kb,mb或gb。
–device-write-bps=”” 限制指定设备的写入速率[格式::[]]。number是一个正整数。unit可以是kb,mb或gb。
–device-read-iops=””
–device-write-iops=”” 限制指定设备写入速率(每秒IO操作数)[格式::]。number为正整数。
–oom-kill-disable=false 是否禁用容器的OOM Killer
–oom-score-adj=0 调整容器的OOM偏好 (-1000 to 1000)
–memory-swappiness=”” 调整容器的内存swappiness行为。 接受介于0和100之间的整数。
–shm-size=”” /dev/shm的大小。格式为:。number必须大于0。unit可选,可以是b,k,m或g。如果不指定unit,系统默认使用字节。如果此参数不指定,默认使用64m。

用户内存约束

有四种方式来设置用户内存使用:

选项 结果
memory=inf, memory-swap=inf (default) 对容器内存使用无限制。容器可以根据需要使用尽可能多的内存。
memory=L[设置memory为正整数并设置memory-swap为-1]容器不允许使用超过L字节的内存,不过可以根据需要使用尽可能多的swap[如果主机支持swap内存]
memory=L[只设置memory,不设置memory-swap]容器不允许使用超过L字节内存,swap加上memory总共不超过两倍L。
memory=L[memory和memory-swap都设置]容器不允许使用超过L字节内存,swap加上memory不能超过S。

示例:

  1. $ docker run -it ubuntu:14.04 /bin/bash

这个示例我们没有设置内存限制,意味着容器进程可以根据需要使用尽可能多的内存和swap。

  1. $ docker run -it -m 300M --memory-swap -1 ubuntu:14.04 /bin/bash

我们设置了memory限制,取消了swap内存限制,意味着容器进程可以使用300M内存,且可以按需使用尽可能多的swap[如果主机支持swap内存]。

  1. $ docker run -it -m 300M ubuntu:14.04 /bin/bash

我们只设置memory限制,意味着容器进程可以使用300M内存和300M swap,默认下,虚拟内存总共大小[-memory-swap]将设置为memory的两倍大小,所以在这种情况下,memory+swap将是2*300M,所以进程能使用300M swap内存。

  1. $ docker run -it -m 300M --memory-swap 1G ubuntu:14.04 /bin/bash

memory和swap内存都设置了,所以容器进程能使用300M内存和700M swap内存。
内存预留(Memory reservation)是一种内存软限制,允许更大的内存共享。正常情况下,容器可以根据需要使用尽可能多的内存,且仅被硬限制-m/–memory限制。当设置了内存预留,Docker检测内存争用或低内存,并强制容器将其内存消耗限制为预留限制。
始终设置内存预留小于硬限制,否则硬限制优先触发。设置reservation为0表示不做限制。默认下[没有设置预留],内存预留与内存硬限制一样。
内存预留是一个软限制功能,不能保证不会超过限制。而是,这个功能尝试确保的是,当内存争用严重时,内存就按预留设置分配。
以下示例限制内存[-m]为500M,内存软限制200M。

  1. $ docker run -it -m 500M --memory-reservation 200M ubuntu:14.04 /bin/bash

在这个配置下,当容器消耗内存超过200M,小于500M时,下一个系统内存回收将尝试缩减容器内存到200M以下。
以下示例设置内存软限制为1G,没有设置内存硬限制。

  1. $ docker run -it --memory-reservation 1G ubuntu:14.04 /bin/bash

容器可以按需使用尽可能多的内存。这个内存软限制设置只是确保容器不会长时间消耗过多内存,因为每次内存回收就缩减容器内存消耗到软限制。默认下,如果out-of-memory[OOM]错误发生,内核将杀死容器的进程。要更改这个行为,使用–oom-kill-disable选项。这个只在容器设置了-m/–memory选项时才禁止OOM killer。如果-m没有设置,这会导致消耗完主机内存,然后需要杀掉主机系统进程来释放内存。
以下示例限制内存为100M并禁止容器的OOM killer:

  1. $ docker run -it -m 100M --oom-kill-disable ubuntu:14.04 /bin/bash

以下示例说明了使用这个选项的一种危险方式:

  1. $ docker run -it --oom-kill-disable ubuntu:14.04 /bin/bash

这个容器可以无限制使用内存,这会导致主机消耗完内存,然后需要杀掉系统进程来释放内存。–oom-score-adj参数可以设置当系统内存不足时哪些容器将被杀死的优先级,数字越大越容易被杀死。

内核内存约束

内核内存不同于用户内存,因为内核内存不能交换到硬盘。内核内存无法swap可能会当容器消耗过多的内核内存时导致其阻塞系统服务。内核内存包括:

  • stack pages
  • slab pages
  • sockets memory pressure
  • tcp memory pressure
  • 可以设置内核内存限制来约束这些类型的内存。例如,每个进程都会消耗一些stack pages。通过限制内核内存,当内核内存使用过多时,阻止新进程的创建。
    内核内存不会完全独立用户内存。而是,在用户内存限制的上下文中限制内核内存。假设”U”是用户内存限制,”K”是内核限制。有三种可能的方式设置限制:

    选项 结果
    U != 0, K = inf (default) 这个是在使用内核内存已经存在了的标准内存限制机制。内核内存是完全忽略的。
    U != 0, K 内核内存是用户内存的一个子集。这个设置适合用在每个cgroup的内存总量已经过度使用的部署中。不建议过度使用内核内存限制,因为这样仍然会消耗完不可回收的内存。在这种情况下,可以配置K以便所有的groups总数不会超过总内存。然后,以系统的服务质量为代价自由设置U。
    U != 0, K > U 因为内核内存的消耗也会反馈到用户计数器中,且容器的两种类型的内存也触发回收。这个配置给了管理员一个内存的统一视图。对仅仅想要追踪内核内存使用情况的用户也有帮助。

    示例:

    1. $ docker run -it -m 500M --kernel-memory 50M ubuntu:14.04 /bin/bash

    memory和内核memory都设置了,所以容器进程可以使用总共500M的内存,在500M内存中,可以使用最高50M内核内存。

    1. $ docker run -it --kernel-memory 50M ubuntu:14.04 /bin/bash

    这里只设置了内核内存限制,所以容器进程可以使用尽可能多的内存,不过只可以使用50M的内核内存。

    Swappiness约束

    默认下,容器内核可以设置交换指定百分比的匿名页面。要设置这个百分比,可以设置–memory-swappiness为0-100的值。0表示关闭匿名页面交换。100表示设置所有匿名页面可交换。默认下,如果没有设置memory-swappiness,内存swappiness的值将从父级继承。
    例如,设置:

    1. $ docker run -it --memory-swappiness=0 ubuntu:14.04 /bin/bash

    当希望保留容器的工作集并避免交换性能损失时,设置–memory-swappiness选项非常有用。

    CPU share限制

    默认下,所有的容器都得到相同比例的CPU周期。这个比例可以通过改变容器的CPU share权重来更改,这个权重是相对于所有其它运行中的容器。
    要更改默认的1024比例,使用-c或–cpu-shares设置权限为2或更高。如果为0,系统将忽略这个值并使用默认的1024。
    这个比例只在当CPU密集型进程运行时应用。当一个容器空闲时,其它容器可以使用剩余CPU时间。实际的CPU时间总数根据运行在系统上的容器数量不同。
    例如,有三个容器,一个的cpu-share为1024,其它两个cpu-share为512。当所有三个容器进程尝试使用100%的CPU时,第一个容器将得到50%的CPU时间。如果添加一个cpu-share为1024的容器,第一个容器只得到33%的CPU。其余的容器得到16.5%, 16.5%和 33%的CPU时间。
    在一个多核系统,CPU时间的份额分布在所有CPU内核上。即使一个容器限制为小于100%的CPU,它也能使用每个单独CPU核的100%时间。
    例如,有一个越过3核的系统。如果启动一个容器{C0},-c=512,只运行一个进程,另一个容器{C1},-c=1024,运行两个进程,cpu shares分配如下:

    1. PID    container    CPU CPU share
    2. 100    {C0}     0   100% of CPU0
    3. 101    {C1}     1   100% of CPU1
    4. 102    {C1}     2   100% of CPU2

    CPU周期约束

    默认的CPU CFS(完全公平调度器)周期为100ms。我们可以使用–cpu-period来设置CPU周期来限制容器CPU的使用。通常–cpu-period和–cpu-quota配合使用。
    示例:

    1. $ docker run -it --cpu-period=50000 --cpu-quota=25000 ubuntu:14.04 /bin/bash

    如果只有1个CPU,这意味着容器可以每50ms获得50%的CPU运行时间。
    更多信息,参考CFS有关带宽限制的文档

    Cpuset约束

    我们可以设置允许容器在哪个CPU执行。
    示例:

    1. $ docker run -it --cpuset-cpus="1,3" ubuntu:14.04 /bin/bash

    这个示例意思是容器可以在cpu1和cpu3执行。

    1. $ docker run -it --cpuset-cpus="0-2" ubuntu:14.04 /bin/bash

    意思是容器可以在cpu 0, cpu 1和 cpu 2执行。
    我们可以设置允许容器在哪个mems执行。只在NUMA系统有效。
    示例:

    1. $ docker run -it --cpuset-mems="1,3" ubuntu:14.04 /bin/bash

    这个示例限制容器进程只能使用在memory节点1和3的内存。

    1. $ docker run -it --cpuset-mems="0-2" ubuntu:14.04 /bin/bash

    这个示例限制容器进程只能使用在memory节点0,1和2的内存。

    CPU配额约束

    –cpu-quota标志限制容器的CPU使用率。默认值0允许容器占用100%的CPU资源(1个CPU)。CFS(完全公平调度器)处理执行进程的资源分配,并且是内核使用的默认Linux调度程序。将此值设置为50000,以将容器限制为CPU资源的50%。对于多个CPU,必要时调整–cpu-quota。更多信息,参考CFS有关带宽限制的文档

    块IO带宽(Blkio)约束

    默认下,所有的容器获得相同比例的块IO带宽[bokio]。这个比例是500。要更改这个比例,使用–bokio-weight参数。

    注意:bokio目前只支持直接IO。缓冲IO目前不支持。

    –blkio-weight参数可以设置10到100的值。例如,下面的命令创建两个容器不同的bokio权重:

    1. $ docker run -it --name c1 --blkio-weight 300 ubuntu:14.04 /bin/bash
    2. $ docker run -it --name c2 --blkio-weight 600 ubuntu:14.04 /bin/bash

    如果同时在这两个容器执行块IO操作,例如:

    1. $ time dd if=/mnt/zerofile of=test.out bs=1M count=1024 oflag=direct

    你会发现这两个容器执行块操作所需的时间的比例与bokio权重的比较一样。
    –blkio-weight-device=”DEVICE_NAME:WEIGHT”设置一个指定设备的权重。DEVICE_NAME:WEIGHT是一个包含设备名称与权重,冒号分隔的字符串。例如,要设置/dev/sda设备权重为200:

    1. $ docker run -it \
    2.     --blkio-weight-device "/dev/sda:200" \
    3.     ubuntu

    如果–blkio-weight和–blkio-weight-device两个都设置了,docker使用–blkio-weight作为默认权重,并使用–blkio-weight-device来用指定设备的新权重覆盖这个默认值。以下示例使用默认的权重值300,并覆盖在/dev/sda的默认值设置为200:

    1. $ docker run -it \
    2.     --blkio-weight 300 \
    3.     --blkio-weight-device "/dev/sda:200" \
    4.     ubuntu

    –device-read-bps参数限制指定设备的读取速率[字节/秒]。例如,以下命令创建一个容器,并限制在/dev/sda的读取速率为每秒1mb:

    1. $ docker run -it --device-read-bps /dev/sda:1mb ubuntu

    –device-write-bps参数限制指定设备的写入速率[字节/秒]。例如,以下命令创建一个容器并限制在/dev/sda的写入速率为每秒1mb:

    1. $ docker run -it --device-write-bps /dev/sda:1mb ubuntu

    两个参数以:[unit]格式作限制。两个的读取和写入速率必须是一个正整数。可以在指定速率时使用kb,mb或gb。
    –device-read-iops参数限制指定设备读取速率[IO/秒]。例如,以下命令创建一个容器并限制在/dev/sda的读取速率为每秒10000IO:

    1. $ docker run -ti --device-read-iops /dev/sda:1000 ubuntu

    –device-write-iops参数限制指定设备的写入速率[IO/秒]。例如,以下命令创建一个容器并限制在/dev/sda的写入速率为每秒1000IO:

    1. $ docker run -ti --device-write-iops /dev/sda:1000 ubuntu

    两个参数以:[unit]格式作限制。两个的读取和写入速率必须是一个正整数。

    标签:Docker 发布于:2019-11-19 17:22:42