docker在默认运行容器的情况下,是不会对运行的容器进行资源限制的,在自己的实验环境的话是随便你怎么弄的,不过在生产中是一定会对docker运行的容器进行资源限制的,如果不限制的话在生产中会带来很多弊端的。例如当资源没有做限制时,资源用完了后会导致其他的容器无法运行,在生产中的话是会部署几十个或者几百个容器的,这些容器都是共同使用的宿主机的资源CPU、内存、磁盘等等其他资源,当某一个容器占用宿主机的资源过多时,这时就会导致其他的容器无法正常运行,甚至也会导致一些服务的瘫痪,没有足够的内存运行服务的话,这时就会产生OOM现象,这时就会根据优先机制kill掉宿主机上最高的进程从而来释放空间,只要是宿主机的进程都是会有可能被kill掉的,进程被kill掉的话与之相关的进程的服务就会瘫痪。因此我们都会在创建容器的时候进行必要的资源限制。

1、资源限制的概念

  Docker对容器的资源限制类似于我们使用VMware Workstation创建的虚拟机,VMware Workstation创建时是可以对每一台虚拟机指定能使用的最大CPU和内存等,虚拟机在运行的过程中只能使用限定范围内的宿主机资源;Docker也是使用了类似的方法对容器进行资源限制,Docker利用cgroup功能限制每个容器能使用多少宿主机资源(主要是内存和CPU),这些限制条件可以在执行docker run命令时进行配置。



  在进行Docker资源限制时,一些功能需要得到宿主机的内核支持,在Docker服务器上执行docker info命令可以查看相关支持,如果内核中禁用了某些功能,会在输出结尾给出警告,比较常见的就是使用Ubuntu主机时会提示“WARNING: No swap limit support”。如果要使用这些功能,就必须在宿主机上取消禁用,例如针对Ubuntu作为Docker宿主机时的不支持swap分区内存限制,我们可以修改/etc/default/grub文件,添加启用功能。重启后再次执行docker info命令已不再显示warning,则说明已经取消了禁用。

登录后复制
root@node1:~# docker info
Client:
Debug Mode: false Server:

Containers: 0

Running: 0

Paused: 0

Stopped: 0

Images: 0

Server Version: 19.03.15

Storage Driver: overlay2

Backing Filesystem: extfs

Supports d_type: true

Native Overlay Diff: true

Logging Driver: json-file

Cgroup Driver: cgroupfs

Plugins:

Volume: local

Network: bridge host ipvlan macvlan null overlay

Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog

Swarm: inactive

Runtimes: runc

Default Runtime: runc

Init Binary: docker-init

containerd version: ea765aba0d05254012b0b9e595e995c09186427f

runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd

init version: fec3683

Security Options:

apparmor

seccomp

Profile: default

Kernel Version: 4.15.0-188-generic

Operating System: Ubuntu 18.04.6 LTS

OSType: linux

Architecture: x86_64

CPUs: 2

Total Memory: 3.827GiB

Name: node1.stars.org

ID: K3DP:CU5Z:H6RW:CAC5:5W72:DNGR:4ZXA:3D77:ZKDI:BMY5:HO7G:WFNZ

Docker Root Dir: /var/lib/docker

Debug Mode: false

Registry: https://index.docker.io/v1/

Labels:

Experimental: false

Insecure Registries:

127.0.0.0/8

Live Restore Enabled: false

Product License: Community Engine
WARNING: No swap limit support

root@node1:~# vim /etc/default/grub

GRUB_DEFAULT=0

GRUB_TIMEOUT_STYLE=hidden

GRUB_TIMEOUT=0

GRUB_DISTRIBUTOR=</span>lsb_release <span class="token parameter variable">-i</span> <span class="token parameter variable">-s</span> <span class="token operator"><span class="token file-descriptor important">2</span>&gt;</span> /dev/null <span class="token operator">||</span> <span class="token builtin class-name">echo</span> Debian<span class="token variable">

GRUB_CMDLINE_LINUX_DEFAULT=""

GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 cgroup_enable=memory swapaccount=1"

root@node1:~# update-grub

root@node1:~# reboot

root@node1:~# docker info

2、Docker容器的资源限制

Docker对容器的资源限制主要限制的是内存CPU

2.1、容器的内存限制

  Docker可以强制执行硬性的内存限制,也就是允许容器使用指定的内存大小;也是可以执行非硬性的内存限制,即容器可以使用尽可能多的使用多的内存,除非内核检测到主机上的内存不够用了,一般我们都是使用的硬性内存限制。

  在产生了OOM时,Dockerd会尝试调整Docker守护程序上的OOM的优先级来减轻这些风险,以便它比系统上的其他进程更不可能被杀死,但是容器的OOM优先级没有调整的话,这会使单个容器被杀死的可能性比Docker守护进程或其他系统进程被杀死的可能性会更大,不推荐通过在守护进程或容器上手动设置–oom-score-adj为极端负数,或通过在容器上设置–oom-kill-disable来跳过这些安全的措施。

  在指定容器内存大小时,大部分的选项取正整数,后面跟上b(字节)、k(千字节)、m(兆字节)和g(千兆字节)作为单位后缀。

OOM 优先级的机制

/proc/PID/oom_score_adj #范围为-1000到1000,值越高越容易被宿主机kill掉,如果将该值设置为-1000,则进程永远不会被宿主机kernel kill。

/proc/PIDJoom_adj #范围为-17到+15,取值越高越容易被干掉,如果是-17,则表示不能被kill,该设置参数的存在是为了和旧版本的Linux内核兼容。

/proc/PID/oom_score #这个值是系统综合进程的内存消耗量、CPU时间(utime+stime)、存活时间(uptime - start time)和oom_adj计算出的进程得分,消耗内存越多得分越高,越容易被宿主机kernel强制杀死。

–oom-score-adj:宿主机内核对进程使用的内存进行评分,评分最高的将被宿主机内核kill掉(取值范围为-1000到1000,越低越不会被kill掉),可以指定一个容器的评分为较低的负数,但会影响内核的正常工作,不推荐手动指定;

–oom-kill-disable:在设置了-m选项时使用,对某个容器关闭oom机制,无论是否出现内存溢出现象,该容器都不会被kill掉。如果不设置-m选项,主机在产生oom时也还是会kill到进程。除了MySQL这一类特别重要的容器,一般也不会指定

2.1.1、内存限制的参数

2.1.1.1、-m或–memory

  -m或–memory参数是可以指定容器能使用的最大内存,如果设置了此参数,则运行容器启动时最低内存大小为4M(后期的docker版本最小限制为6M)

登录后复制
root@node1:~# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest 9c6f07244728 2 days ago 5.54MB
ubuntu 18.04 8d5df41c547b 10 days ago 63.1MB
centos centos7.9.2009 eeb6ee3f44bd 11 months ago 204MB
nginx 1.18.0-alpine 684dbf9f01f3 16 months ago 21.9MB
nginx 1.18.0 c2c45d506085 16 months ago 133MB
root@node1:~# docker run -it --rm -m 2m ubuntu:18.04 bash
docker: Error response from daemon: Minimum memory limit allowed is 4MB.
See 'docker run --help'.
root@node1:~# docker run -it --rm -m 4m ubuntu:18.04 bash
root@03cab5616f4f:/# exit
exit

2.1.1.2、–memory-swap

  --memory-swap可以指定容器能使用的交换分区大小,该参数必须和物理内存限制同时存在才可使用,并且设定值不同也有不同的效果。

登录后复制
#当设置值大于物理内存时
[如果想要容器内可以使用交换分区,则设定值要大于物理内存大小,容器中的swap交换分区可用大小为交换分区设定值减去物理内存设定值(所得值大于0),例如容器物理内存限制为512m,要想使用100m的交换分区,则启动容器时交换分区的设定值为612m。]
root@node1:~# docker run -it --rm --memory-swap 30m ubuntu:18.04
docker: Error response from daemon: You should always set the Memory limit when using Memoryswap limit, see usage.
See 'docker run --help'.
root@node1:~# docker run -it --rm -m 512m --memory-swap 612m ubuntu:18.04
root@c9ceb920eae6:/# exit
exit #当设置值为0或等于物理内存时

[当值为0时,这时就可以忽略这个参数设置的,也就是不使用交换分区]

root@node1:~# docker run -it --rm -m 512m --memory-swap 0 ubuntu:18.04

root@bdc0b5f7d4d9:/# exit

exit

root@node1:~# docker run -it --rm -m 512m --memory-swap 512m ubuntu:18.04

root@aa0aeb40125a:/# exit

exit #当设置值为unset时

[当宿主机开启了swap功能,并且--memory-swap设定值为unset,即启动容器时未添加--memory-swap参数,则表示容器可使用的交换分区大小为2倍的物理内存大小;我们将容器的物理内存设定为512m,不添加--memory-swap参数时,容器能使用的交换分区大小为1g]

root@node1:~# docker run -it --rm -m 512m ubuntu:18.04

root@31e868d0dd49:/# exit

exit #当设置值为-1时

[当宿主机开启了swap功能,并且容器--memory-swap设定值为-1,表示容器可以使用宿主机的swap最大空间]

root@node1:~# docker run -it --rm -m 512m --memory-swap -1 ubuntu:18.04

root@3687aa4f055c:/# exit

exit
2.1.1.3、–memory-swappiness

  --memory-swappiness可以设置容器使用交换分区的倾向性,取值范围为0-100,0表示只有在物理内存不足的情况下才会使用交换分区,值越高表示越倾向于使用交换分区,取值为100时表示优先使用交换分区。通常我们不会使用到该参数。

2.1.1.4、–kernel-memory

  --kernel-memory可以指定容器可以使用的最大内核内存大小,由于内核内存与用户空间内存是相互隔离的,无法直接与用户空间内存进行交换,因此内核内存不足的容器可能会阻塞宿主机资源,这时就会对主机和其它容易及服务进程产生影响,在生产中不要设置容器的内核内存大小

2.1.1.5、–memory-reservation

  --memory-reservation允许指定小于物理内存值的软限制,当Docker检测到宿主机上的内存不足时会激活该限制。如果使用该参数时,设定值必须低于-m指定的物理内存才能使其优先,并且因为该参数是软限制,因而不能保证容器不超过设置的限制,但容器能使用的最大内存不会超过物理内存设定值。

2.1.2、容器内存限制的验证

  下载压力测试的镜像来验证容器的内存限制,并执行docker run lorel/docker-stress-ng -help命令来查看压测镜像的使用帮助,底部还有一个示例。



2.1.2.1、内存大小硬限制

不限制物理内存:

使用刚刚下载的压测镜像来创建一个容器,利用-vm指定2个工作进程,并设置每个工作进程最多允许使用256M的内存,并且宿主机也不限制当前容器的最大内存



限制物理内存:

使用-m或者–memory选项来指定容器的最大使用内存



宿主机验证cgroups:

宿主机对容器的资源限制主要是利用Docker的cgroup功能来实现的,可以在/sys/fs/cgroup/memory/docker/目录下找到对应容器ID,容器ID目录下的memory.limit_in_bytes文件中记录了宿主机对容器的内存资源限制;memory.limit_in_bytes文件中的值是将容器内存转化为字节,所以一般数值会很大;我们是可以使用命令来编辑这个文件的数值,从而修改了物理内存大小的限制



注意: 我们是可以通过文本编辑工具编辑文件里的内存限制值的,但是是在原有的基础上添加内存限制,如果修改值小于原有的内存的话是会报出"write error: Device or resource busy"

2.1.2.2、内存大小软限制

  内存的软限制是需要使用到–memory-reservation参数,这个参数设置的作用不是很大,设置了后使用docker stats查看时“MEM USAGE / LIMIT”的值还是在设置的最大内存值附件波动



容器内存设置软限制是,也是可以修改/sys/fs/cgroup/memory/docker/容器ID/memory.soft_limit_in_bytes文件,在这里我们是可以增加或者减少的

2.1.2.3、关闭OOM机制

  在docker运行容器时会受到OOM机制的影响的,可以创建一个容器来验证cgroup的功能,会发现默认是开启OOM机制的,这时当宿主机出现OOM时会出现被kill掉的情况,需要关闭OOM机制的话是需要添加–oom-kill-disable参数的。





如果关闭OOM机制的话从而会影响宿主机的正常工作,这个参数基本上是不会去添加的,除非一些特殊的情况就另外看咯

2.1.2.4、交换分区限制

  当启动一个容器设置的内存是256m,没有添加–memory-swap参数时,这时验证cgroup时memory.memsw.limit_in_bytes文件的值是默认设置的内存的2倍;当我们希望能使用128m的交换分区,则需要设置–memory-swap参数的值为384m,设置完后再查看memory.memsw.limit_in_bytes文件时,这时就已经是设定的384m。





注意: 这个–memory-swap参数设置的值比设置的的物理内存小的话是会报错的

2.2、容器的CPU限制

  在默认的情况下,每个容器对主机CPU周期的访问权限是没有限制的,但是我们是可以设置各种约束来限制给定容器访问宿主机的CPU的周期,大多数的用户使用使用的默认的CFS调度的方式,在Docker 1.13版本以及更高的版本,是还可以配置实时的优先级的。

2.2.1、容器CPU限制的参数

2.2.1.1、–cpus

  --cpus参数是在Docker1.13版本及后面的版本才开始使用的,也就是替代了之前版本中的–cpu-period(CPU调度周期)和–cpu-quota(CPU调度限制)参数;使用该参数可以指定容器使用宿主机中的可用CPU资源,假设宿主机中是有4个CPU,启动容器时设置了–cpu=“1.5”,则表示容器最多可以访问宿主机1.5个CPU,并且可以是在4个CPU的每个核心上都使用一点,但总数不能超过1.5个。

2.2.1.2、–cpuset-cpus

  --cpuset-cpus参数是用于指定容器运行的CPU编号,也就是我们说的绑核。

2.2.1.3、–cpuset-mem

  --cpuset-mem参数是设置使用哪个cpu的内存,这个仅对非统一内存访问(NUMA)的架构有效,这个参数用的少。

2.2.1.4、–cpu-shares

  --cpu-shares参数是用于设置cfs中调度的相对最大比例权重,cpu-share的值越高的容器,将会分得更多的时间片(宿主机多核CPU的总数为100%,假设容器A的–cpu-shares设定值为1024,容器B的–cpu-shares设定值为2048,则容器B能获得的宿主机CPU资源最多为容器1的2倍),默认的时间片是1024,最大是262144。

2.2.2、容器CPU限制的验证

2.2.2.1、不限制容器的CPU

  这里我的虚拟机cpu核数是2C的,我就直接先不对容器的CPU做限制了,分配2个CPU在加上两个工作进程,启动容器后再验证一下cgroup的一些功能。



2.2.2.2、限制容器的CPU





查看cpu.cfs_quota_us文件时,发现里面的值是100000,这个值是以百分比的形式来呈现的,每个核心CPU是按照1000位单位转换成百分比来进行资源分配的,如果是一个CPU的话就是100000/1000=100%,以此类推就好了。

注意: 给容器分配CPU资源时,要计划好一个容器分多少,是不可以超过宿主机的最大CPU核心数,超过的话是会报错的。

2.2.2.3、容器绑定指定CPU

  默认容器是没有与宿主机的CPU核心做绑定的,运行容器时是工作在宿主机上的任意一个CPU核心上;如果想要绑定CPU核心的话是要使用到–cpuset-cpus参数,Linux中是从0开始编号的,之所以1号CPU就是编号0,绑定多个CPU是用逗号隔开,连续的可以使用短横线。

2.2.2.4、基于cpu-share来切分CPU

  --cpu-shares这个参数是根据不同容器所占的权重来划分宿主机CPU资源,如果设置的权重越高,容器就越容易获得更多的宿主机CPU资源。这里我就启动两个容器来做测试了一个容器的–cpu-shares值设置为1000,另一个就设置500,这样的话查看CPU利用率的话会明显点。



2.2.2.5、动态修改cpu-share值(修改权重)

  这里我就直接动态修改一下test-t2容器的–cpu-shares值了,修改完是立即生效的,这个值是可以动态调大或调小的,因为我这里的宿主机的CPU核心是2C,CPU的%也就是200%了。





这时我又把test-t2容器的–cpu-shares值改回去,验证cgroup数据



    <div id="asideoffset"></div>
<div class="clearfix label-list"> <!-- <span>本文包含:</span>-->
<!-- -->
<!-- <a href="" target="_blank"></a>--> </div>
</div>

[转帖]Docker限制容器的资源的更多相关文章

  1. docker对容器进行资源限制

    对内存进行资源限制 docker run --memory=200m soymilk/stress 对cpu进行资源限制 终端1 docker run --name=test1 --cpu-share ...

  2. [转帖]Docker容器CPU、memory资源限制

    Docker容器CPU.memory资源限制 https://www.cnblogs.com/zhuochong/p/9728383.html 处理事项内容等 这一块内容感觉 不清楚.. 背景 在使用 ...

  3. Docker(十九)-Docker监控容器资源的占用情况

    启动一个容器并限制资源 启动一个centos容器,限制其内存为1G ,可用cpu数为2 [root@localhost ~]# docker run --name os1 -it -m 1g --cp ...

  4. Docker 限制容器资源

     默认情况下,容器没有资源的限制,它可以使用整个主机的所有资源.Dcoker提供了控制资源的方法,  多少内存,CPU,IO,都可以在docker run使用标志符来设置.   内存 Docker可以 ...

  5. docker 限制容器能够使用的资源

    docker 限制容器能够使用的内存,CPU,I/O 资源概述,内存是非可压缩资源,cpu是可压缩资源. 内存用超了,就发送Out Of Memory Exception,容器会被kill掉.所以内存 ...

  6. Docker 容器的资源限制 cgroup(九)

    目录 一.cgroup简介 二.CPU资源配额控制 1.CPU份额控制 2.CPU周期控制 3.CPU core控制 4.CPU配额控制参数的混合使用 二.对内存的限额 三.对 Block IO 的限 ...

  7. Docker监控容器资源的占用情况

    启动一个容器并限制资源 启动一个centos容器,限制其内存为1G ,可用cpu数为2 [root@localhost ~]# docker run --name os1 -it -m 1g --cp ...

  8. 【转帖】使用容器化和 Docker 实现 DevOps 的基础知识

    使用容器化和 Docker 实现 DevOps 的基础知识 https://www.kubernetes.org.cn/6730.html 2020-02-24 15:20 灵雀云 分类:容器 阅读( ...

  9. Docker与容器快速入门

    Docker之风席卷全球,但很多人觉得docker入门确实不太容易,其原因在于很多知识点上没准备好,在docker解决了什么问题.怎么解决的.用什么技术解决的都还没想清楚的时候就去探索docker组件 ...

  10. Docker系列之(三):Docker微容器Alpine Linux

    1. 前言 使用Docker创建容器时,基础镜像通常选择Ubuntu或Centos,不管哪个镜像的大小都在100MB以上. Alpine Linux是一个面向安全的轻型的Linux发行版. Alpin ...

随机推荐

  1. 技术解读丨GaussDB数仓高可用容灾利器之逻辑备份

    摘要:GaussDB数仓的Roach工具,同时提供物理备份和逻辑备份两种主要形态的备份.逻辑备份针对数据库的逻辑对象进行抽取和备份,能够有效地应对单表.schema级等较细粒度的备份,较为灵活和便利. ...

  2. WSDM Cup 2020大赛金牌参赛方案全解析

    近日,在美国休斯敦闭幕的第13届网络搜索与数据挖掘国际会议(WSDM 2020)上,华为云语音语义创新Lab带领来自华南理工大学.华中科技大学.江南大学.武汉大学的四位学生组成的联合团队"X ...

  3. 云小课|GaussDB(DWS)数据存储尽在掌控,冷热数据切换自如

    阅识风云是华为云信息大咖,擅长将复杂信息多元化呈现,其出品的一张图(云图说).深入浅出的博文(云小课)或短视频(云视厅)总有一款能让您快速上手华为云.更多精彩内容请单击此处. 摘要: GaussDB( ...

  4. CentOS7安装maven,mvn clean -DskipTests package

    1.JAVA_HOME 首先确保正确安装并配置了JAVA_HOME 我这里安装了jdk1.8 2.下载maven 3.6.3 wget https://mirrors.tuna.tsinghua.ed ...

  5. 高性能 Jsonpath 框架,Snack3 3.2.57 发布

    Snack3,一个高性能的 JsonPath 框架 借鉴了 Javascript 所有变量由 var 申明,及 Xml dom 一切都是 Node 的设计.其下一切数据都以ONode表示,ONode也 ...

  6. ChatGPT带你入门机器学习:逻辑回归模型博客和小红书风格文案一次搞定!

    打脸了 顺手向大家演示一下如何用 ChatGPT 写技术博客吧,其实蛮简单的,特别需要操心的是它会一本正经的胡说八道,还信誓旦旦的.我们要审查它的回答,万不可全信. 为了便于阅读,我把prompt加粗 ...

  7. AcWing第四场周赛

    比赛链接:Here AcWing 3694. A还是B 签到题 void solve() { int n; string s; cin >> n >> s; int t = c ...

  8. 【动态规划】动态规划基础 (OI wiki)

    文章来自 OI wiki ,转载仅作学习使用 动态规划应用于子问题重叠的情况: 要去刻画最优解的结构特征: 尝试递归地定义最优解的值(就是我们常说的考虑从 \(i - 1\) 转移到 \(i\)): ...

  9. Android 原生 SQLite 数据库的一次封装实践

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/CL4MsQEsrWS8n7lhXCOQ_g作者:Li Bingyan 本文主要讲述原生SQLi ...

  10. 无需代码绘制人工神经网络ANN模型结构图的方法

      本文介绍几种基于在线网页或软件的.不用代码的神经网络模型结构可视化绘图方法.   之前向大家介绍了一种基于Python第三方ann_visualizer模块的神经网络结构可视化方法,大家可以直接点 ...