【云原生|Docker】04-docker的资源限制

news/2024/11/29 17:31:18/

目录

前言

容器的生命周期 

1.  容器的启动过程

2.  容器的生命周期 

​编辑

内存限制 

1.  内存限制的相关参数

2.  内存限制方式 

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.5  OOM killer 

2.6   设置-m=a,--memory-swappiness=0

CPU限制 

1.  cpu限制相关参数

2.  cpu限制方式 

2.1  设置容器可以在哪个CPU上运行 

2.2  cpu权重设置 

Block io限制

1.  限制io的参数 

2.  IO限制操作 

2.1  block IO 权重 

2.2  限制bps和iops


前言

        用户内存限制就是对容器能使用的内存和交换分区的大小作出限制;主机运行若干容器,每个容器都需要cpu、内存以及IO资源,为避免因为单个容器占用过多资源而影响到所有其他容器乃至整个宿主机的性能,因此需要对容器资源进行限制。 

容器的生命周期 

         在说容器的资源限制之前,我们需要补充两点知识点。

1.  容器的启动过程

容器的启动过程说明:

  • 检查本地是否存在指定的镜像,如果没有就从指定的仓库下载
  • 利用镜像启动一个容器
  • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
  • 从宿主机配置的网桥接口中桥接一个虚拟接口到容器中去
  • 从地址池配置一个IP给容器
  • 执行用户指定的程序
  • 执行完毕后停止容器

2.  容器的生命周期 

        下面这张图实际上展现了容器的各个状态和操作,比如操作:start,kill,stop等。 

         一个docker host上会运行若干容器,每个容器都需要CPU、内存和 IO 资源。对于 KVM,VMware等虚拟化技术,用户可以控制分配多少 CPU、内存资源给每个虚拟机。对于容器,Docker 也提供了类似的机制避免某个容器因占用太多资源而影响其他容器乃至整个 host 的性能。因此我们需要对容器的内存,cpu,io,磁盘等做适当的限制。

内存限制 

1.  内存限制的相关参数

参数说明

-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)。

2.  内存限制方式 

2.1  设置-m,--memory,不设置--memory-swap

         使用-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

2.2  设置-m,--memory=a,--memory-swap=b,且b >a

示例: 当设置-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

2.3  设置-m,--memory=a,--memory-swap=-1

         使用-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		                     #重启系统  

 2.4  内存软限制(设置--memory-reservation)

        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 以下。

2.5  OOM killer 

        OOM killer机制指默认情况下,在出现 out-of-memory(OOM) 错误时,系统会杀死容器内的进程来获取更多空闲内存。通过设置--oom-kill-disable选项来禁止 OOM killer 杀死容器内进程。但请确保只有在使用了-m/--memory选项时才使用--oom-kill-disable禁用 OOM killer。如果没有设置-m选项,却禁用了 OOM-killer,可能会造成出现 out-of-memory 错误时,系统通过杀死宿主机进程或获取更改内存。 

2.6   设置-m=a,--memory-swappiness=0

         默认情况下,容器的内核可以交换出一定比例的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值,即为容器可使用的最大值。

CPU限制 

1.  cpu限制相关参数

参数说明

--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 系统有效

2.  cpu限制方式 

2.1  设置容器可以在哪个CPU上运行 

        表示容器中的进程可以在 cpu 1 和 cpu 3 上执行。 

 docker run -d --name ubuntu_07 --cpuset-cpus="1,3" ubuntu:16.04

2.2  cpu权重设置 

        默认情况下,所有的容器得到同等比例的 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 是另一种可以限制容器使用的资源。Block IO 指的是磁盘的读写,docker 可通过设置权重、限制 bps 和 iops 的方式控制容器读写磁盘的带宽。

1.  限制io的参数 

参数说明
--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(不使用文件缓存)有效

2.  IO限制操作 

2.1  block 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      

 2.2  限制bps和iops

        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。


http://www.ppmy.cn/news/382822.html

相关文章

pascal编程语言介绍

Pascal是一种过程式编程语言&#xff0c;由Niklaus Wirth于1968年设计并于1970年发布&#xff0c;并以法国数学家和哲学家Blaise Pascal的名字命名。Pascal可以运行在多种平台上&#xff0c;例如Windows、Mac OS和各种版本的UNIX/Linux。[3] 软件名称 Pascal 软件平台 Windows、…

mapreduce针对n列orc文件的读写

建300列的ORC表&#xff0c;可以用execl简单建一个300列&#xff0c;10000行的数据&#xff0c;复制成以tab分割的txt文件 hdfs dfs -put ddd.txt hdfs://hadoop:9000/tmp/input/ create table test_orc_300( c1 string , c2 string , c3 string , c4 …

Neutron DVR 分布式虚拟路由(Neutron Distributed Virtual Routing)

Neutron 作为 OpenStack 一个基础性关键服务&#xff0c;高可用性&#xff08;HA&#xff09;和扩展性是它的基本需求之一。对 neutron server 来说&#xff0c;因为它是无状态的&#xff0c;我们可以使用负载均衡器&#xff08;Load Balancer&#xff09;比如 HAProxy 来实现其…

正确理解 CSS 权值(不应存在进制)

这是我的博客。 欢迎在 freeCodeCamp 社区阅读原文。 前言 直接说结论&#xff0c;CSS 选择器&#xff08;selector&#xff09;的权值&#xff08;以下直接称为“CSS 权值”&#xff09;不应以进制来理解&#xff0c;因此进制既不是 10&#xff0c;100&#xff0c;也不是 25…

微信小程序知识云开发

一个小程序最多5个服务类目&#xff0c;一个月可以修改3次类目 小程序侵权投诉的发起与应对 软件著作权作品登记证书 实现小程序支付功能 如何借助官方支付api简单、高效率地实现小程序支付功能 借助小程序云开发实现 只需要一个简单的云函数 实现微信小程序支付功能 ex…

【Vue】从量子链网页钱包看vue项目结构以及开发部署最佳实践

项目介绍 qtum-web-wallet 是量子链推出的网页版钱包。 项目地址 https://github.com/qtumproject/qtum-web-wallet 项目采用vue搭建。 通过网页可以实现钱包的创建备份转账以及智能合约的部署调用功能。 项目结构 这个vue项目采用了vue-loader,所以整体用的是嵌套结构。 b…

Android P中的AVB校验

avb校验功能主要是由external/avb/libavb库实现的&#xff0c;该库主要完成的工作包括各个分区镜像的校验&#xff0c;签名验证&#xff0c;以及vbmeta数据的解析&#xff0c;包括了各种flags的处理以及dm-verity所需要的参数解析。avb校验库的主入口为 avb_slot_verify(AvbOps…

Android P 如何挂载system镜像到根目录

Android O/P 版本以来&#xff0c;谷歌加入了A/B system的特性&#xff0c;此时ramdisk和system是一起放在同一个system.img镜像中的。而系统起来之后也就不存在system分区了&#xff0c;而是直接把system镜像挂载到/根目录上。那么这个操作是怎么进行的呢&#xff1f; system.…