一.系统环境

服务器版本 docker软件版本 CPU架构
CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 x86_64

二.前言

默认情况下,容器没有资源限制,并且可以使用主机内核调度程序允许的尽可能多的给定资源。Docker 提供了控制容器可以使用多少内存或 CPU 的方法。

三.docker对于CPU和内存的限制

3.1 限制容器对内存的访问

重要的是不要让正在运行的容器消耗过多的主机内存。在 Linux 主机上,如果内核检测到没有足够的内存来执行重要的系统功能,它会抛出一个OOME或 Out Of Memory Exception,并开始杀死进程以释放内存。任何进程都可能被杀死,包括 Docker 和其他重要的应用程序。如果错误的进程被杀死,这可以会导致关闭整个系统。

Docker 可以强制执行内存硬限制,允许容器使用不超过给定数量的用户或系统内存,或软限制,允许容器根据需要使用尽可能多的内存,除非满足某些条件,例如何时内核检测到主机内存不足或争用。其中一些选项在单独使用或设置多个选项时具有不同的效果。这些选项中的大多数采用正整数,后跟b, k, m, g, 后缀来表示字节、千字节、兆字节或千兆字节。

常用的参数有

参数 参数解释
-m或者--memory= 容器可以使用的最大内存量。如果设置此选项,则允许的最小值为6m(6 兆字节)。也就是说,您必须将该值设置为至少 6 兆字节。
--memory-swap* 允许此容器交换到磁盘的内存量。
--memory-swappiness 默认情况下,主机内核可以换出容器使用的一定百分比的匿名页面。您可以设置--memory-swappiness为 0 到 100 之间的值,以调整此百分比。
--memory-reservation 允许您指定一个小于--memory在 Docker 检测到主机上的争用或内存不足时激活的软限制。如果使用--memory-reservation,则必须将其设置为低于--memory它才能优先。因为是软限制,所以不保证容器不超过限制。
--kernel-memory 容器可以使用的最大内核内存量。允许的最小值是4m。因为内核内存不能被换出,内核内存不足的容器可能会阻塞主机资源,这会对主机和其他容器产生副作用。
--oom-kill-disable 默认情况下,如果发生内存不足 (OOM) 错误,内核会终止容器中的进程。要更改此行为,请使用该--oom-kill-disable选项。仅在您还设置了该-m/--memory选项的容器上禁用 OOM kill。如果-m未设置该标志,主机可能会耗尽内存,内核可能需要终止主机系统的进程以释放内存。

本次主要使用hub.c.163.com/library/centos:latest镜像测试,没有该镜像需要自己docker pull一下

[root@k8smaster harbor]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hub.c.163.com/library/centos latest 328edcd84f1b 4 years ago 193MB

上传memload-7.0-1.r29766.x86_64.rpm安装包,用于模拟内存的使用

[root@k8smaster ~]# mkdir /memload

[root@k8smaster ~]# mv memload-7.0-1.r29766.x86_64.rpm /memload/

使用centos创建一个临时容器,-v /memload:/memload进行数据卷挂载,使容器/memload目录下有memload-7.0-1.r29766.x86_64.rpm安装包

[root@k8smaster ~]# docker run -it --rm -v /memload:/memload hub.c.163.com/library/centos:latest

#在容器里安装memload
[root@3c9083a7b318 /]# rpm -ivh /memload/memload-7.0-1.r29766.x86_64.rpm
Preparing... ################################# [100%]
Updating / installing...
1:memload-7.0-1.r29766 ################################# [100%] #memload 1000使内存使用1000M
[root@3c9083a7b318 /]# memload 1000
Attempting to allocate 1000 Mebibytes of resident memory...
^C [root@3c9083a7b318 /]# exit
exit

当在容器执行memload 1000时,打开另外一个Linux终端,使用docker stats查看该容器的内存使用,发现此容器使用了1013MiB内存,3.32GiB表示物理机的最大内存

CONTAINER ID   NAME                                                                                                            CPU %     MEM USAGE / LIMIT    MEM %     NET I/O           BLOCK I/O         PIDS
3c9083a7b318 friendly_roentgen 100.71% 1013MiB / 3.32GiB 29.79% 648B / 0B 32.5MB / 19.5MB 2

使用-m对容器的内存进行限制,-m 512m:表示容器内存最大使用512M,这时如果我们执行memload 1000,使用docker stats查看,最大内存也只能是512M

[root@k8smaster ~]# docker run -it --rm -m 512m -v /memload:/memload hub.c.163.com/library/centos:latest
[root@a81686360ba1 /]#
[root@a81686360ba1 /]# exit
exit

3.2 限制容器对CPU的访问

默认情况下,每个容器对主机 CPU 周期的访问是无限制的。您可以设置各种约束来限制给定容器对主机 CPU 周期的访问。大多数用户使用和配置 默认的 CFS 调度程序。您还可以配置实时调度程序。

CFS 是用于普通 Linux 进程的 Linux 内核 CPU 调度程序。几个运行时标志允许您配置对容器拥有的 CPU 资源的访问量。当您使用这些设置时,Docker 会修改主机上容器的 cgroup 的设置。

常用的参数有

参数 参数解释
--cpus= 指定容器可以使用多少可用 CPU 资源。例如,如果主机有两个 CPU,并且您设置--cpus="1.5"了 ,则容器最多可以保证一个半的 CPU。这相当于设置--cpu-period="100000"和--cpu-quota="150000"。
--cpu-period= 指定 CPU CFS 调度程序周期,它与 --cpu-quota. 默认为 100000 微秒(100 毫秒)。大多数用户不会更改默认设置。对于大多数用例,--cpus是一种更方便的选择。
--cpu-quota= 对容器施加 CPU CFS 配额。--cpu-period容器在被限制之前被限制的每微秒数。因此充当有效上限。对于大多数用例,--cpus是一种更方便的选择。
--cpuset-cpus 限制容器可以使用的特定 CPU 或内核。如果您有多个 CPU,则容器可以使用的逗号分隔列表或连字符分隔的 CPU 范围。第一个 CPU 编号为 0。有效值可能是0-3(使用第一个、第二个、第三个和第四个 CPU)或1,3(使用第二个和第四个 CPU)。
--cpu-shares 将此标志设置为大于或小于默认值 1024 的值,以增加或减少容器的重量,并允许它访问或多或少比例的主机 CPU 周期。这仅在 CPU 周期受到限制时才会强制执行。当有足够多的 CPU 周期可用时,所有容器都会根据需要使用尽可能多的 CPU。这样,这是一个软限制。--cpu-shares不会阻止容器以 swarm 模式调度。它优先考虑可用 CPU 周期的容器 CPU 资源。它不保证或保留任何特定的 CPU 访问权限。

对CPU的限制一般是设置CPU的亲和性,查看cpu信息:两个CPU:On-line CPU(s) list: 0,1

[root@k8smaster ~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 2
座: 1
NUMA 节点: 1
厂商 ID: GenuineIntel
CPU 系列: 6
型号: 142
型号名称: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
步进: 10
CPU MHz: 1991.381
BogoMIPS: 3984.01
超管理器厂商: VMware
虚拟化类型: 完全
L1d 缓存: 32K
L1i 缓存: 32K
L2 缓存: 256K
L3 缓存: 8192K
NUMA 节点0 CPU: 0,1
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec arat

使用centos镜像创建容器,里面运行5个cat进程

[root@k8smaster ~]# docker run -it --rm  -v /memload:/memload hub.c.163.com/library/centos:latest
[root@1a4fff793014 /]#
[root@1a4fff793014 /]# cat /dev/zero > /dev/null &
[1] 15
[root@1a4fff793014 /]# cat /dev/zero > /dev/null &
[2] 16
[root@1a4fff793014 /]# cat /dev/zero > /dev/null &
[3] 17
[root@1a4fff793014 /]# cat /dev/zero > /dev/null &
[4] 18
[root@1a4fff793014 /]# cat /dev/zero > /dev/null &
[5] 19
[root@1a4fff793014 /]# exit
exit

当在容器执行5个cat进程之后,打开另外一个Linux终端,查看每个cat进程运行在哪个CPU上,可以看到cat进程都运行在0号和1号CPU上

[root@k8smaster ~]# ps mo pid,comm,psr `pgrep cat`
PID COMMAND PSR
130120 cat -
- - 0
130143 cat -
- - 1
130144 cat -
- - 0
130145 cat -
- - 1
130146 cat -
- - 1

--cpuset-cpus=0 设置容器里的进程都运行在0号CPU上

[root@k8smaster ~]# docker run -it --rm  --cpuset-cpus=0 -v /memload:/memload hub.c.163.com/library/centos:latest
[root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
[1] 15
[root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
[2] 16
[root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
[3] 17
[root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
[4] 18
[root@0c3b37f8e679 /]# cat /dev/zero > /dev/null &
[5] 19
[root@0c3b37f8e679 /]#
[root@0c3b37f8e679 /]# exit
exit

--cpuset-cpus=1 设置容器里的进程都运行在1号CPU上

[root@k8smaster ~]# docker run -it --rm  --cpuset-cpus=1 -v /memload:/memload hub.c.163.com/library/centos:latest
[root@dac513abce35 /]#
[root@dac513abce35 /]# cat /dev/zero > /dev/null &
[1] 15
[root@dac513abce35 /]# cat /dev/zero > /dev/null &
[2] 16
[root@dac513abce35 /]#
[root@dac513abce35 /]# cat /dev/zero > /dev/null &
[3] 17
[root@dac513abce35 /]# cat /dev/zero > /dev/null &
[4] 18
[root@dac513abce35 /]# exit
exit

--cpuset-cpus=0,1 设置容器里的进程都运行在0,1号CPU上

[root@k8smaster ~]# docker run -it --rm  --cpuset-cpus=0,1 -v /memload:/memload hub.c.163.com/library/centos:latest
[root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
[1] 15
[root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
[2] 16
[root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
[3] 17
[root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
[4] 18
[root@244fe7eb8707 /]# cat /dev/zero > /dev/null &
[5] 19
[root@244fe7eb8707 /]#
[root@244fe7eb8707 /]# exit
exit

--cpuset-cpus=0-7,14 设置容器里的进程都运行在0-7,14号CPU上,由于没有那么多CPU所以报错

[root@k8smaster ~]# docker run -it --rm  --cpuset-cpus=0-7,14 -v /memload:/memload hub.c.163.com/library/centos:latest
docker: Error response from daemon: Requested CPUs are not available - requested 0-7,14, available: 0-1.
See 'docker run --help'.

注意:还可以设置容器对NVIDIA GPU 的访问,不过目前暂时没用到。

docker容器资源限制:限制容器对内存/CPU的访问的更多相关文章

  1. Docker 容器资源限制

    Docker 容器资源限制 默认情况下,一个容器并没有资源限制,并且该容器可以使用内核调度的所有资源.Docke提供了在启动容器时设置一些参数来控制该容器使用的内存.CPU和IO. 内存 OOME:在 ...

  2. docker stats监控容器资源消耗

    在容器的使用过程中,如果能及时的掌握容器使用的系统资源,无论对开发还是运维工作都是非常有益的.幸运的是 docker 自己就提供了这样的命令:docker stats. 默认输出 docker sta ...

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

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

  4. docker容器资源配额控制

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

  5. [转]Docker 生产环境之配置容器 - 限制容器资源

    默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的给定资源.Docker 提供了一些方法来控制容器可以使用多少内存.CPU 或块 IO,并设置 docker run 命令的运行时配置标志.本 ...

  6. Docker 限制容器资源

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

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

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

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

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

  9. docker网络-如何让外部网络访问容器资源

    docker网络-如何让外部网络访问容器资源 安装httpd 服务: docker:/root# docker exec -it f63b2633d146 bash bash-4.1# yum ins ...

随机推荐

  1. VirtualBox虚拟机安装Ubuntu系统后,增加内存空间和处理器核心数

    对于Linux爱好者而言,初次使用虚拟机时,一般都会使用默认的设置,例如硬盘空间.内存空间等等. 而往往在熟悉之后,安装了某些必要的软件,或者熟悉了实际的开发场景后,却发现原本给虚拟机分配的物理资源是 ...

  2. 【python基础】第04回 变量常量

    本章内容概要 1. python 语法注释 2. python 语法之变量常量 3. python 基本数据类型(整型(int),浮点型(float),字符串(str)) 本章内容详解 1. pyth ...

  3. 8.3 如何在Windows电脑安装Java开发环境(JDK)

    下载 来到JDK官方下载界面,找到Java SE 8(简称JDK 8)后面的JDK下载,来到该界面,先同意协议,然后下载对应平台的JDK,我们这里下载Windows x64. 安装 双击安装就行了了, ...

  4. hs-black 杂题选讲

    [POI2011]OKR-Periodicity 考虑递归地构造,设 \(\text{solve(s)}\) 表示字典序最小的,\(\text{border}\) 集合和 \(S\) 的 \(\tex ...

  5. CF487E Tourists 题解

    题目链接 思路分析 看到这道题首先想到的此题的树上版本.(不就是树链剖分的板子题么?) 但是此题是图上的两点间的走法,自然要想到是圆方树. 我们先无脑构建出圆方树. 我们先猜测:设后加入的节点权值为 ...

  6. PTA(BasicLevel)-1018 锤子剪刀布

    一.问题定义 大家应该都会玩"锤子剪刀布"的游戏:两人同时给出手势,胜负规则如下:         剪刀 > 布, 锤子 > 剪刀, 布 > 锤子 现给出两人的交 ...

  7. PTA(BasicLevel)-1014 福尔摩斯的约会

    一.问题描述 大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm.大侦探很快就明 ...

  8. labview入门到出家10(进阶)——CAN通讯

    ​          讲完串口,这边再讲一个labveiw工控程序中比较常用的CAN通讯吧.很久没有写过CAN通讯的程序了,网上一搜就是什么现场总线,控制器局域网总线,然后一堆复杂的协议.在这里还是一 ...

  9. 循环队列(严3.30)--------西工大NOJ习题.9

    #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> typedef struct _Q ...

  10. 吐泡泡_via牛客网

    题目 链接:https://ac.nowcoder.com/acm/contest/28537/E 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言 ...