Docker Container Resource Limit

默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的尽可能多的给定资源。

Memory

内存风险

不允许容器消耗宿主机太多的内存是非常重要的。在 Linux 主机上,如果内核检测到没有足够的内存来执行重要的系统功能,它会抛出 OOMEOut of Memory 异常,并开始终止进程​​以释放内存。任何进程都会被杀死,包括 Docker 和其他重要的应用程序。如果杀错进程,可能导致整个系统瘫痪。

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

有关Linux内核的OOM管理的更多信息,查看 Out of Memory Management

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

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

限制容器内存

下述选项中的大多数采用正整数,后跟 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 killer,如果未设置 -m 标志,则主机可能会耗尽内存,内核可能需要终止主机系统的进程才能释放内存

有关 cgroup 和内存的更多信息,查看 Memory Resource Controller

关于 --memory-swap

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

它的设置会产生复杂的影响:

  • 如果 --memory-swap 设置为正整数,则必须设置 --memory--memory-swap--memory-swap 表示可以使用的 memory 和 swap 总量, --memory 控制 no-swap 的用量。 所以,如果设置 --memory="300m"--memory-swap="1g", 容器可以使用 300m memory 和 700m (1g - 300m) swap。
  • 如果 --memory-swap 设置为 0, 该设置被忽略,该值被视为未设置。
  • 如果 --memory-swap 的值等于 --memory 的值, 并且 --memory 设置为正整数, 则容器无权访问 swap。这是因为 --memory-swap 是可以使用组合的 Memory 和 Swap,而 --memory 只是可以使用的 Memory。
  • 如果 --memory-swap 不设置, 并且 --memory 设置了值, 容器可以使用 --memory 两倍的 Swap(如果主机容器配置了 Swap)。示例: 设置 --memory="300m" 并且不设置 --memory-swap,容器可以使用 300m memory 和 600m swap。
  • 如果 --memory-swap 设置为 -1,允许容器无限制使用 Swap。
  • 在容器内部,像 free 等工具报告的是主机的可用 Swap,而不是容器内可用的。不要依赖于 free 或类似工具的输出来确定是否存在 Swap。

关于 --memory-swappiness

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

关于 --kernel-memory

内核内存限制是就分配给容器的总内存而言的,考虑一下方案:

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

当你打开任何内核内存限制时,主机会根据每个进程跟踪 “高水位线” 统计信息,因此您可以跟踪哪些进程(在本例中为容器)正在使用多余的内存。通过查看主机上的 /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",则容器最多可以使用 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 访问权限。

示例:如果你有 1 个 CPU,则以下每个命令都会保证容器每秒最多占 CPU 的 50%。

Docker 1.13 或更高版本:

docker run -it --cpus=".5" ubuntu /bin/bash

Docker 1.12 或更低版本:

docker run -it --cpu-period=100000 --cpu-quota=50000 ubuntu /bin/bash

配置实时调度程序

In Docker 1.13 and higher, you can configure your container to use the realtime scheduler,

在 Docker 1.13 或更高版本,你可以配置容器使用实时调度程序。在配置 Docker daemon 或配置容器之前,需要确保正确配置主机的内核。

警告:CPU 调度和优先级是高级内核级功能,大多数用户不需要从默认值更改这些值,错误地设置这些值可能会导致主机系统变得不稳定或无法使用。

配置主机机器的内核

通过运行 zcat /proc/config.gz | grep CONFIG_RT_GROUP_SCHED 验证是否在 Linux 内核中启用了 CONFIG_RT_GROUP_SCHED,或者检查是否存在文件 /sys/fs/cgroup/cpu.rt_runtime_us。有关配置内核实时调度程序的教程,请参阅操作系统的文档。

配置DOCKER DAEMON

要使用实时调度程序运行容器,请运行 Docker daemon,并将 --cpu-rt-runtime 设置为每个运行时间段为实时任务保留的最大微秒数。例如,默认周期为 1000000 微秒(1秒),设置 --cpu-rt-runtime=950000 可确保使用实时调度程序的容器每 1000000 微秒可运行 950000 微秒,并保留至少 50000 微秒用于非实时任务。要在使用 systemd 的系统上永久保留此配置,请参阅 Control and configure Docker with systemd

配置个别容器

使用 docker run 启动容器时,可以传递多个参数来控制容器的 CPU 优先级。有关适当值的信息,请参阅操作系统的文档或 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 标志。

示例:

docker run --it --cpu-rt-runtime=950000 \
                  --ulimit rtprio=99 \
                  --cap-add=sys_nice \
                  debian:jessie

如果未正确配置内核或 Docker Daemon,则会发生错误。

相关文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356

推荐阅读更多精彩内容

  • Docker容器技术已经发展了好些年,在很多项目都有应用,线上运行也很稳定。整理了部分Docker的学习笔记以及新...
    __七把刀__阅读 11,452评论 0 58
  • 想要改进这个备忘单吗?参见[贡献](#贡献)部分! 目录 [为何选择Docker](#why-docker) [先...
    iOSDevLog阅读 2,099评论 0 3
  • 初秋微凉的黄昏,当我再次路过新街口地下通道,经过那个熟悉的走廊,已看不到那个卖唱的帅小伙的身影。 想起,春末初夏时...
    卓妍阅读 564评论 1 8