【云原生】Docker容器资源限制(CPU/内存/磁盘)

news2024/12/27 17:42:24

目录

​编辑

1.限制容器对内存的使用

2.限制容器对CPU的使用

3.block IO权重

4.实现容器的底层技术

1.cgroup

1.查看容器的ID

2.在文件中查找

2.namespace

1.Mount

2.UTS

3.IPC

4.PID

5.Network

6.User


1.限制容器对内存的使用

⼀个 docker host 上会运⾏若⼲容器,每个容器都需要 CPU、内存和 IO 资源。对于 KVM,VMware 等虚拟化技 术,⽤户可以控制分配多少 CPU、内存资源给每个虚拟机。对于容器,Docker 也提供了类似的机制避免某个容器 因占⽤太多资源⽽影响其他容器乃⾄整个 host 的性能。

内存限额 与操作系统类似,容器可使⽤的内存包括两部分:物理内存和 swap。 Docker 通过下⾯两组参数来控制容器内存 的使⽤量。

-m 或者--memory:设置内存的使用限额,例如100M,2G。
--memory-swap:设置内存+swap的使用限额。

当我们执行如下命令:

[root@localhost ~]# docker run -it -m 200M --memory-swap=300M centos:7

其含义是允许该容器最多使⽤ 200M 的内存和 100M 的 swap。默认情况下,上⾯两组参数为 -1,即对容器内存 和 swap 的使⽤没有限制。

下⾯我们将使⽤ progrium/stress 镜像来学习如何为容器分配内存。该镜像可⽤于对容器执⾏压⼒测试。执⾏如下 命令:

[root@localhost ~]# docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
​
选项:
--vm 1:启动 1 个内存⼯作线程
--vm-bytes 280M:每个线程分配 280M 内存

因为299M在可分配的范围内,所以工作线程能够正常工作,过程是:

[root@localhost ~]# 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 [8] forked
stress: dbug: [8] allocating 313524224 bytes ...
stress: dbug: [8] touching bytes in strides of 4096 bytes ...
stress: dbug: [8] freed 313524224 bytes
stress: dbug: [8] allocating 313524224 bytes ...
stress: dbug: [8] touching bytes in strides of 4096 bytes ...
stress: dbug: [8] freed 313524224 bytes
stress: dbug: [8] allocating 313524224 bytes ...
  1. 分配299内存

  2. 释放299内存

  3. 再分配299内存

  4. 再释放299内存

  5. 一直循环

如果让工作线程分配的内存超过300M,结果如下:

[root@localhost ~]# 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

注意:分配的内存超过限额,stress线程报错,容器退出。

如果在启动容器时只指定 -m ⽽不指定 --memory-swap,那么 --memory-swap 默认为 -m 的两倍,⽐如:

docker run -it -m 200M centos

容器最多使⽤ 200M 物理内存和 200M swap。

2.限制容器对CPU的使用

默认设置下,所有容器可以平等地使⽤ host CPU 资源并且没有限制。 Docker 可以通过 -c 或 --cpu-shares 设置容器使⽤ CPU 的权重。如果不指定,默认值为 1024。 与内存限额不同,通过 -c 设置的 cpu share 并不是 CPU 资源的绝对数量,⽽是⼀个相对的权重值。某个容器最终 能分配到的 CPU 资源取决于它的 cpu share 占所有容器 cpu share 总和的⽐例。

换句话说:通过 cpu share 可以设置容器使⽤ CPU 的优先级。

⽐如在 host 中启动了两个容器:

[root@localhost ~]# docker run --name 'centos-1' -c 1024 --cpu 1 centos:7
[root@localhost ~]# docker run --name 'centos-2' -c 512 --cpu 1 centos:7
​
选项:
-c:CPU权重
--cpu:CPU核数

centos-1 的 cpu share 1024,是centos-2的两倍。当两个容器都需要 CPU 资源时,centos-1 可以得 到的 CPU 是 centos-2 的两倍。

需要特别注意的是,这种按权重分配 CPU 只会发⽣在 CPU 资源紧张的情况下。如果centos-1 处于空闲状态, 这时,为了充分利⽤ CPU 资源,centos-2 也可以分配到全部可⽤的 CPU。

例子:

启动 container_A,cpu share 为 1024:

[root@localhost ~]# docker run --name container_A -it -c 1024 progrium/stress --cpu 4
stress: info: [1] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 12000us
stress: dbug: [1] --> hogcpu worker 4 [7] forked
stress: dbug: [1] using backoff sleep of 9000us
stress: dbug: [1] --> hogcpu worker 3 [8] forked
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] --> hogcpu worker 2 [9] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [10] forked

--cpu ⽤来设置⼯作线程的数量。因为当前 host 只有 1 颗 CPU,所以⼀个⼯作线程就能将 CPU 压满。如果 host 有多颗 CPU,则需要相应增加 --cpu 的数量。

启动 container_B,cpu share 为 512:

[root@localhost ~]# docker run --name container_B -it -c 512 progrium/stress --cpu 4
stress: info: [1] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [7] forked

在 host 中执⾏ top,查看容器对 CPU 的使⽤情况:

[root@localhost ~]# top
top - 22:22:11 up 55 min,  4 users,  load average: 5.49, 2.17, 0.84
Tasks: 147 total,   9 running, 138 sleeping,   0 stopped,   0 zombie
%Cpu(s): 99.8 us,  0.2 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  3865552 total,  2876864 free,   279432 used,   709256 buff/cache
KiB Swap:  2097148 total,  2095436 free,     1712 used.  3284060 avail Mem
​
   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 11431 root      20   0    7308     96      0 R  66.4  0.0   1:59.51 stress
 11433 root      20   0    7308     96      0 R  66.4  0.0   2:00.93 stress
 11434 root      20   0    7308     96      0 R  66.4  0.0   1:57.31 stress
 11432 root      20   0    7308     96      0 R  66.1  0.0   2:00.42 stress
 12343 root      20   0    7308     96      0 R  33.6  0.0   0:05.46 stress
 12342 root      20   0    7308     96      0 R  33.2  0.0   0:05.40 stress
 12344 root      20   0    7308     96      0 R  33.2  0.0   0:05.48 stress
 12341 root      20   0    7308     96      0 R  32.9  0.0   0:05.40 stress

现在挂起container_A

[root@localhost ~]# docker pause container_A
container_A

top 显示 container_B 在 container_A 空闲的情况下能够⽤满整颗 CPU

3.block IO权重

默认情况下,所有容器能平等地读写磁盘,可以通过设置 --blkio-weight 参数来改变容器 block IO 的优先级。

--blkio-weight 与 --cpu-shares 类似,设置的是相对权重值,默认为 500。在下⾯的例⼦中,container_A 读写磁 盘的带宽是 container_B 的两倍。

[root@localhost ~]# docker run -it --name container_A --blkio-weight 600 centos
[root@localhost ~]# docker run -it --name container_B --blkio-weight 300 centos

限制 bps 和 iops

  • bps 是 byte per second,每秒读写的数据量。

  • iops 是 io per second,每秒 IO 的次数。

可通过以下参数控制容器的 bps 和 iops:

  • --device-read-bps,限制读某个设备的 bps。

  • --device-write-bps,限制写某个设备的 bps。

  • --device-read-iops,限制读某个设备的 iops。

  • --device-write-iops,限制写某个设备的 iops。

例子:限制容器写/dev/sda的速率为30MB/s

[root@localhost ~]# docker run -it --device-write-bps /dev/sda:30MB centos:7
[root@85ec78d68f3d /]# dd if=/dev/zero of=1.txt bs=1M count=300
300+0 records in
300+0 records out
314572800 bytes (315 MB) copied, 0.116481 s, 2.7 GB/s
[root@85ec78d68f3d /]# dd if=/dev/zero of=1.txt bs=1M count=300 oflag=direct
300+0 records in
300+0 records out
314572800 bytes (315 MB) copied, 9.91958 s, 31.7 MB/s

通过 dd 测试在容器中写磁盘的速度。因为容器的⽂件系统是在 host /dev/sda 上的,在容器中写⽂件相当于对 host /dev/sda 进⾏写操作。另外,oflag=direct 指定⽤ direct IO ⽅式写⽂件,这样 --device-write-bps 才能⽣ 效。

4.实现容器的底层技术

为了更好地理解容器的特性,本节我们将讨论容器的底层实现技术。

cgroup 和 namespace 是最重要的两种技术。cgroup 实现资源限额, namespace 实现资源隔离。

1.cgroup

cgroup 全称 Control Group。Linux 操作系统通过 cgroup 可以设置进程使⽤ CPU、内存 和 IO 资源的限额。-- cpu-shares、-m、--device-write-bps 实际上就是在配置 cgroup。

cgroup 到底⻓什么样⼦呢?我们可以在 /sys/fs/cgroup 中找到它。还是⽤例⼦来说明,启动⼀个容器,设置 -- cpu-shares=512:

1.查看容器的ID
[root@localhost ~]# docker ps -a --no-trunc
CONTAINER ID                                                       IMAGE      COMMAND       CREATED         STATUS                        PORTS     NAMES
85ec78d68f3d9daa9b5604845c18364760c5f1be506098e6cac81717eb0e3e69   centos:7   "/bin/bash"   5 minutes ago   Exited (127) 19 seconds ago             youthful_merkle
2.在文件中查找
在 /sys/fs/cgroup/cpu/docker ⽬录中,Linux 会为每个容器创建⼀个 cgroup ⽬录,以容器⻓ID 命名:
[root@localhost ~]# ls /sys/fs/cgroup/cpu/docker/414090cec75558162c3679b913af2c739b44bd6228f8184662e7a2e253f12a69/
cgroup.clone_children  cpuacct.stat           cpu.cfs_period_us      cpu.rt_runtime_us      notify_on_release
cgroup.event_control   cpuacct.usage          cpu.cfs_quota_us       cpu.shares             tasks
cgroup.procs           cpuacct.usage_percpu   cpu.rt_period_us       cpu.stat

⽬录中包含所有与 cpu 相关的 cgroup 配置,⽂件 cpu.shares 保存的就是 --cpu-shares 的配置,值为 512。 同样的,/sys/fs/cgroup/memory/docker 和 /sys/fs/cgroup/blkio/docker 中保存的是内存以及 Block IO 的 cgroup 配置。

2.namespace

在每个容器中,我们都可以看到⽂件系统,⽹卡等资源,这些资源看上去是容器⾃⼰的。拿⽹卡来说,每个容器都 会认为⾃⼰有⼀块独⽴的⽹卡,即使 host 上只有⼀块物理⽹卡。这种⽅式⾮常好,它使得容器更像⼀个独⽴的计 算机。

Linux 实现这种⽅式的技术是 namespace。namespace 管理着 host 中全局唯⼀的资源,并可以让每个容器都觉 得只有⾃⼰在使⽤它。换句话说,namespace 实现了容器间资源的隔离。

Linux 使⽤了六种 namespace,分别对应六种资源:Mount、UTS、IPC、PID、Network 和 User,下⾯我们分 别讨论。

1.Mount

Mount namespace 让容器看上去拥有整个⽂件系统。

容器有⾃⼰的 / ⽬录,可以执⾏ mount 和 umount 命令。当然我们知道这些操作只在当前容器中⽣效,不会影响 到 host 和其他容器。

2.UTS

简单的说,UTS namespace 让容器有⾃⼰的 hostname。 默认情况下,容器的 hostname 是它的短ID,可以通 过 -h 或 --hostname 参数设置。

[root@localhost ~]# docker run -it -h test1 centos:7
[root@test1 /]#
3.IPC

IPC namespace 让容器拥有⾃⼰的共享内存和信号量(semaphore)来实现进程间通信,⽽不会与 host 和其他 容器的 IPC 混在⼀起。

4.PID

我们前⾯提到过,容器在 host 中以进程的形式运⾏。例如当前 host 中运⾏了两个容器:

[root@localhost ~]# docker inspect centos-2 -f '{{.State.Pid}}'
14300
[root@localhost ~]# docker inspect youthful_merkle -f '{{.State.Pid}}'
14568

⽽且进程的 PID 不同于 host 中对应进程的 PID,容器中 PID=1 的进程当然也不是 host 的 init 进程。也就是说: 容器拥有⾃⼰独⽴的⼀套 PID,这就是 PID namespace 提供的功能。

5.Network

Network namespace 让容器拥有⾃⼰独⽴的⽹卡、IP、路由等资源

6.User

User namespace 让容器能够管理⾃⼰的⽤户,host 不能看到容器中创建的⽤户。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/799118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux下6818开发板(ARM)】SecureCRT串口和交叉编译工具(巨细版!)

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

策略:一致性行动原则,力出一孔

策略&#xff1a;一致性行动的原则 策略有很多种解释 经常跟战略混淆 趣讲大白话&#xff1a;就是指导方针 【趣讲信息科技238期】 **************************** 教员的游击战“16字口诀”很经典 敌进我退&#xff0c;敌退我进&#xff0c; 敌疲我打&#xff0c;敌驻我扰 曾国…

小城市当程序员好不好?

在职业发展中&#xff0c;小城市和大城市都有各自的机会和挑战。在大城市&#xff0c;C#的应用比例可能相对较低&#xff0c;学习C可能有一定的难度&#xff0c;而学习Java最好有人指导。在小城市&#xff0c;机会相对较少&#xff0c;跳槽的选择也有限。然而&#xff0c;小城市…

想转嵌入式或工控上位机,哪个前途更光明?

上位机开发的需求目前很大&#xff0c;根据BOSS上的数据&#xff0c;C#和WPF的需求较多。作为WPF开发者&#xff0c;薪资水平可以有较大的变动&#xff0c;主要取决于经验&#xff0c;20,000到30,000元的薪资并不难达到。工作环境因工种而异&#xff0c;不可避免地需要进行现场…

消息队列 - 数据库操作

这里写自定义目录标题 前言数据表的插入删除操作关于实现接口类的几个注意实现实现封装创建DataBaseManager 类另一种获取Bean对象的方式 对数据库进行单元测试 前言 上一篇博客, 我们将消息队列的实体类创建完毕了, 并且还写了一些关于数据库的操作, 接下来我们继续进行关于数…

【Spring Cloud Alibaba】Sentinel运行原理

文章目录 前言1、基本原理2、SphU.entry()2.1、StringResourceWrapper2.2、Entry 3、entry.exit()4、Context 前言 本文基于sentinel-1.8.0版本 Sentinel 是面向分布式服务架构的流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从限流、流量整形、熔断降级、系统负载保…

fast segment anything

[论文解读]比sam快50倍的通用视觉模型fastsam(Fast Segment Anything) - 知乎MetaAI提出的能够“分割一切”的视觉基础大模型SAM提供了很好的分割效果&#xff0c;为探索视觉大模型提供了一个新的方向。 虽然sam的效果很好&#xff0c;但由于sam的backbone使用了vit&#xff0c…

Nexus上传jar包到私有Maven仓库的方法: 页面Upload 和命令

Upload和mvn deploy命令两种上传方式的应用场景不同&#xff0c;手动上传适用于工具类的jar包&#xff0c;比如项目需要引入的lib文件&#xff0c;这种可以选择手动上传。复杂的、有较多依赖的jar包则需要连同pom文件一起上传&#xff0c;此时需要使用mvn deploy。 登录Nexus&a…

ESP32 官方AT固件编译(从零开始环境搭建到编译完成全过程)

1、下载VMware免费版 https://download3.vmware.com/software/WKST-PLAYER-1702/VMware-player-full-17.0.2-21581411.exe 2、下载Ubuntu &#xff08;ubuntu-22.04.2-desktop-amd64.iso&#xff09;** https://releases.ubuntu.com/jammy/ubuntu-22.04.2-desktop-amd64.iso…

Redis学习2--使用java操作Redis

1、java操作Redis库的比较 Redis有各种语言的客户端可以来操作redis数据库&#xff0c;其中java语言主要有Jedis与lettuce &#xff0c;Spring Data Redis封装了上边两个客户端&#xff0c;优缺点如下&#xff1a; 2、使用Jedis操作Redis Jedis使用的基本步骤&#xff1a; 引…

python_PyQt5开发工具结构基础

写在前面&#xff1a; 考虑已经陆陆续续在平台写了几篇PyQt5开发的小工具&#xff0c;后续还会继续发布新的新工具&#xff0c;这些工具都基于一个基础结构往上构建&#xff0c;这个基础结构是本人自己开发的习惯&#xff0c;在这里把工具的基础结构代码抽取出来&#xff0c;后…

ARM汇编中预定义的寄存器和协处理器名称

一、是什么? 预定义的寄存器和协处理器名称,汇编代码中直接使用就可以. # 二、使用步骤 1.引入库 代码如下(示例): .global _start _start:mov r0,#0x18LDR R3,=0x55555555mov r1,#0x18LDR R1,=0x55555555mov r2,#

HTML:常用标签归纳(用法 + 代码 + 显示效果)

目录 标签span 文本标签div 竖着布局的标签h1~h6 标题标签p 段落标签a 超链接标签href 资源位置target 打开位置 a 锚点标签固定位置 br 换行标签img 图片标签src 属性altwidth 宽度 height 高度 列表标签ul 无序列表ol 有序标签设置表示顺序 table 表格属性border 边框width 宽…

Unity Shader - if 和 keyword 的指令比较

文章目录 环境TestingIf4Sampleunity shaderlab 中的 TestingIf4Sample.shadergraphics analyzer 中的 TestingIf4Sample.glsl TestingKW4Sampleunity shaderlab 中的 TestingKW4Sample.shadergraphics analyzer 中的 TestingKW4Sample.glsl 比较 环境 Unity : 2020.3.37f1 Pi…

gin框架内容(三)--中间件

gin框架内容&#xff08;三&#xff09;--中间件 Gin框架允许开发者在处理请求的过程中&#xff0c;加入用户自己的函数。这个函数就叫中间件&#xff0c;中间件适合处理一些公共的业务逻辑&#xff0c;比如登录认证、权限校验、数据分页、记录日志、耗时统计等 即比如&#x…

虚拟个家用服务器集群(2):PVE 系统安装启动

风无痕 July 26,2023 前言 很多人想建个人博客类的网站&#xff0c;这就需要网站服务器&#xff1b;需要管理手机、电脑中积累的照片&#xff0c;每张照片可都是人生一个片段的记录&#xff0c;需要管理微信中收发的各种文档等等&#xff0c;这就需要一台 NAS 即 Network Att…

【JMeter】JMeter添加插件

目录 一、前言 二、插件管理器 三、推荐插件 1.Custom Thread Groups &#xff08;1&#xff09;Ultmate Thread Group &#xff08;2&#xff09;Stepping Thread Group 2.3 Basic Graph 资料获取方法 一、前言 ​ 在我们的工作中&#xff0c;我们可以利用一些插件来帮…

【机器学习】西瓜书学习心得及课后习题参考答案—第3章线性模型

过了一遍第三章&#xff0c;大致理解了内容&#xff0c;认识了线性回归模型&#xff0c;对数几率回归模型&#xff0c;线性判别分析方法&#xff0c;以及多分类学习&#xff0c;其中有很多数学推理过程以参考他人现有思想为主&#xff0c;没有亲手去推。 术语学习 线性模型 l…

网站构建说明

一、网站中的web构建 HTML 4.01CSS 的使用 &#xff08;样式表&#xff09;XHTMLXML 和 XSLT客户端脚本服务器端脚本通过 SQL 管理数据Web 的未来 HTML 4.01 通过 HTML 4.01&#xff0c;所有的格式化信息可以被移出 HTML 文档&#xff0c;转而放入一个独立的样式表中。 层叠样…

linux实现运行java分包部署

1.打好包之后 找到bin文件夹下的 startup.sh文件 2.cd 进入bin文件夹下 3.执行 sh startup.sh 运行命令 4.如果出现此错误 是Windows和Linux的.sh脚本文件格式不同&#xff0c;如果在脚本中有空行&#xff0c;脚本是在Windows下进行编辑之后上传到linux上去执行的话&#xff0c…