Docker的系统资源限制及验证

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

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

[[email protected] ~]# docker info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 43
Server Version: 17.03.2-ce
Storage Driver: overlay
Backing Filesystem: xfs
Supports d_type: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 4ab9917febca54791c5f071a9d1f404867857fcc
runc version: 54296cf40ad8143b62dbcaa1d90e520a2136ddfe
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-514.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 976.5 MiB
Name: along
ID: KGWA:GDGT:PTK7:PAX4:A3JZ:LV6N:U5QD:UQCY:AGZV:P32E:V73T:JJHR
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: alongedu
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
docker2:80
127.0.0.0/8
Registry Mirrors:
https://registry.docker-cn.com
Live Restore Enabled: false
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?)先查询宿主机的资源:

[[email protected] ~]# lscpu CPU资源
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 4
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 60
Model name: Intel(R) Xeon(R) CPU E3-1231 v3 @ 3.40GHz
Stepping: 3
CPU MHz: 3395.854
BogoMIPS: 6792.17
Hypervisor vendor: VMware
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 8192K
NUMA node0 CPU(s): 0-3
[[email protected] ~]# free -h 内存、swap资源
total used free shared buff/cache available
Mem: 7.8G 193M 7.2G 8.6M 438M 7.3G
Swap: 2.0G 400K 2.0G

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

[[email protected] ~]# docker pull lorel/docker-stress-ng

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

[[email protected] ~]# 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?)现在最大使用内存启动容器

[[email protected] ~]# 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

[[email protected] ~]# 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

[[email protected] ~]# 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

[[email protected] ~]# 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?核数

[[email protected] ~]# 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

[[email protected] ~]# 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
欢迎欢迎学Java的朋友们加入java架构交流: 855835163
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

原文地址:http://blog.51cto.com/14158311/2343676

时间: 2024-11-14 12:01:15

Docker的系统资源限制及验证的相关文章

LinuxMint下Docker的安装部署和验证

通过lsb_release命令查看以下我的LinuxMint发行版, 查看以下我的Linux内核版本, Docker要求Linux内核版本必须在要在3.10以上,显然我们的系统是满足的. 1. Docker安装 操作系统默认的apt源有docker包,我们可以直接使用下面的apt-get命令安装docker, $ sudo apt-get install -y docker.io 不过其安装的版本比较老.我们采用下面两种方式进行安装,个人比较推荐第二种,第二种方式安装的是最新的. 1.1 从Do

利用内核cgroup机制轻松实现类似docker的系统资源管控

近几年,以docker为代表的容器技术异常火热,它的轻量.高效让人欣喜若狂,它被赋予了改变传统IT运维的使命.相信随着时间推移,以容器云为落地形式的产品将真正实现这一使命. 我们都知道docker能够实现资源的隔离和控制,正当打算引入docker来管理产品不同业务的资源占用时,发现它的隔离性是我们所不需要的,而我们都知道,docker底层实际上是利用了linux内核提供的namespace和cgroup机制,而前者是用于资源隔离的,后者是用于资源控制的.这时,我们想到了直接用cgroup来实现.

docker技术剖析--镜像、容器管理

防伪码:博观而约取,厚积而薄发                                 docker技术剖析--镜像.容器管理 一.Docker简介 Docker是什么? Docker的英文本意是"搬运工",在程序员的世界里,Docker搬运的是集装箱(Container),集装箱里装的是任意类型的App,开发者通过Docker可以将App变成一种标准化的.可移植的.自管理的组件,可以在任何主流系统中开发.调试和运行. 说白了,docker是一种用了新颖方式实现的轻量级虚拟机,

docker讲解和命令汇总

docker 什么是docker? Docker是Docker.inc公司开源的一个基于LXC技术之上构建的Container容器引擎,源代码托管在GitHub上,基于Go语言并遵从Apache2.0协议开源(可以商业). Docker项目的目标是实现轻量级的操作系统虚拟化解决方案. Docker是通过内核虚拟化技术(namespaces及cgroups等)来提供容器的资源隔离与安全保障等.由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机VM额外的操

docker基本介绍与安装

一.Docker简介 Docker是什么? Docker的英文本意是"搬运工",在程序员的世界里,Docker搬运的是集装箱(Container),集装箱里装的是任意类型的App,开发者通过Docker可以将App变成一种标准化的.可移植的.自管理的组件,可以在任何主流系统中开发.调试和运行. 说白了,docker是一种用了新颖方式实现的轻量级虚拟机,类似于VM,但是在原理和应用上和VM的差别还是很大的.并且docker的专业叫法是应用容器(Application Container)

Docker 上如何开发 nodejs?

Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目.它基于 Google 公司推出的 Go 语言实现. 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub上进行维护. Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案. Docker 的基础是 Linux 容器(LXC)等技术. 在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便.用户操

Docker实践(一)

Docker实践 什么是LXC? LXC为Linux Container的简写.Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性.相当于C++中的NameSpace.容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求.与传统虚拟化技术相比,它的优势在于: 与宿主机使用同一个内核,性能损耗小: 不需要指令级模拟: 不需要即时(Just-in-tim

k8s docker集群搭建

?Kubernetes介绍 1.背景介绍 云计算飞速发展 - IaaS - PaaS - SaaS Docker技术突飞猛进 - 一次构建,到处运行 - 容器的快速轻量 - 完整的生态环境 2.什么是kubernetes 首先,他是一个全新的基于容器技术的分布式架构领先方案.Kubernetes(k8s)是Google开源的容器集群管理系统(谷歌内部:Borg).在Docker技术的基础上,为容器化的应用提供部署运行.资源调度.服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性

隔离 docker 容器中的用户

笔者在前文<理解 docker 容器中的 uid 和 gid>介绍了 docker 容器中的用户与宿主机上用户的关系,得出的结论是:docker 默认没有隔离宿主机用户和容器中的用户.如果你已经了解了 Linux 的 user namespace 技术(参考<Linux Namespace : User>),那么自然会问:docker 为什么不利用 Linux user namespace 实现用户的隔离呢?事实上,docker 已经实现了相关的功能,只是默认没有启用而已.笔者将在