从 Node 确定 Docker for Mac RAM 限制

Determining the Docker for Mac RAM limit from Node

背景

我们为 Mac 使用 Docker。 Docker/Linux 容器无法 运行 在 MacOS/Darwin/Unix 上本地运行,因此在内部 Docker 用于 Mac 运行 是一个 Linux 虚拟机,并且所有容器实际上 运行 都在那上面。

Docker for Mac 有一个 GUI 设置界面,可以让我们指定分配给这个 Linux 虚拟机 (screenshot) 的 RAM。它似乎默认为 2 GB,但我们的开发环境实际最小为 8 GB,否则我们会遇到病态交换,Docker 守护进程可能会变得无响应。

我们的问题是 RAM 限制似乎有时会静默重置为默认值。这似乎发生在自动更新之后,但并不总是如此。我们的团队成员并不总是意识到发生了什么,并且在找到真正原因之前经常浪费时间调查导致性能问题的其他原因。

问题

我们使用 Node 脚本启动大部分本地开发环境。我如何从 Node 检测 Docker 中 Mac 的当前 RAM 限制,以便我们的脚本可以在低于我们预期的最​​小值时向我们的开发人员显示警告消息?

尝试的解决方案

我没有找到任何直接公开此设置的 docker 命令,但是 docker stats 命令报告每个 运行ning 容器的内存使用情况,以及它们各自的 RAM 限制似乎与我为 Docker 设置的总体 Mac 相同。

docker stats --no-stream --format "{{.MemUsage}}"
172MiB / 7.786GiB
175.6MiB / 7.786GiB
171.7MiB / 7.786GiB
1.031MiB / 7.786GiB

我一直在努力解析其中的价值。

const execa = require('execa');

(async () => {
  const result = await execa(
    'docker',
    ['stats', '--no-stream', '--format', '{{.MemUsage}}'],
    {encoding: 'utf8'}
  );
  const stdout = await result.stdout;
  const firstLine = stdout.split(/\n/)[0];
  const limit = firstLine.split(/ \/ /)[1];
  console.log(limit); // 7.786GiB
})();

但是,这有一个主要限制:它仅在当前 运行ning 有容器时才有效。我想用它来警告用户 启动任何容器之前。结果是为人类格式化的,带有潜在可变的单位后缀,这也很不方便。


有什么好的方法可以从 Node 检测 Docker 的 Mac RAM 限制设置吗?

Mac 的 Docker 设置存储在位于 ~/Library/Group Containers/group.com.docker/settings.json 的简单 JSON 文件中。 RAM 限制在 'memoryMiB' 键下指定为整数。我们可以像这样从 Node 读取它:

const fs = require('fs');
const os = require('os');
const path = require('path');

(() => {
  const configPath = path.join(
    os.homedir(),
    "Library/Group Containers/group.com.docker/settings.json"
  );

  const config = JSON.parse(fs.readFileSync(configPath, {
    encoding: 'utf8'
  }));

  if (typeof config.memoryMiB === 'number' && config.memoryMiB < 8000) {
    console.warn(
      `Docker for Mac is configured to use ${config.memoryMiB} MiB of RAM.`);
    console.warn(
      'Consider raising it to 8 GB or you may encounter performance issues.');
  }
})();

“主机的”/proc 文件系统暴露在容器中,因此您可以非常直接地检查:

docker run --rm busybox cat /proc/meminfo \
  | grep MemTotal

您还可以在那里找到 SwapTotal 设置。这些在技术上是 Linux 内核值,但它们反映了 Docker 中用于 Mac 控件的 VM 设置。