“sudo systemctl enable docker”不可用:在 WSL2 上启动时自动运行 Docker(使用“sysvinit”/“init”命令或解决方法)

que*_*o42 28 service systemd docker systemctl wsl-2

我在 WSL2 上使用 Ubuntu(不是在 Docker 桌面上)。

\n

根据如何修复 docker \xe2\x80\x98Cannot connect to the Docker daemon at unix:///var/run/docker.sock。Ubuntu 上的 docker 守护进程是否正在运行?\xe2\x80\x99,我可以在启动时自动启动 docker 守护进程

\n
sudo systemctl enable docker\n
Run Code Online (Sandbox Code Playgroud)\n

而不是在每次启动时重新启动它

\n
sudo systemctl start docker\n
Run Code Online (Sandbox Code Playgroud)\n

这两个命令都避免了“无法连接到位于 unix:///var/run/docker.sock 的 Docker 守护进程。docker 守护进程正在运行吗?”。

\n

当使用两者中的任何一个时,我得到

\n
\n

使用 \n/lib/systemd/systemd-sysv-install 将 docker.service 的状态与 SysV 服务脚本同步。执行:\n/lib/systemd/systemd-sysv-install 启用 docker

\n
\n

测试运行显示,docker 尚未运行:

\n
\n
docker run hello-world \n
Run Code Online (Sandbox Code Playgroud)\n

docker:无法连接到 \nunix:///var/run/docker.sock 处的 Docker 守护程序。docker 守护进程是否正在运行?请参阅\n\'docker run --help\'。

\n
\n

之前的一些步骤,此时我也收到了不同的消息:

\n
\n

系统尚未使用 systemd 作为 init 系统 (PID 1) 进行引导。无法操作。无法连接到总线:主机已关闭”

\n
\n

这让我修复“系统尚未使用 systemd 作为 init 系统启动”错误

\n
\n

原因:您的 Linux 系统没有使用 systemd\n如何知道您正在使用哪个 init 系统?您可以使用此命令来了解与 PID 1 关联的进程名称(系统上运行的第一个进程):

\n
ps -p 1 -o comm=\n
Run Code Online (Sandbox Code Playgroud)\n

它应该在输出中显示 systemd 或 sysv (或类似的东西)。

\n
\n

ps -p 1 -o comm=给我init

\n

根据这个和这个表

\n

在此输入图像描述

\n
Systemd command\n    Sysvinit command\n\nsystemctl start service_name\n    service service_name start\n\nsystemctl stop service_name\n    service service_name stop\n\nsystemctl restart service_name\n    service service_name restart\n\nsystemctl status service_name\n    service service_name status\n\nsystemctl enable service_name\n    chkconfig service_name on\n\nsystemctl disable service_name\n    chkconfig service_name off\n
Run Code Online (Sandbox Code Playgroud)\n

我可以选择service docker start运行 docker,它可以工作。但我找不到像sudo systemctl enable docker“sysvinit”的“systemd”之类的东西。我希望它是这样的:

\n
sudo service docker enable\n
Run Code Online (Sandbox Code Playgroud)\n

但该“enable”不适用于“sysvinit”/“init”。

\n

虽然sudo service docker start工作原理与 类似sudo systemctl start docker,但没有这样的命令使用“enable”。目前,sudo service docker start每当启动 WSL2 时我都需要运行。

\n

问题:

\n

sudo systemctl enable docker到达using的命令是什么sudo service docker ...,或者如果不存在,那么在 WSL2 上打开 Ubuntu 时自动启动 docker 的解决方法是什么?

\n

Not*_*1ds 57


重要提示:大多数用户应该首先阅读我更新的答案。这个答案有点过时,但我将其留在这里,以防它对在较旧的 WSL 版本上运行的任何人都有好处。


简短回答“在 WSL2 上打开 Ubuntu 时自动启动 docker 的解决方法是什么?

  • 选项 1: 在 Windows 11 上,将必要的命令添加到[boot]以下部分/etc/wsl.conf

    [boot]
    command="service docker start"
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,在最新的预览版中,似乎存在一个问题boot.command,当通过实际命令行启动的服务都没有仍在运行时,会导致通过此启动的任何内容终止。换句话说,如果您需要 Docker(或任何其他服务)在退出 WSL2 会话后继续运行,您可能需要使用选项 2(或卸载预览版)。

  • 选项 2:在 Windows 10 上,在用户启动脚本中运行必要的命令(例如.profile)。首先检查服务是否正在运行,例如:

    wsl.exe -u root -e sh -c "service docker status || service docker start"
    
    Run Code Online (Sandbox Code Playgroud)

    这是比我之前的答案(下面的选项 3)更好的选择,因为它不需要修改sudoers. 这利用了以下事实:该wsl.exe命令可以从 WSL 内部运行,使用-u root选项以 root 身份运行命令而无需密码。

    注意:如果由于某种原因此命令失败,您的默认 WSL 分发可能与您预期的不同。检查 的输出wsl.exe -l -v。您可以使用更改默认发行版wsl.exe --setdefault <distro_name>或调整上面的命令行以指定带有-d <distro_name>.

  • 选项 3:(旧答案,供后代使用):visudo或添加规则/etc/sudoers.d以允许您的用户无需密码即可运行命令:

    username ALL = (root) NOPASSWD: /usr/sbin/service docker *
    
    Run Code Online (Sandbox Code Playgroud)

    然后编辑您的.profile添加:

    sudo service docker status || sudo service docker start
    
    Run Code Online (Sandbox Code Playgroud)

更多细节:

正如您所发现的,WSL 不包含任何 systemd 支持,也不包含对启动时启动服务的任何直接支持。

对于初学者来说,WSL 子系统不会在 Windows 启动时启动,而是仅在用户启动登录会话时启动。因此,如果没有任何真正的“系统启动”,init.d 或 systemd 启动就没有多大意义。

此外,用户可能运行多个 WSL 实例/发行版,如果您这样做(就像我一样),那么您确实不希望每次启动时都运行所有实例的所有服务(尽管更新的答案,Windows 11 现在确实如此)给我们这个选项)。

不过,对于 Docker,您是运行带有 WSL2 集成的 Docker Desktop,还是直接安装到 WSL2 实例中?对于 Docker Desktop,我昨天在另一个关于如何在 Windows 启动时启动 Docker Desktop 守护进程的问题中遇到了这个问题。

您还可以在用户登录时通过 Windows 任务管理器启动 WSL2 实例,并通过wsl -u root service docker start任务管理器中的类似方式运行脚本。

请注意,同样的操作似乎在 Windows boot中不起作用(仅登录),因为 Windows 似乎会在几秒钟后终止任何未与活动用户绑定的 WSL 实例(即使服务正在运行)背景)。您可以使用 PowerShell 解决此问题Invoke-WmiMethod,例如......

powershell.exe Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList 'wsl',尽管我还没有彻底测试过这一点。

  • 为我工作添加 `sudo service docker status || sudo service docker start` 到我的 WSL2 Linux 驱动器上的 ~/.profile。之后,“sudo docker run hello-world”运行。你是对的,docker 不会自动启动似乎是合乎逻辑的,因为你并不总是需要它;)。至于你的问题,我运行直接安装到 WSL2 实例中的 Docker。 (3认同)

Not*_*1ds 6


此答案需要在发布本文时使用最新版本的 Windows 和 WSL,现在它可以在 Windows 10 和 11 下运行。运行wsl --version并确认您使用的是 WSL 1.0.0(不要与 WSL1 混淆)或更高版本。

如果您使用的是旧版本的 Windows 或 WSL,则wsl --version可能只显示帮助文本。有关如何升级的信息,请参阅此答案。

如果您此时无法升级,请参阅我的原始答案以获取适用于 Windows 10 的解决方法。


在 WSL2 上打开 Ubuntu 时自动启动 docker 的解决方法是什么?

  • 选项 1:在 WSL2 中启用 Systemd 支持

    最新版本的 WSL2 包括对 Systemd 的支持。您可以在此社区 Wiki 答案我原来的 Ask Ubuntu 答案中阅读如何启用它。

    不过,我个人的建议是考虑一下你是否真的需要 Systemd。它会增加额外的开销和潜在的其他复杂性,并且 Ubuntu 在 WSL 上运行(良好)并不是严格必要的,就像我们在没有 WSL 的情况下已经做了很多年一样。对于许多服务而言,选项 2 可能是更好(且更快)的选项。

    如果您确实启用了 Systemd,那么原始问题中的命令应该适合您:

    sudo systemctl enable docker
    sudo systemctl start docker
    
    Run Code Online (Sandbox Code Playgroud)

    下次重新启动 WSL2 发行版时,Docker 引擎应该会自动为您启动。但是,请参阅此答案的底部,了解有关保持服务运行的重要说明。


重要提示:如果您使用这些方法之一运行服务(例如cron或),请注意,当最后一个以交互方式启动的进程完成时,WSL 分发仍将自动终止。您可以在我对询问 Ubuntu 问题是否可以在后台运行 WSL 应用程序的回答中看到更多讨论(以及使用 的解决方法)。。dockerkeychain

  • “它会增加额外的开销和潜在的其他复杂性” - 我在 Linux 方面大致处于中级水平,并且很好奇它会增加什么开销? (2认同)
  • @J.ScottElblein 回复:开销——Systemd 会自动启动许多您可能不需要的服务。在 WSL2 上启用 Systemd 之前,我统计了启动时默认运行的服务有 5 个。启用 Systemd 后,该数字上升到 34。其中一些可以禁用,因为它们根本不需要(例如“wpa-supplicant”,用于在 Ubuntu 中配置无线网络),但这确实需要一些额外的操作努力。此外,虽然 Systemd 支持越来越好,但它仍然是最近 WSL2 版本中许多问题(和修复)的根源。 (2认同)
  • @J.ScottElblein 老实说,这本身可能就值得一个问题,但可能很难用正确的方式来表达它以避免“意见”。另外,如果你这样做,我建议你在 [Ask Ubuntu](askubuntu.com) 上询问(假设你运行的是 Ubuntu),因为那里的 Mod 比这里画的“主观”线更远一点;-)。 (2认同)