将 Docker-Desktop 用于 Windows,如何配置 sysctl 参数以渗透重启?

Using Docker-Desktop for Windows, how can sysctl parameters be configured to permeate a reboot?

运行 elasticsearch in win10 [wsl2] docker-desktop 需要通过 sysctl -w vm.max_map_count=262144

将 mmap 计数增加到 262144
C:\Users\<username>>wsl -d docker-desktop
<hostname>:/tmp/docker-desktop-root/mnt/host/c/Users/<username># sysctl -w vm.max_map_count=262144

and elastic's doc中建议相应地更新/etc/sysctl.conf中的vm.max_map_count以将此值设置为永久值,即。 e.使其在重启后仍然存在。

请注意下面的输出,显示有效 mmap 计数不适应 sysctl.conf 中定义的值,在我尝试遵循此建议并重新启动后。

为什么没有?

PS C:\Users\<username>> wsl -d docker-desktop
<hostname>:/tmp/docker-desktop-root/mnt/host/c/Users/<username># sysctl vm.max_map_count
vm.max_map_count = 65530
<hostname>:/tmp/docker-desktop-root/mnt/host/c/Users/<username># cd /etc
<hostname>:/etc# cat sysctl.conf
# content of this file will override /etc/sysctl.d/*
vm.max_map_count=262144

考虑到 etc/ 中改错了 sysctl.conf 我试着改 <hostname>:/tmp/docker-desktop-root/etc# 中的 sysctl.conf。 这是不允许的,因为这是 Read-only file system.

Can/should 这将在 .wslconfig 中参数化,如果是,如何?

使用 openSUSE Leap 15.2 而不是 Win10 的 PowerShell 并没有改变结果。

<username@hostname>:~> sysctl vm.max_map_count
vm.max_map_count = 65530
<username@hostname>:~> cat /etc/sysctl.conf
####
#
# /etc/sysctl.conf is meant for local sysctl settings
#
# sysctl reads settings from the following locations:
#   /boot/sysctl.conf-<kernelversion>
#   /lib/sysctl.d/*.conf
#   /usr/lib/sysctl.d/*.conf
#   /usr/local/lib/sysctl.d/*.conf
#   /etc/sysctl.d/*.conf
#   /run/sysctl.d/*.conf
#   /etc/sysctl.conf
#
# To disable or override a distribution provided file just place a
# file with the same name in /etc/sysctl.d/
#
# See sysctl.conf(5), sysctl.d(5) and sysctl(8) for more information
#
####
vm.max_map_count=262144

值得注意的是,上述 sysctl.conf 文件中的 header 指的是 /boot/sysctl.conf-<kernelversion>。考虑到,mmap计数可能需要在这个文件中定义,以便在启动时考虑,我试图在那里设置所需的参数,但没有权限这样做。

<username@hostname>:/boot> sudo echo 'vm.max_map_count=262144' >> sysctl.conf-5.10.16.3-microsoft-standard-WSL2
-bash: sysctl.conf-5.10.16.3-microsoft-standard-WSL2: Permission denied

openSUSE:WSL - openSUSE Wiki 中报告的已知问题和限制之一是

A system in WSL does not actually boot and does not use systemd. A proprietary Microsoft /init binary initializes the system. Therefore service management does not work like in a VM. It rather behaves like an interactive container.

任何人都可以验证这是参数化 sysctl.conf 不能有效实现当前目的的原因吗?

系统

主持人
OS:微软 Windows 10 家企业
版本:10.0.18363 内部版本 18363 \

Docker
客户:
版本:20.10.8
API 版本:1.41
去版本:go1.16.6
Git 提交:3967b7d
建成时间:7 月 30 日星期五 19:54:02 2021 年
OS/Arch: linux/amd64
插件:
撰写:Docker 撰写(Docker Inc.,v2.0.0-rc.2)
扫描:Docker 扫描(Docker Inc.,v0.8.0)

服务器:
引擎:
版本:20.10.8
API版本:1.41(最低版本1.12)
去版本:go1.16.6
Git 提交:75249d8
建成时间:7 月 30 日星期五 19:52:10 2021 年
OS/Arch: linux/amd64
集装箱:
版本:1.4.9
Git提交:e25210fe30a0a703442421b0f60afac609f950a3
runc:
版本:1.0.1
Git提交:v1.0.1-0-g4144b63
docker-init:
版本:0.19.0
Git提交:de40ad0 \

内核版本:5.10.16.3-microsoft-standard-WSL2
操作系统:Docker 桌面
OS类型:linux
架构:x86_64
CPU:4
总内存:12.39GiB
姓名:docker-desktop

简答:

在您的 Windows %userprofile% 目录(通常是 C:\Users\<username>)中,使用以下内容创建或编辑文件 .wslconfig

[wsl2]
kernelCommandLine = "sysctl.vm.max_map_count=262144"

然后退出任何 WSL 实例,wsl --shutdown,然后重新启动。

> sysctl vm.max_map_count
vm.max_map_count = 262144

更多详情:

您确实有三个(密切相关的)问题:

  • (主要)如何最好地坚持这个设置
  • 可以通过.wslconfig完成吗?

    Can/should this be parameterized in .wslconfig instead, if so, how?

  • 为什么 /etc/sysctl.conf 不努力坚持下去?

    /etc/sysctl.conf to set this value permanent, i. e. making it survive the reboot .... Why didn't it?

我们将结合前两个,因为答案是“是的,你可以通过 .wslconfig.

这不容易找到,因为更改是最近发生的。礼貌 this answer.

从内核版本 5.8 开始,您可以使用值的 sysctl.* 前缀在内核命令行上设置 sysctl 值。

因此,只要您升级了 WSL 内核(自从 wsl --update 最近才在 21H1 发布以来,我的两个系统上 没有 ),您可以像上面那样设置你的%userprofile%\.wslconfig


/etc/sysctl.conf

/etc/sysctl.conf to set this value permanent, i. e. making it survive the reboot .... Why didn't it?

这部分内容比真正需要的要多得多,因为我首先沿着这条兔子小径走下去并将其作为原始答案发布。但首先,“为什么”它不起作用...

这是 WSL2 的 known issue

虽然 sysctl 和 Systemd/systemctl 是两个完全不同的东西,但在那一期中,(微软 WSL 团队的)therealkenc 指出 something必须阅读和处理 /etc/sysctl.conf。在大多数 Linux 发行版中,这是 Systemd 或 SysVInit 脚本。

另一方面,WSL 使用它自己的 /init 代替 SysVInit 或 Systemd。正如您在 openSUSE 文档中所见,WSL init 进程(目前)没有在启动时 运行ning 服务的机制。所以...启动时没有任何内容读取和作用于 /etc/sysctl.conf


这个答案的其余部分包括一些不需要的 systcl.conf 变通办法,因为我们可以用 .wslconfig 做到这一点。这是为了以防万一有人出于某种原因发现它有用。

对此有一些解决方法。所有这些都将涉及找到一种自动 运行 sysctl -w vm.max_map_count=262144 (作为 root)的方法:

  • 首先,在Windows11中,WSL有一个新功能来简化这个。只需 create/edit /etc/wsl.conf(通过 sudo)与:

    [boot]
    command="sysctl -w vm.max_map_count=262144"
    

    每次 WSL 实例启动时,这将 运行 在根目录下。据我所知,这也适用于 docker-desktop 实例,但我无法对其进行测试。

    重要说明:请在尝试之前使用wsl --export备份您的 WSL 实例,或者至少备份您的 Docker 卷、图像和容器这个变化。根据我的经验,可以通过停滞的启动命令完全阻止实例启动,而我(还)没有找到任何恢复机制。幸运的是,我在一个新安装的测试实例中工作,所以我能够 wsl --unregister 它(完全破坏它)除了几分钟之外没有任何损失。


对于我们中许多将在 Windows 10 待一段时间的人来说,有几种选择。不幸的是,我无法针对 Docker 测试这些,但我过去曾在其他 WSL 实例中使用过类似的技术:

  • 如果 Docker 桌面在您登录时设置为 运行,那么您可以将计划任务(通过 Windows 任务计划程序)添加到 运行 在登录时。这将是:

    • “基本任务”
    • “程序”设置为 wsl.exe
    • 并将参数设置为 -d docker-desktop sh -c "sysctl -w vm.max_map_count=262144"

    请注意,如果 docker-desktop WSL 实例在任何时候终止,那么更改将丢失,直到下次重新启动。但是,因为 Docker 桌面 运行 宁在 boot/login,实例 应该 跟上这个变化。


  • 这可能适合也可能不适合,具体取决于您的工作流程。如果您使用单独的 WSL 实例(例如 Ubuntu)用于开发目的,您可以让 that 实例在启动时修改 docker-desktop 实例。

    这样您就不必在每次启动时都输入 sudo 密码, 在您的 .bashrc(或等效项)中使用以下行:

    wsl.exe -d docker-desktop sh -c "sysctl -w vm.max_map_count=262144"
    

最后一个建议 -- 向 Docker 桌面团队提交功能请求。恕我直言,Docker Desktop 的启动过程最容易读取 /etc/sysctl.conf 并进行相应处理。