1、限制容器的资源

  默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的尽可能多的给定资源。Docker提供了控制容器可以使用多少内存或CPU的方法,设置docker run命令的运行时配置标志。本篇提供有关何时应设置此类限制的详细信息以及设置这些限制的可能含义。

  其中许多功能都要求您的内核支持Linux功能。要检查支持,可以使用该 docker info命令。如果内核中禁用了某项功能,您可能会在输出结尾处看到一条警告,如下所示:WARNING: No swap limit support,请参阅操作系统的文档以启用它们,了解更多

root@caicai:~# docker info
Client:
Debug Mode: false Server:
Containers: 13
Running: 1
Paused: 0
Stopped: 12
Images: 10
Server Version: 19.03.11
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: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
init version: fec3683
Security Options:
apparmor
seccomp
Profile: default
Kernel Version: 4.4.0-170-generic
Operating System: Ubuntu 16.04.6 LTS
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 1.953GiB
Name: caicai
ID: XPTV:KT7U:BW45:AIPF:YOYN:ZIU3:3LF7:DIHV:NKJ2:BBSA:7TU2:NH3S
Docker Root Dir: /var/lib/docker
Debug Mode: false
Username: centercai
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
172.17.0.1:5000
127.0.0.0/8
Registry Mirrors:
https://y0qd3iq.mirror.aliyuncs.com/
Live Restore Enabled: false WARNING: No swap limit support

2、内存

2.1 内存不足的风险

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

  Docker尝试通过调整Docker守护程序上的OOM优先级来降低这些风险,以便它比系统上的其他进程更不可能被杀死。容器上的OOM优先级未调整。这使得单个容器被杀死的可能性比Docker守护程序或其他系统进程被杀死的可能性更大。您不应试图通过--oom-score-adj 在守护程序或容器上手动设置为极端负数或通过设置容器来绕过这些安全措施--oom-kill-disable

  有关Linux内核的OOM管理的更多信息,请参阅内存不足管理

  您可以通过以下方式降低OOME导致系统不稳定的风险:

  • 在将应用程序投入生产之前,请执行测试以了解应用程序的内存要求。
  • 确保您的应用程序仅在具有足够资源的主机上运行。
  • 限制容器可以使用的内存量,如下所述。
  • 在Docker主机上配置交换时要小心。交换比内存更慢且性能更低,但可以提供缓冲以防止系统内存耗尽。
  • 考虑将容器转换为服务,并使用服务级别约束和节点标签来确保应用程序仅在具有足够内存的主机上运行

2.2 限制容器对内存设有的设置

  Docker可以强制执行硬内存限制,允许容器使用不超过给定数量的用户或系统内存或软限制,这允许容器使用尽可能多的内存,除非满足某些条件,例如内核检测到主机上的低内存或争用。当单独使用或设置了多个选项时,其中一些选项会产生不同的效果。

  大部分的选项取正整数,跟着一个后缀b,k, m,g,,表示字节,千字节,兆字节或千兆字节。

选项

描述

-m or --memory=

容器可以使用的最大内存量。如果设置此选项,则允许的最小值为4m

--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杀手。如果-m 未设置该标志,则主机可能会耗尽内存,并且内核可能需要终止主机系统的进程才能释放内存。

2.2.1 --memory-swap 设置

(1)介绍

  --memory-swap 是一个修饰符标志,只有在--memory 设置时才有意义。使用swap允许容器在容器耗尽可用的所有RAM时将多余的内存需求写入磁盘。对于经常将内存交换到磁盘的应用程序,性能会受到影响。

(2)它的设置会产生复杂的效果:

  • 如果--memory-swap 设置为正整数,那么这两个--memory和 --memory-swap 必须设置。--memory-swap 表示可以使用的memory and swap,并--memory 控制非交换内存(物理内存)使用的量。所以如果--memory="300m" 和--memory-swap="1g",容器可以使用300米的内存和700米(1g - 300m)swap。
  • 如果--memory-swap 设置为0,则忽略该设置,并将该值视为未设置。
  • 如果--memory-swap 设置为与值相同的值--memory,并且--memory设置为正整数,则容器无权访问swap。请参考下面阻止容器使用交换。
  • 如果--memory-swap 未设置--memory 设置,则容器可以使用两倍于--memory设置的swap,主机容器需要配置有swap。例如,如果设置--memory="300m" 和--memory-swap 未设置,容器可以使用300米的内存和600米的swap。
  • 如果--memory-swap 明确设置为-1,则允许容器使用无限制swap,最多可达宿主机系统上可用的数量
  • 在容器内部,工具如free 报告主机的swap,而不是容器内真正可用的内存。不要依赖free 或类似工具来确定是否存在swap。

(3)防止容器使用交换

  如果--memory 和--memory-swap设置为相同的值,则可以防止容器使用swap。这是因为--memory-swap 可以使用的memory and swap,而--memory只是可以使用的物理内存量。

2.2.2 --memory-swappiness 设置

  • 值为0将关闭匿名页面交换。
  • 值100将所有匿名页面设置为可交换。
  • 默认情况下,如果未设置--memory-swappiness,则值将从主机继承。

2.2.3 --kernel-memory 设置

(1)介绍

内核内存限制以分配给容器的总内存表示。请考虑以下方案:

  • 无限内存,无限内核内存:这是默认设置。
  • 无限内存,有限的内核内存:当所有cgroup所需的内存量大于主机上实际存在的内存量时,这是合适的。您可以将内核内存配置为永远不会覆盖主机上可用的内容,而需要更多内存的容器需要等待它。
  • 有限的内存,无限的内核内存:整体内存有限,但内核内存不受限制。
  • 有限的内存,有限的内核内存:限制用户和内核内存对于调试与内存相关的问题非常有用。如果容器使用意外数量的任一类型的内存,则内存不足而不会影响其他容器或主机。在此设置中,如果内核内存限制低于用户内存限制,则内核内存不足会导致容器遇到OOM错误。如果内核内存限制高于用户内存限制,则内核限制不会导致容器遇到OOM。

当您打开任何内核内存限制时,主机会根据每个进程跟踪“高水位线”统计信息,因此您可以跟踪哪些进程(在本例中为容器)正在使用多余的内存。通过/proc/<PID>/status在主机上查看,可以在每个过程中看到这一点。

3、CPU

  • 默认情况下,每个容器对主机CPU周期的访问权限是不受限制的
  • 您可以设置各种约束来限制给定容器访问主机的CPU周期。
  • 大多数用户使用和配置 默认CFS调度程序。
  • 在Docker 1.13及更高版本中,您还可以配置 实时调度程序。

3.1 配置默认CFS调度程序

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

选项

描述

--cpus=<value>

指定容器可以使用的可用CPU资源量。例如,如果主机有两个CPU并且你已设置--cpus="1.5",则容器最多保证一个半CPU。这相当于设置--cpu-period="100000" 和 --cpu-quota="150000"。可在Docker 1.13及更高版本中使用。

--cpu-period=<value>

指定CPU CFS调度程序周期,它与并用 --cpu-quota。默认为100微秒。大多数用户不会更改默认设置。如果您使用Docker 1.13或更高版本,请--cpus 使用。

--cpu-quota=<value>

对容器施加CPU CFS配额。--cpu-period限制前容器限制为每秒的微秒数。作为有效上限。如果您使用Docker 1.13或更高版本,请--cpus改用。

--cpuset-cpus

限制容器可以使用的特定CPU或核心。如果您有多个CPU,则容器可以使用逗号分隔列表或连字符分隔的CPU范围。第一个CPU编号为0.有效值可能是0-3(使用第一个,第二个,第三个和第四个CPU)或1,3(使用第二个和第四个CPU)。

--cpu-shares

将此标志设置为大于或小于默认值1024的值,以增加或减少容器的重量,并使其可以访问主机的CPU周期的较大或较小比例。仅在CPU周期受限时才会强制执行此操作。当有足够的CPU周期时,所有容器都会根据需要使用尽可能多的CPU。这样,这是一个软限制。--cpu-shares不会阻止容器以群集模式进行调度。它为可用的CPU周期优先考虑容器CPU资源。它不保证或保留任何特定的CPU访问权限。

4、操作演示

4.1 准备工作

(1)先查询宿主机的资源:

root@caicai:~# lscpu     CPU资源
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 1
On-line CPU(s) list: 0
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 85
Model name: Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz
Stepping: 4
CPU MHz: 2499.994
BogoMIPS: 4999.98
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 1024K
L3 cache: 33792K
NUMA node0 CPU(s): 0
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 rep_good nopl tsc_known_freq 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 invpcid_single ibrs ibpb stibp kaiser fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f rdseed adx smap avx512cd xsaveopt xsavec xgetbv1
root@caicai:~# free -h 内存、swap资源
total used free shared buff/cache available
Mem: 2.0G 255M 815M 3.0M 928M 1.5G
Swap: 0B 0B 0B

(2)在dockerhub 下载一个用于压测的镜像

root@caicai:~# docker pull lorel/docker-stress-ng

(3)该压测镜像的使用方法

root@caicai:~# docker run --name stress --rm lorel/docker-stress-ng:latest stress --help

使用--help 可以查询此压测镜像的用法

例:

stress-ng --cpu 8 --io 4 --vm 2 --vm-bytes 128M --fork 4 --timeout 10s

语法:

  • -c N, --cpu N 启动N个子进程(cpu)
  • --vm N 启动N个进程对内存进行压测
  • --vm-bytes 128M 每个子进程使用多少内存(默认256M)

4.2 测试内存限制

(1)现在最大使用内存启动容器

[root@docker ~]# docker run --name stress --rm -m 256m lorel/docker-stress-ng:latest stress --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm [root@docker ~]# docker stats stress
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
e1fdb0520bad stress 8.22% 254MiB / 256MiB 99.22% 648B / 0B 46.9MB / 3.63GB 5

注释:

  • -m 256m 限制此容器最大只能使用256m 内存;
  • --vm 2    启动压测容器,使用256x2=512m的内存;
  • docker stats 结果查询,容器实际使用内存不能超过256m

4.3 测试CPU限制

(1)限制最大使用2核CPU

[root@docker ~]# docker run --name stress --rm --cpus 2 lorel/docker-stress-ng:latest stress --cpu 8
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 8 cpu [root@docker ~]# docker stats stress
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
ca86c0de6431 stress 199.85% 15.81MiB / 7.781GiB 0.20% 648B / 0B 0B / 0B 9

(2)不限制使用CPU核数

[root@docker ~]# docker run --name stress --rm lorel/docker-stress-ng:latest stress --cpu 8
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 8 cpu [root@docker ~]# docker stats stress
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
167afeac7c97 stress 399.44% 15.81MiB / 7.781GiB 0.20% 508B / 0B 0B / 0B 9

 

  作者:along阿龙
  出处:http://www.cnblogs.com/along21/
  简介:每天都在进步,每周都在总结,你的一个点赞,一句留言,就可以让博主开心一笑,充满动力!
  版权:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

Docker系列--Docker设置系统资源限制及验证的更多相关文章

  1. docker 系列 - Docker 安装和Hub Mirror地址设置

    ======================为什么要使用Docker?======================= 容器真是个好东西, (1)容器能提供隔离性; (2)容器能打包环境, 简化部署难度 ...

  2. Docker系列——Docker安装&基础命令

    Docker 概述 Docker 是一个开源的应用容器引擎,Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化. ...

  3. docker 系列 - Docker CheatSheet | Docker 配置与实践清单 (转载)

    本文转载自 (https://segmentfault.com/a/1190000016447161), 感谢作者.

  4. Docker系列一之基础快速入门企业实战

    1.1什么是LXC LXC为Linux Container的简写.Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚 ...

  5. Docker系列一:Docker基本概念及指令介绍

    1. Docker是什么? Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用 ...

  6. Docker系列01—容器的发展历程---Docker的生态圈

    本文收录在容器技术学习系列文章总目录 Docker 和容器技术的发展可谓是日新月异,本文试图以全局的视角来梳理一下 docker 目前的生态圈.既然是概览,所以不会涉及具体的技术细节. Docker ...

  7. Docker系列07—Dockerfile 详解

    本文收录在容器技术学习系列文章总目录 1.认识Dockerfile 1.1 镜像的生成途径 基于容器制作  dockerfile,docker build 基于容器制作镜像,已经在上篇Docker系列 ...

  8. Docker系列10—容器编排工具Docker Compose详解

    本文收录在容器技术学习系列文章总目录 1.Docker Compose 概述 Compose是一个用于定义和运行多容器Docker应用程序的工具.使用Compose,您可以使用Compose文件来配置 ...

  9. Docker深入浅出系列 | Docker Compose多容器实战

    目录 前期准备 Docker Compose是什么 为什么要用Docker Compose Docker Compose使用场景 Docker Compose安装 Compose Yaml文件结构 C ...

  10. Docker系列03—Docker 基础入门

    本文收录在容器技术学习系列文章总目录 1.概念介绍 1.1 容器 1.1.1 介绍 容纳其它物品的工具,可以部分或完全封闭,被用于容纳.储存.运输物品.物体可以被放置在容器中,而容器则可以保护内容物. ...

随机推荐

  1. Chart控件-常用设置

    visual studio中原生控件chart控件使用时的一些常用设置 鼠标缩放功能 缩放后恢复曲线

  2. tool script to convert back slash

    Back slash is used in windows, which makes so many headache for me. Then an idea came to my mind. It ...

  3. iOS基础 - SceneDelegate

    前言 1 - 自从 Xcode11 发布以来,当你使用新 XCode 创建一个新的 iOS 项目时 SceneDelegate 会被默认创建 2 - 在 iOS 13 后 SceneDelegate ...

  4. 建筑CAD中如何标注动态标高?CAD标注动态标高步骤

    在建筑CAD软件中,标高标注用来表示某个点的高程或者垂直高度.浩辰CAD建筑软件中以标高对象来实现CAD标高的标注,标高画法符合国家建筑制图统一标准与总图制图标准的图例,同时也提供了流行的楼层标高画法 ...

  5. https原理(三)双向实践(curl)

    接 https代理服务器(三)实践,实践双向ssl 本文采用客户端与服务端不同密钥对 1 mkcert myclient 生成客户端公钥 私钥 2 mkcert -pkcs12 myclient 也可 ...

  6. dart extends 覆盖规则

    1,不覆写super的变量,child会自动继承super的变量.即使是在child里给super赋值,child里也是可以访问到的,可能是因为引用的关系. 2,只要覆写了super的变量,只给sup ...

  7. windows上Yii2使用workerman整套流程

    1.在根目录下新建Worker目录 进入新建的Worker文件夹 运行 LINUX下运行 composer require workerman/workerman win 下运行 composer r ...

  8. HTML+CSS+JS制作一个灰白色简约时钟

    HTML+CSS+JS制作一个灰白色简约时钟 1. 效果图: 2. 特点:这次借鉴了网络上的代码,利用JS动态创建元素,减少html语句的数量,也便于与vue.react等语言进行结合. 3. 代码实 ...

  9. 使用 DataType 特性应用于 Date 和 Price 属性

    [Display(Name = "Release Date")] [DataType(DataType.Date)] public DateTime ReleaseDate { g ...

  10. iverilog_makefile

    makefile run: iverilog -g2005-sv -I ../inc -s tb -f filelist -o kout sim: vvp kout flist: find ../rt ...