docker容器的参数如何指定配额

1. 内存

现在让我看下内存限制。

第一件事需要注意的是,默认一个容器可以使用主机上的所有内存。

如果你想为容器中的所有进程限制内存,使用docker run命令的 -m开关即可。你可以使用bytes值定义它的值或是添加后缀(kmg)。

1.1 示例:管理一个容器的内存分配

你可以像这样使用-m开关:

$ docker run -it --rm -m 128m fedora bash

为了显示限制的实际情况,我将使用我的stress镜像。考虑一下的运行:

$ docker run -it --rm -m 128m stress --vm  --vm-bytes 128M --vm-hang
stress: info: [] dispatching hogs: cpu, io, vm, hdd

stress工具将创建一个进程,并尝试分配128MB内存给它。它工作的很好,但是如果我们使用的比实际分配给容器的更多的内存会发生什么?

$ docker run -it --rm -m 128m stress --vm  --vm-bytes 200M --vm-hang
stress: info: [] dispatching hogs: cpu, io, vm, hdd

它照样正常工作,是不是很奇怪?是的,我同意。

memory.memsw.limit_in_bytes值是被设置成我们指定的内存参数的两倍,当我们启动一个容器的时候。memory.memsw.limit_in_bytes参数表达了什么?它是memory和swap的总和。这意味着Docker将分配给容器-m内存值以及-mswap值。

当前的Docker接口不允许我们指定(或者是完全禁用它)多少的swap应该被使用,所以我们现在需要一起使用它。

有了以上信息,我们可以再次运行我们的示例。这次我们尝试分配超过我们分配的两倍内存。它将使用所有的内存和所有的 swap,然后玩完了。

$ docker run -it --rm -m 128m stress --vm  --vm-bytes 260M --vm-hang
stress: info: [] dispatching hogs: cpu, io, vm, hdd
stress: FAIL: [] () <-- worker got signal
stress: WARN: [] () now reaping child worker processes
stress: FAIL: [] () kill error: No such process
stress: FAIL: [] () failed run completed in 5s

如果你尝试再次分配比如 250MB(--vm-bytes 250M),它将会很好的工作。

警告:如果你不通过-m开关限制内存,swap也被不会被限制。(这在技术上是不正确的; 这有限度, 但是它设置的值在我们当前运行的系统是不可达的。 例如在我的笔记本上 16GB 的内存值是 18446744073709551615,这是 ~18.5 exabytes…)

不限制内存将导致一个容器可以很容易使得整个系统不稳定的问题。因此请记住要一直使用-m参数。( 或者是使用MemoryLimit属性。)

你可以在/sys/fs/cgroup/memory/system.slice/docker-$FULL_CONTAINER_ID.scope/下面发现关于内存的所有信息,例如:

$ ls /sys/fs/cgroup/memory/system.slice/docker-48db72d492307799d8b3e37a48627af464d19895601f18a82702116b097e8396.scope/
cgroup.clone_children memory.memsw.failcnt
cgroup.event_control memory.memsw.limit_in_bytes
cgroup.procs memory.memsw.max_usage_in_bytes
memory.failcnt memory.memsw.usage_in_bytes
memory.force_empty memory.move_charge_at_immigrate
memory.kmem.failcnt memory.numa_stat
memory.kmem.limit_in_bytes memory.oom_control
memory.kmem.max_usage_in_bytes memory.pressure_level
memory.kmem.slabinfo memory.soft_limit_in_bytes
memory.kmem.tcp.failcnt memory.stat
memory.kmem.tcp.limit_in_bytes memory.swappiness
memory.kmem.tcp.max_usage_in_bytes memory.usage_in_bytes
memory.kmem.tcp.usage_in_bytes memory.use_hierarchy
memory.kmem.usage_in_bytes notify_on_release
memory.limit_in_bytes tasks
memory.max_usage_in_bytes

2、CPU

2.1、Docker能够指定(通过运行命令的-c开关)给一个容器的可用的CPU分配值。这是一个相对权重,与实际的处理速度无关。事实上,没有办法说一个容器只可以获得1Ghz CPU。请记住。

每个新的容器默认的将有1024CPU配额,当我们单独讲它的时候,这个值并不意味着什么。但是如果我们启动两个容器并且两个都将使用 100%CPU,CPU时间将在这两个容器之间平均分割,因为它们两个都有同样的CPU配额(为了简单起见,假设没有任何其他进程在运行)。

如果我们设置容器的CPU配额是512,相对于另外一个容器,它将使用一半的CPU时间。但这不意味着它仅仅能使用一半的CPU时间。如果另外一个容器(1024配额的)是空闲的 - 我们的容器将被允许使用100%CPU。这是需要注意的另外一件事。

限制仅仅当它们应该被执行的时候才会强制执行。CGroups不限制进程预先使用(比如,不允许它们更快地运行即使它们有空余资源)。相反的,它提供了它尽可能提供的以及它仅仅在必需的时候限制(比如,当太多的进程同时大量地使用CPU)。

当然,这很难说清楚(我想说的是这不可能说清楚的)多少资源应该被分配给你的进程。这实际取决于其他进程的行为以及多少配额被分配给它们。

示例:管理一个容器的 CPU 分配

正如我在前面提到的,你可以使用-c开关来分配给运行在容器中的所有进程的配额值。

因为在我的机器上我有4核,我将使用4压测:

$ docker run -it --rm stress --cpu
stress: info: [] dispatching hogs: cpu, io, vm, hdd

如果你想以相同的方式启动两个容器,两个都将使用 50% 左右的 CPU。但是当我们修改其中一个容器的 shares 时,将发生什么?

$ docker run -it --rm -c  stress --cpu
stress: info: [] dispatching hogs: cpu, io, vm, hdd

正如你所看到的,CPU在两个容器之间是以这样的方式分割了,第一个容器使用了60%的CPU,另外一个使用了30%左右。这似乎是预期的结果。

注意:丢失的约10%CPU被GNOME、Chrome和我的音乐播放器使用了。

 2.2、除了限制 CPU配额,我们可以做更多的事情:我们可以把容器的进程固定到特定的处理器(core)。为了做到这个,我们使用docker run命令的- -cpuset开关。

为了允许仅在第一个核上执行:

docker run -it --rm --cpuset= stress --cpu 

为了允许仅在前两个核上执行:

docker run -it --rm --cpuset=, stress --cpu 

你当然可以混合使用选项--cpuset-c

注意:Share enforcement仅仅发生在当进程运行在相同的核上的时候。这意味着如果你把一个容器固定在第一个核,而把另外一个容器固定在另外一个核,两个都将使用各自核的 100%,即使它们有不同的CPU配额设置(再次声明,我假设仅仅有两个容器运行在主机上)。

2.3 变更一个正在运行的容器的配额

有可能改变一个正在运行的容器的配额(当然或是任何其他进程)。你可以直接与cgroups文件系统交互,但是因为我们有systemds,我们可以通过它来为我们管理。

为了这个目的,我们将使用systemctl命令和set-property参数。使用docker run命令新的容器将有一个systemd scope,自动分配到其内的所有进程都将被执行。为了改变容器中所有进程的CPU配额,我们仅仅需要在scope内改变它,像这样:

$ sudo systemctl set-property docker-4be96b853089bc6044b29cb873cac460b429cfcbdd0e877c0868eb2a901dbf80.scope CPUShares=

注意:添加--runtime暂时地改变设置。否则,当主机重启后,这个设置会被记住。

把默认值从1024变更到512。你可以看到下面的结果。这一变化发生在记录中。请注意CPU使用率。在systemd-cgtop中100%意味着满额使用了一核,并且这是正确的,因为我绑定了两个容器在相同的核上。

注意:为了显示所有的属性,你可以使用systemctl show docker-4be96b853089bc6044b29cb873cac460b429cfcbdd0e877c0868eb2a901dbf80.scope命令。想要列出所有可用的属性,请查看man systemd.resource-control。

你可以在/sys/fs/cgroup/cpu/system.slice/下发现指定容器的关于CPU的所有信息。

需要记住的一些事项:

    1. CPU配额仅仅是一个数字 - 与CPU速度无关
    2. 新容器默认有1024配额
    3. 在一台空闲主机上,低配额的容器仍可以使用100%的CPU
    4. 如果你想,你可以把容器固定到一个指定核

3、 限制磁盘空间

正如我前面提到的,这是艰难的话题,默认你每个容器有10GB的空间,有时候它太大了,有时候不能满足我们所有的数据放在这里。不幸的是,为此我们什么都不能做。

我们能做的唯一的事情就是改变新容器的默认值,如果你认为一些其他的值(比如 5GB)更适合你的情况,你可以通过指定Docker daemon的 --storage-opt来实现,像这样:

docker -d --storage-opt dm.basesize=5G

4、限制写速率

让我测试没有执行限制的速率:

$ docker run -it --rm --name block-device-test fedora bash
bash-4.2# time $(dd if=/dev/zero of=testfile0 bs= count= && sync)
+ records in
+ records out
bytes ( MB) copied, 0.202718 s, MB/s real 0m3.838s
user 0m0.018s
sys 0m0.213s

花费了 3.8秒来写入100MB数据,大概是26MB/s。让我们尝试限制一点磁盘的速率。

为了能调整容器可用的带宽,我们需要明确的知道容器挂载的文件系统在哪里。当你在容器里面执行mount命令的时候,你可以发现它,发现设备挂载在root文件系统:

$ mount
/dev/mapper/docker-:--d2115072c442b0453b3df3b16e8366ac9fd3defd4cecd182317a6f195dab3b88 on / type ext4 (rw,relatime,context="system_u:object_r:svirt_sandbox_file_t:s0:c447,c990",discard,stripe=,data=ordered)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev type tmpfs (rw,nosuid,context="system_u:object_r:svirt_sandbox_file_t:s0:c447,c990",mode=) [SNIP]

在我们的示例中是:/dev/mapper/docker-253:0-3408580-d2115072c442b0453b3df3b16e8366ac9fd3defd4cecd182317a6f195dab3b88

你也可以使用nsenter得到这个值,像这样:

$ sudo /usr/bin/nsenter --target $(docker inspect -f '{{ .State.Pid }}' $CONTAINER_ID) --mount --uts --ipc --net --pid mount | head -1 | awk '{ print $1 }'
/dev/mapper/docker-:--d2115072c442b0453b3df3b16e8366ac9fd3defd4cecd182317a6f195dab3b88

现在我们可以改变BlockIOWriteBandwidth属性的值,像这样:

$ sudo systemctl set-property --runtime docker-d2115072c442b0453b3df3b16e8366ac9fd3defd4cecd182317a6f195dab3b88.scope "BlockIOWriteBandwidth=/dev/mapper/docker-253:0-3408580-d2115072c442b0453b3df3b16e8366ac9fd3defd4cecd182317a6f195dab3b88 10M"

这应该把磁盘的速率限制在10MB/s,让我们再次运行dd

bash-4.2# time $(dd if=/dev/zero of=testfile0 bs= count= && sync)
+ records in
+ records out
bytes ( MB) copied, 0.229776 s, MB/s real 0m10.428s
user 0m0.012s
sys 0m0.276s

可以看到,它花费了10s来把100MB数据写入磁盘,因此这速率是 10MB/s。

docker容器的参数如何指定配额的更多相关文章

  1. docker容器启动参数

    docker run [option] 镜像名 [向启动容器中传入的命令] 常用可选参数说明: -i 表示以“交互模式”运行容器 -t 表示容器启动后会进入其命令行.加入这两个参数后,容器创建就能登录 ...

  2. docker 容器创建参数错误记录

    sudo docker ps -a -q sudo docker ps -a|cutawk '{print $1}' #删除前八条 sudo docker ps -a -q|head -n |xarg ...

  3. 关于docker容器内核参数修改问题

    以下内容截取自docker官方文档 地址:https://docs.docker.com/edge/engine/reference/commandline/run/#configure-namesp ...

  4. docker容器安全

    title: docker容器安全 tags: Docker,容器,安全策略 grammar_cjkRuby: true --- Docker容器的安全性 1.安全策略-Cgroup 1.限制Cpu ...

  5. 【转帖】一文看懂docker容器技术架构及其中的各个模块

    一文看懂docker容器技术架构及其中的各个模块 原创 波波说运维 2019-09-29 00:01:00 https://www.toutiao.com/a6740234030798602763/ ...

  6. Docker容器技术

    Docker介绍 什么是容器 Linux容器是与系统其他部分隔离开的一系列进程,从另一个系统镜像运行,并由该镜像提供支持进程所需的全部文件. 容器镜像包含了应用的所有依赖项,因而在从开发到测试再到生产 ...

  7. 一看就懂-Docker容器化

    一.Docker简介 1.1 什么是docker docker的英文意思是 码头工人,意思就是搬运东西的意思,其实这和docker的特点是一样的,docker提供的就是一种容器化搬运东西(我们的软件. ...

  8. docker容器资源配额控制

    转自:http://blog.csdn.net/horsefoot/article/details/51731543 文/ 天云软件 容器技术团队 Docker通过cgroup来控制容器使用的资源配额 ...

  9. docker容器资源配额控制_转

    转自:docker容器资源配额控制 ■ 文/ 天云软件 容器技术团队 docker通过cgroup来控制容器使用的资源配额,包括CPU.内存.磁盘三大方面,基本覆盖了常见的资源配额和使用量控制. cg ...

随机推荐

  1. 每天进步一点点——Linux中的线程局部存储(二)

    转载请说明出处:http://blog.csdn.net/cywosp/article/details/26876231     在Linux中另一种更为高效的线程局部存储方法,就是使用keyword ...

  2. Python+Selenium框架unittest执行脚本方法之discover()方法

    继续接着介绍,如何利用unittest管理和执行测试用例的问题,这里我们还是利用之前已经有的三条测试用例,如果你跳过了前面文章,请回到框架设计篇的第八篇和第七篇,里面有相关测试类的文件.本文来介绍,如 ...

  3. linux c语言 select函数使用方法

    linux c语言 select函数使用方法 表头文件 #i nclude<sys/time.h> #i nclude<sys/types.h> #i nclude<un ...

  4. caffe学习--caffe入门classification00学习--ipython

    首先,数据文件和模型文件都已经下载并处理好,不提. cd   "caffe-root-dir " ----------------------------------分割线---- ...

  5. babylon使用3dsmax导出的obj文件时模型偏暗

    将模型的material的diffuseTexture设置为null即可

  6. php 去除html标记-strip_tags和htmlspecialchars的区别

    strip_tags 去掉 HTML 及 PHP 的标记. 语法: string strip_tags(string str); 传回值: 字串 函式种类: 资料处理 内容说明 本函式可去掉字串中包含 ...

  7. POJ 1195 Mobile phones (二维树状数组)

    Description Suppose that the fourth generation mobile phone base stations in the Tampere area operat ...

  8. ios上视频与音乐合成后出现播放兼容问题的解决方法

    近期EasyDarwin开源流媒体团队EasyVideoRecorder小组同学Carl在支持一款短视频应用上线时,遇到一个问题:我们在IOS上合成"图片+音乐"成为视频之后,在P ...

  9. hsv hsb rgb lab

    lab  欧式距离 反映 人类所能感受到的这两种颜色的差异

  10. aop学习总结二------使用cglib动态代理简单实现aop功能

    aop学习总结二------使用cglib动态代理简单实现aop功能 模拟业务需求: 1.拦截所有业务方法 2.判断用户是否有权限,有权限就允许用户执行业务方法,无权限不允许用户执行业务方法 (判断是 ...