目录
2.1 设置-m,--memory,不设置--memory-swap
2.2 设置-m,--memory=a,--memory-swap=b,且b >a
2.3 设置-m,--memory=a,--memory-swap=-1
2.4 内存软限制(设置--memory-reservation)
2.6 设置-m=a,--memory-swappiness=0
用户内存限制就是对容器能使用的内存和交换分区的大小作出限制;主机运行若干容器,每个容器都需要cpu、内存以及IO资源,为避免因为单个容器占用过多资源而影响到所有其他容器乃至整个宿主机的性能,因此需要对容器资源进行限制。
在说容器的资源限制之前,我们需要补充两点知识点。
容器的启动过程说明:
- 检查本地是否存在指定的镜像,如果没有就从指定的仓库下载
- 利用镜像启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
- 从宿主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个IP给容器
- 执行用户指定的程序
- 执行完毕后停止容器
下面这张图实际上展现了容器的各个状态和操作,比如操作:start,kill,stop等。

一个docker host上会运行若干容器,每个容器都需要CPU、内存和 IO 资源。对于 KVM,VMware等虚拟化技术,用户可以控制分配多少 CPU、内存资源给每个虚拟机。对于容器,Docker 也提供了类似的机制避免某个容器因占用太多资源而影响其他容器乃至整个 host 的性能。因此我们需要对容器的内存,cpu,io,磁盘等做适当的限制。
| 参数 | 说明 |
| -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大;
· 若不设置-m,--memory和--memory-swap,容器默认可用完宿主机所有内存和swap分区。但容器占宿主机所有内存和swap分区超过一段时间后,会被宿主机系统杀死(若没有设置--oom-kill-disable=true)。
使用-m或--memory设置一个不小于 4M 的a值,不设置--memory-swap,或将--memory-swap设置为 0。则表示容器能使用的内存大小为 a,能使用的交换分区大小也为 a。因为 Docker 默认容器交换分区的大小和内存相同。若容器中运行一个一直不停申请内存的程序,则该程序最终能使用的内存大小为 2a。
示例: 使用progrium/stress容器来资源测试。
当设置-m=200m,不设置--memory-swap,则容器最多使用内存大小测试如下:
Step1:测试内存为200m
[root@clinet ~]# docker run -it -m 200m progrium/stress --vm 1 --vm-bytes 200m
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [7] forked
stress: dbug: [7] allocating 209715200 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 209715200 bytes
stress: dbug: [7] allocating 209715200 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 209715200 bytes
stress: dbug: [7] allocating 209715200 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 209715200 bytes
stress: dbug: [7] allocating 209715200 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
Step2:测试内存为399m
[root@clinet ~]#
[root@clinet ~]# docker run -it -m 200m progrium/stress --vm 1 --vm-bytes 399m
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [7] forked
stress: dbug: [7] allocating 418381824 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 418381824 bytes
stress: dbug: [7] allocating 418381824 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: dbug: [7] freed 418381824 bytes
stress: dbug: [7] allocating 418381824 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
Step3:测试内存为401M
[root@clinet ~]# docker run -it -m 200m progrium/stress --vm 1 --vm-bytes 401m
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [6] forked
stress: dbug: [6] allocating 420478976 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (416) <-- worker 6 got signal 9
stress: WARN: [1] (418) now reaping child worker processes
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 0s
总结:
使用-m或--memory设置一个不小于 4M 的a值,不设置--memory-swap,或将--memory-swap设置为 0。则表示容器能使用的内存大小为 a,能使用的交换分区大小也为 a。因此容器最大使用的内存数为2a
示例: 当设置-m=200m,设置--memory-swap=300m时,此时的swap=100m
Step1: 测试内存为299m(容器正常运行)
[root@clinet ~]# docker run -it -m 200m --memory-swap 300m progrium/stress --vm 1 --vm-bytes 299m
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [6] forked
stress: dbug: [6] allocating 313524224 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
stress: dbug: [6] freed 313524224 bytes
stress: dbug: [6] allocating 313524224 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
step2:测试内存为301时(容器运行异常)
[root@clinet ~]# docker run -it -m 200m --memory-swap 300m progrium/stress --vm 1 --vm-bytes 301m
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [7] forked
stress: dbug: [7] allocating 315621376 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (416) <-- worker 7 got signal 9
stress: WARN: [1] (418) now reaping child worker processes
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 0s
使用-m或--memory设置一个不小于 4M 的a值,且b必须大于a,使用--memory-swap设置一个参数 b。则表示容器能使用的内存大小为 a,能使用的交换分区+内存大小为 b,b-a 即为容器能使用的 swap 分区大小。此时容器最大使用内存为b
使用-m或--memory设置一个不小于 4M 的a值,使用--memory-swap设置一个参数-1,则表示限制容器能使用的内存大小为 a,且不限制容器使用 swap 分区大小。
提示:若出现如下提示:
WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.
可打开内核内存限制的操作:
[root@docker docker]# vi /etc/default/grub
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
root@docker:~# update-grub #重启系统
Memory reservation是一种软性限制,用于节制容器内存使用。使用--memory-reservation设置一个比-m小的值后,虽然容器最多可以使用-m设置的内存大小,但在宿主机内存资源紧张时,在系统的下次内存回收时,系统会回收容器的部分内存页,强迫容器的内存占用回到--memory-reservation设置的值大小。没有设置时(默认情况下)--memory-reservation的值则--memory-reservation和-m的限定的值相同。将它设置为 0 或设置的比-m的参数大等同于没有设置。这种软性机制,它不保证任何时刻容器使用的内存不会超过--memory-reservation限定的值,它只是确保容器不会长时间占用超过--memory-reservation限制的内存大小。
[root@docker docker]# docker run -d --name ubuntu_04 -m 2G --memory-reservation 1G ubuntu:16.04
#该容器能使用的内存大小为 2G,当宿主机内存资源紧张时,系统会回收1G内存,以便尝试将容器的内存锁紧到 1G 以下。
OOM killer机制指默认情况下,在出现 out-of-memory(OOM) 错误时,系统会杀死容器内的进程来获取更多空闲内存。通过设置--oom-kill-disable选项来禁止 OOM killer 杀死容器内进程。但请确保只有在使用了-m/--memory选项时才使用--oom-kill-disable禁用 OOM killer。如果没有设置-m选项,却禁用了 OOM-killer,可能会造成出现 out-of-memory 错误时,系统通过杀死宿主机进程或获取更改内存。
默认情况下,容器的内核可以交换出一定比例的swap。--memory-swappiness可设置从 0 到 100这个比例。0 表示关闭swap交换。100 表示所有的swap都可以交换。默认情况下,如果不使用--memory-swappiness,则该值从父进程继承而来。
注意:--memory-swappiness=0 表示禁用容器 swap 功能。
示例:设置-m=200m和--memory-swappiness=0
Step·:测试内存为199m(容器正常运行)
[root@clinet ~]# docker run -it -m 200m --memory-swappiness 0 progrium/stress --vm 1 --vm-bytes 199m
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [6] forked
stress: dbug: [6] allocating 208666624 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
stress: dbug: [6] freed 208666624 bytes
stress: dbug: [6] allocating 208666624 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
stress: dbug: [6] freed 208666624 bytes
stress: dbug: [6] allocating 208666624 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
Step2:测试内存为201m(容器终止运行)
[root@clinet ~]# docker run -it -m 200m --memory-swappiness 0 progrium/stress --vm 1 --vm-bytes 201m
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [7] forked
stress: dbug: [7] allocating 210763776 bytes ...
stress: dbug: [7] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (416) <-- worker 7 got signal 9
stress: WARN: [1] (418) now reaping child worker processes
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 0s
总结:
以上多种内存限制方式中,我们一般只使用设置-m=a,--memory-swappiness=0的方式来限制容器内存的使用,此时-m设置的a值,即为容器可使用的最大值。
| 参数 | 说明 |
| --cpuset-cpus="0,3" | 允许使用的 CPU 集,值可以为 0-3,0,1 |
| -c,--cpu-shares=0 | CPU 共享权值(相对权重) |
| --cpu-period=0 | 限制 CPU CFS 的周期,范围从 100ms~1s,即[1000, 1000000] |
| --cpu-quota=0 | 限制 CPU CFS 配额,必须不小于1ms,即 >= 1000 |
| --cpuset-mems="" | 允许在上执行的内存节点(MEMs),只对 NUMA 系统有效 |
表示容器中的进程可以在 cpu 1 和 cpu 3 上执行。
docker run -d --name ubuntu_07 --cpuset-cpus="1,3" ubuntu:16.04
默认情况下,所有的容器得到同等比例的 CPU 周期。在有多个容器竞争 CPU 时可设置每个容器能使用的 CPU 时间比例。这个比例叫作共享权值,通过-c或--cpu-shares设置。Docker 默认每个容器的权值为 1024。不设置或将其设置为 0,都将使用这个默认值。系统会根据每个容器的共享权值和所有容器共享权值和比例来给容器分配 CPU 时间。
举例:
假设有三个正在运行的容器,这三个容器中的任务都是 CPU 密集型的。第一个容器的 cpu 共享权值是 1024,其它两个容器的 cpu 共享权值是 512。第一个容器将得到 50% 的 CPU 时间,而其它两个容器就只能各得到 25% 的 CPU 时间了。如果再添加第四个 cpu 共享值为 1024 的容器,每个容器得到的 CPU 时间将重新计算。第一个容器的CPU 时间变为 33%,其它容器分得的 CPU 时间分别为 16.5%、16.5%、33%。
[root@clinet ~]# docker run -d -c 1024 progrium/stress -c 1
9423b7ae9b21f86ee22f2ab569f8deadef1657a7fcf526791037f10db063bf66
[root@clinet ~]# docker run -d -c 512 progrium/stress -c 1
ea17c016c1377d75a9af85df6c66181f53e4fef753780cc639a85234adfe89b7
[root@clinet ~]# docker run -d -c 512 progrium/stress -c 1
cc45e9082c218a6dc7a6405fd2ab4f38203bc78be2bc104f3cd8eccd6578af0d
[root@clinet ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cc45e9082c21 progrium/stress "/usr/bin/stress --v…" 22 seconds ago Up 20 seconds pedantic_moore
ea17c016c137 progrium/stress "/usr/bin/stress --v…" 25 seconds ago Up 24 seconds pensive_wing
9423b7ae9b21 progrium/stress "/usr/bin/stress --v…" 31 seconds ago Up 30 seconds sleepy_moore
[root@clinet ~]#
在多核系统上,CPU 时间权值是在所有 CPU 核上计算的。即使某个容器的 CPU 时间限制少于 100%,它也能使用各个 CPU 核的 100% 时间。
例如,假设有一个2核的系统。用-c=512的选项启动容器{C0},并且该容器只有一个进程,用-c=1024的启动选项为启动容器C1,此时C0也可以是占用100%
[root@clinet ~]# docker run -d -c 512 progrium/stress -c 1
6bda65f951693eec80455a32db301dbbf0350c1347f9ea70d50d8ac858e8fe56
[root@clinet ~]# docker run -d -c 1024 progrium/stress -c 1
41e7bc74b2c3dc04c6d45986121ebdd5f93f9f89f1ab805020084cdeb9b86fd2
[root@clinet ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
41e7bc74b2c3 progrium/stress "/usr/bin/stress --v…" About a minute ago Up About a minute sleepy_raman
6bda65f95169 progrium/stress "/usr/bin/stress --v…" About a minute ago Up About a minute peaceful_noyce
[root@clinet ~]#

总结:
在实际生产中几乎不会设置容器在某个cpu上运行,使用最多的就是通过权重限制cpu的使用。
Block IO 是另一种可以限制容器使用的资源。Block IO 指的是磁盘的读写,docker 可通过设置权重、限制 bps 和 iops 的方式控制容器读写磁盘的带宽。
| 参数 | 说明 |
--blkio-weight | 设置块 IO 权重,可以为容器指定一个 0 到 1000 的值,值越高,表示容器在 IO 资源分配中拥有更高的优先级。默认值为 0,表示不受限制。 |
| --device-read-bps | 限制设备的读速率,可以为容器中的设备指定一个最大的读速率,单位是字节/秒,例如 --device-read-bps=/dev/sda:1mb 表示限制容器中 /dev/sda 设备的读速率为 1MB/s |
| --device-write-bps | 限制设备的写速率,同上 |
| --device-read-iops | 限制设备的 IOPS(每秒输入操作数),可以为容器中的设备指定一个最大的 IOPS 数量,例如 --device-read-iops=/dev/sda:100 表示限制容器中 /dev/sda 设备的读 IOPS 为 100。 |
| --device-write-iops | 限制设备的 IOPS(每秒输出操作数),同上 |
bps是byte per second,每秒读写的数据量 ;iops是io per second,每秒io的次数。
注意:目前 Block IO 限额只对 direct IO(不使用文件缓存)有效
ubuntu_10容器的读写磁盘的带宽是ubuntu_11的两倍。
[root@docker docker]# docker run -d --name ubuntu_10 --blkio-weight 600 ubuntu:16.04
[root@docker docker]# docker run -d --name ubuntu_11 --blkio-weight 300 ubuntu:16.04
ubuntu_12容器写 /dev/sda 的速率为 30 MB/s。
bps:byte per second,每秒读写的数据量。
iops:io per second,每秒 IO 的次数。
[root@docker docker]#docker run -d --name ubuntu_12 --device-write-bps /dev/sda:30MB ubuntu:16.04
容器常用的资源限制就是上面所说的:1. -m=a,--memory-swappiness=0的方式来限制容器内存的使用;2. 通过-c或--cpu-shares设置权重限制cpu的使用;3. 通过bps和iops和权重限制block io。
当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我正在尝试将一个资源属性的默认值设置为另一个属性的值。我正在为我正在构建的tomcat说明书定义一个资源,其中包含以下定义。我想要可以独立设置的“名称”和“服务名称”属性。当未设置服务名称时,我希望它默认为为“名称”提供的任何内容。以下不符合我的预期:attribute:name,:kind_of=>String,:required=>true,:name_attribute=>trueattribute:service_name,:kind_of=>String,:default=>:name注意第二行末尾的“:default=>:name”。当我在Recipe的新block中引用我
我试图在Ubuntu14.04中使用Curl安装RVM。我运行了以下命令:\curl-sSLhttps://get.rvm.io|bash-sstable出现如下错误:curl:(7)Failedtoconnecttoget.rvm.ioport80:Networkisunreachable非常感谢解决此问题的任何帮助。谢谢 最佳答案 在执行curl之前尝试这个:echoipv4>>~/.curlrc 关于ruby-在Ubuntu14.04中使用Curl安装RVM时出错,我们在Stack
因此,在使用Sphinx时,搜索限制为1000个结果。但是,如果will_paginate生成的结果分页链接超过1000个,请不要考虑这一点,并提供指向超过1000/per_page的页面的链接。设置最大页数或类似内容的明显方法是什么?干杯。 最佳答案 我认为最好将参数:total_entries提交给方法paginate:@posts=Post.paginate(:page=>params[:page],:per_page=>30,:total_entries=>1000)will_paginate将仅为显示1000个结果所需的页
安装Rails时,一切都很好,但后来,我写道:rails-v和输出:/home/toshiba/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in`require':cannotloadsuchfile--rails/cli(LoadError)from/home/toshiba/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in`r
提供3种Ubuntu系统安装微信的方法,在Ubuntu20.04上验证都ok。1.WineHQ7.0安装微信:ubuntu20.04安装最新版微信--可以支持微信最新版,但是适配的不是特别好;比如WeChartOCR.exe报错。2.原生微信安装:linux系统下的微信安装(ubuntu20.04)--微信适配的最好,反应最快,但是微信版本只到2.1.1,版本太老,很多功能都没有。3.深度deepin-wine6安装微信:ubuntu20.04+系统deepin-wine6安装新版微信--综合比较好,当前个人使用此种方法1个月,微信版本3.4;没什么大问题,尚可。一、WineHQ7.0安装微信
目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一