默认情况下,容器没有资源约束,并且可以使用主机内核调度器允许的给定资源的多少。Docker提供了控制容器可以使用多少内存、CPU或块IO的方法,并设置docker run
命令。本节详细介绍了何时设置这些限制以及设置这些限制可能带来的影响。
记忆
了解内存不足的风险
重要的是不要让正在运行的容器占用主机的太多内存。在linux主机上,如果内核检测到没有足够的内存来执行重要的系统功能,则会抛出OOME
,或Out Of Memory Exception
,并开始销毁进程以释放内存。任何程序都可能被杀死,包括Docker和其他重要的应用程序。如果错误的过程被扼杀,这将有效地降低整个系统。
Docker试图通过调整Docker守护进程上的OOM优先级来降低这些风险,这样它就不会比系统上的其他进程被杀死的可能性更小。不调整容器的OOM优先级。这使得单个容器更有可能被杀死,而不是Docker守护进程或其他系统进程被杀死。您不应该试图通过手动设置来规避这些安全措施。--oom-score-adj
在守护进程或容器上,或通过设置--oom-disable-kill
在集装箱上。
有关Linux内核的OOM管理的更多信息,请参阅内存不足管理。
您可以通过以下方法减少由于OOME而导致的系统不稳定风险:
-
在将应用程序投入生产之前,执行测试以了解应用程序的内存需求。
-
确保您的应用程序仅在资源充足的主机上运行。
-
限制容器可以使用的内存量,如下所述。
-
在您的Docker主机上配置交换时要注意。交换比内存慢,性能差,但可以提供缓冲,防止系统内存不足。
-
考虑将容器转换为服务,并使用服务级约束和节点标签确保应用程序仅在内存充足的主机上运行。
限制容器对内存的访问
Docker可以强制执行硬内存限制,这允许容器使用不超过给定数量的用户或系统内存,或者软限制,允许容器使用它所需要的内存,除非满足某些条件。例如,当内核检测到主机上的低内存或争用时。当单独使用或设置多个选项时,这些选项中的一些具有不同的效果。
大部分的选项取正整数,跟着一个后缀b
,k
,m
,g
,,表示字节,千字节,兆字节或千兆字节。
选项 |
描述 |
---|---|
-m or --memory= |
容器可以使用的最大内存量。如果您设置此选项,则允许的最小值为4米(4兆字节)。 |
--memory-swap* |
此容器允许交换到磁盘的内存量。请参阅--memory-swap详细信息。 |
--memory-swappiness |
默认情况下,主机内核可以交换容器使用的匿名页面的百分比。您可以将--memory-swappiness设置为介于0和100之间的值,以调整此百分比。请参阅--memory-swappiness详细信息。 |
--memory-reservation |
允许您指定一个小于--memory的软限制,当Docker检测到主机上的争用或内存不足时,该内存会被激活。如果使用--memory-reservation,它必须设置为低于--memory才能优先。由于这是一个软限制,它不能保证容器不会超出限制。 |
--kernel-memory |
容器可以使用的最大内核内存量。允许的最小值是4米。由于内核内存不能被换出,因此内核内存不足的容器可能会阻塞主机资源,这会对主机和其他容器产生副作用。请参阅 - 内核内存细节。 |
--oom-kill-disable |
默认情况下,如果发生内存不足(OOM)错误,内核会杀死容器中的进程。要更改此行为,请使用--oom-kill-disable选项。只有在您还设置了-m / - memory选项的容器上禁用OOM杀手。如果未设置-m标志,主机可能会耗尽内存,内核可能需要终止主机系统的进程以释放内存。 |
有关cgroup和内存的详细信息,请参阅内存资源控制器...
--memory-swap
细节
--memory-swap
是一个修饰符标志,它只有在以下情况下才有意义:--memory
也设置好了。当容器耗尽了可用的所有RAM时,使用交换空间允许容器将多余的内存需求写入磁盘。对于经常将内存交换到磁盘的应用程序,存在性能损失。
它的设置可能会产生复杂的影响:
-
如果
--memory-swap
设置为正整数,则两者均为--memory
和--memory-swap
必须设置好。--memory-swap
表示可以使用的内存和交换空间的总量,以及--memory
控制非交换内存使用的数量。所以如果--memory="300m"
和--memory-swap="1g"
,该容器可使用300 m内存和700 m%28。1g - 300m
%29掉期
-
如果
--memory-swap
设置为0
,则忽略该设置,并将该值视为未设置。
-
如果
--memory-swap
设置为与--memory
,和--memory
被设置为正整数,容器将无法访问交换。.见防止容器使用交换...
-
如果
--memory-swap
是未设置的,而且--memory
设置后,容器可以使用的交换空间是--memory
设置,如果主机容器已配置了交换内存。例如,如果--memory="300m"
和--memory-swap
如果没有设置,容器可以使用300米内存和600米交换。
-
如果
--memory-swap
显式设置为-1
,容器可以使用无限交换,最多可在主机系统上使用。防止容器使用交换如果--memory
和--memory-swap
设置为相同的值,这将防止容器使用任何交换。这是因为--memory-swap
是可以使用的组合内存和交换空间的数量,而--memory
仅为可使用的物理内存量。--memory-swappiness
细节
-
值0关闭匿名页交换。
-
值100将所有匿名页面设置为可交换。
-
默认情况下,如果不设置
--memory-swappiness
,则从主机继承该值。
--kernel-memory
细节
内核内存限制以分配给容器的总体内存表示。考虑以下情况:
-
无限内存,无限内核内存这是默认行为。
-
无限内存,有限内核内存当所有cgroup所需的内存量大于主机上实际存在的内存量时,这是适当的。您可以将内核内存配置为永远不要检查主机上可用的内容,需要更多内存的容器需要等待。
-
有限内存,无限制内核内存:总体内存是有限的,但是内核内存不是。
-
有限内存,有限内核内存限制用户和内核内存对于调试与内存相关的问题非常有用。如果容器使用的内存类型都是意外的,那么它将耗尽内存,而不会影响其他容器或主机。在此设置中,如果内核内存限制低于用户内存限制,内核内存不足将导致容器遇到OOM错误。如果内核内存限制高于用户内存限制,内核限制将不会导致容器体验OOM。
当您打开任何内核内存限制时,主机会在每个进程的基础上跟踪“高水标记”统计数据,这样您就可以跟踪哪个进程%28--在这种情况下,容器%29使用的是多余内存。这可以通过查看每个进程来查看。/proc/<PID>/status
在主机上。
cpu
默认情况下,每个容器对主机CPU周期的访问是无限的。您可以设置各种约束来限制给定容器对主机CPU周期的访问。大多数用户将使用和配置默认CFS调度程序.在Docker 1.13及更高版本中,还可以配置实时调度器...
配置默认的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一起使用。默认为1秒,以微秒表示。大多数用户不会从默认值更改此设置。如果您使用Docker 1.13或更高版本,请改用--cpus。 |
--cpu-quota=<value> |
在容器上添加CPU CFS配额。每个--cpu-period允许CPU访问的容器数微秒数。换句话说,cpu-quota / 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访问权限。 |
如果您有一个CPU,下面的每条命令将保证容器最多每秒占CPU的50%。
码头1.13及以上*
docker run -it --cpus=".5" ubuntu /bin/bash
码头1.12及以下*
$ docker run -it --cpu-period=100000 --cpu-quota=50000 ubuntu /bin/bash
配置实时调度程序
在Docker 1.13及更高版本中,可以将容器配置为使用实时调度程序,以处理无法使用cfs调度程序的任务。你需要确保主机的内核配置正确在你可以之前配置Docker守护进程或配置单个容器...
警告CPU调度和优先级是高级内核级特性.。大多数用户不需要从默认值中更改这些值。不正确地设置这些值会导致主机系统变得不稳定或无法使用。
配置主机的内核
核实CONFIG_RT_GROUP_SCHED
在linux内核中通过运行zcat /proc/config.gz | grep CONFIG_RT_GROUP_SCHED
或者通过检查文件的存在/sys/fs/cgroup/cpu.rt_runtime_us
有关配置内核实时调度程序的指导,请参阅操作系统的文档。
配置Docker守护进程
若要使用实时调度程序运行容器,请使用--cpu-rt-runtime
标志设置为每个运行时期间为实时任务保留的最大微秒数。例如,默认周期为10000微秒%281秒%29,设置--cpu-rt-runtime=95000
确保使用实时调度程序的容器每10000微秒可以运行95000微秒,为非实时任务留出至少5000微秒。使此配置在使用systemd
,见用system d控制和配置Docker...
配置单个容器
在启动容器时,可以传递几个标志来控制容器的CPU优先级。docker run
查阅您的操作系统文档或ulimit
命令获取有关适当值的信息。
选项 |
描述 |
---|---|
--cap-add=sys_nice |
授予容器CAP_SYS_NICE功能,允许容器提升进程的良好值,设置实时调度策略,设置CPU关联和其他操作。 |
--cpu-rt-runtime=<value> |
容器可以在Docker守护进程的实时调度程序期间以实时优先级运行的最大微秒数。您还需要--cap-add = sys_nice标志。 |
--ulimit rtprio=<value> |
容器允许的最大实时优先级。您还需要--cap-add = sys_nice标志。 |
下面的示例命令设置debian:jessie
集装箱。
$ docker run --it --cpu-rt-runtime=95000 \ --ulimit rtprio=99 \ --cap-add=sys_nice \ debian:jessie
如果内核或Docker守护进程配置不正确,就会发生错误。