如何在启动时启动Docker for Mac守护程序?

31

我希望将Docker for Mac设置为开机自启动,而不是登录后启动。请问如何做到这一点?我想创建一个LaunchDaemon,但不知道要启动哪个程序。

我看到的所有示例似乎都使用docker-machine来定义虚拟机,但文档现在说如果您想使用安装Docker时创建的默认虚拟机,则不应该使用docker-machine,因为Docker for Mac不使用docker-machine来创建虚拟机。

原因是我想启动Docker以在启动时运行Jenkins和Nexus容器,因为服务器将用作CI服务器。 Docker GUI有一个首选项选项可以在登录时启动,但与开机启动不同。

我正在运行OSX Sierra。


嗨,我面临着完全相同的需求(在无需登录的情况下启动Jenkins),并且遇到了相同的问题,你有没有找到不创建docker机器的解决方法?谢谢! - ZhouX
2个回答

33
TL;DR:作为独立服务运行Docker for Mac是不支持的
相反地,可以在VirtualBox虚拟机中运行Docker,可以创建一个普通的虚拟机或使用docker-machine然后设置Virtualbox虚拟机以在启动时运行
这是我用于Virtualbox的LaunchAgent:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>vm.dockervm</string>
    <key>ProgramArguments</key>
    <array>
      <string>/usr/local/bin/VBoxHeadless</string>
      <string>-s</string>
      <string>dockervm_default_1667177741</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>UserName</key>
    <string>me</string>
    <key>WorkingDirectory</key>
    <string>/Users/me</string>
    <key>StandardErrorPath</key>
    <string>/Users/me/log/vm/dockervm.log</string>
    <key>StandardOutPath</key>
    <string>/Users/me/log/vm/dockervm.log</string>
  </dict>
</plist>

装载了:

launchctl load /Users/matt/Library/LaunchAgents/vm.dockervm.plist

尝试安装Docker for Mac...

Docker for Mac应用程序创建一个launchd服务:

○→ launchctl list | grep -i docker
-   0   com.docker.helper
78105   0   com.docker.docker.52512

该服务具有以下细节:
○→ launchctl list com.docker.docker.52512
{
    "LimitLoadToSessionType" = "Aqua";
    "Label" = "com.docker.docker.52512";
    "TimeOut" = 30;
    "OnDemand" = true;
    "LastExitStatus" = 0;
    "PID" = 78105;
    "Program" = "/Applications/Docker.app/Contents/MacOS/Docker";
    "ProgramArguments" = (
        "/Applications/Docker.app/Contents/MacOS/Docker";
    );
    "PerJobMachServices" = {
        "com.apple.tsm.portname" = mach-port-object;
        "com.apple.CFPasteboardClient" = mach-port-object;
        "com.apple.coredrag" = mach-port-object;
        "com.apple.axserver" = mach-port-object;
    };
};

并具有以下进程树:

○→ pstree -p 78105
-+= 00001 root /sbin/launchd
 \-+= 78105 matt /Applications/Docker.app/Contents/MacOS/Docker
   \-+= 78118 matt /Applications/Docker.app/Contents/MacOS/com.docker.osx.hyperkit.linux -watchdog fd:0 -max-restarts 5 -restart-seconds 30
     |--- 78119 matt /Applications/Docker.app/Contents/MacOS/com.docker.osx.hyperkit.linux -watchdog fd:0 -max-restarts 5 -restart-seconds 30
     |--= 78120 matt com.docker.db --url fd://3 --git /Users/matt/Library/Containers/com.docker.docker/Data/database
     |--= 78121 matt com.docker.osxfs --address fd:3 --connect /Users/matt/Library/Containers/com.docker.docker/Data/@connect --control fd:4 --volume-control
     |--= 78122 matt com.docker.slirp --db /Users/matt/Library/Containers/com.docker.docker/Data/s40 --ethernet fd:3 --port fd:4 --introspection fd:5 --diagn
     |-+= 78123 matt com.docker.osx.hyperkit.linux
     | \--- 78125 matt /Applications/Docker.app/Contents/MacOS/com.docker.osx.hyperkit.linux
     \-+= 78124 matt com.docker.driver.amd64-linux -db /Users/matt/Library/Containers/com.docker.docker/Data/s40 -osxfs-volume /Users/matt/Library/Containers
       |--- 78126 matt /Applications/Docker.app/Contents/MacOS/com.docker.driver.amd64-linux -db /Users/matt/Library/Containers/com.docker.docker/Data/s40 -o
       \--- 78130 matt /Applications/Docker.app/Contents/MacOS/com.docker.hyperkit -A -m 2048M -c 3 -u -s 0:0,hostbridge -s 31,lpc -s 2:0,virtio-vpnkit,uuid=

第一个问题是/Applications/Docker.app/Contents/MacOS/Docker是坐落在托盘中的GUI应用程序,而不是VM,因此在启动时很难运行。第一个后代/Applications/Docker.app/Contents/MacOS/com.docker.osx.hyperkit.linux看起来更像是管理VM的东西,所以我们从那里开始。
获取hyperkit进程的完整命令
○→ ps -fp 78105
  UID   PID  PPID   C STIME   TTY           TIME CMD
  501 78105 82644   0  2:08am ??         0:00.03 /Applications/Docker.app/Contents/MacOS/com.docker.osx.hyperkit.linux -watchdog fd:0 -max-restarts 5 -restart-seconds 30

获取进程的工作目录
○→ sudo lsof -p 78105 | grep cwd
com.docke 78105 matt  cwd      DIR                1,4       748 63186601 /Users/matt/Library/Containers/com.docker.docker/Data

创建一个 launchd plist 文件 /Library/LaunchDaemons/com.you.docker.plist,其中包含详细信息。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
    <string>com.you.docker</string>
  <key>ProgramArguments</key>
    <array>
      <string>/Applications/Docker.app/Contents/MacOS/com.docker.osx.hyperkit.linux</string>
      <string>-watchdog</string>
      <string>fd:0</string>
      <string>-max-restarts</string>
      <string>5</string>
      <string>-restart-seconds</string>
      <string>30</string>
    </array>
  <key>UserName</key>
    <string>youruser</string>
  <key>WorkingDirectory</key>
    <string>/Users/youruser/Library/Containers/com.docker.docker/Data</string>
  <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

你可以加载它

sudo launchctl load -w /Library/LaunchDaemons/com.you.docker.plist

然后...什么都没有。检查日志。
○→ tail /var/log/system.log
Mar  7 02:23:26 mac Docker[87728]: Acquired task manager lock
Mar  7 02:23:26 mac Docker[87728]: Maximum number of file descriptors is 10240
Mar  7 02:23:26 mac Docker[87728]: Failed to read watchdog handshake
Mar  7 02:23:26 mac com.apple.xpc.launchd[1] (com.you.docker[87728]): Service exited with abnormal code: 1

您会注意到我们运行的命令指定了一个选项-watchdog fd:0,这将是hyperkit进程的标准输入,因此可能缺少某些内容。
如果我再次正常运行Docker,并查看hyperkit进程工作时FD 0的含义。
○→ sudo lsof -p 88360
COMMAND     PID USER   FD     TYPE             DEVICE  SIZE/OFF     NODE NAME
com.docke 88360 matt    0     PIPE 0xff80ce577ca2ed91     16384          ->0xff80ce5776aa8d51

然后查看系统中的PIPE 0xff80ce577ca2ed91,您会发现主要的Docker进程已经为许多进程打开了该管道。

○→ sudo lsof | grep 0xff80ce577ca2ed91
COMMAND     PID             USER   FD      TYPE             DEVICE    SIZE/OFF     NODE NAME
Docker    88349             matt   13      PIPE 0xff80ce5776aa8d51       16384          ->0xff80ce577ca2ed91
com.docke 88360             matt    0      PIPE 0xff80ce577ca2ed91       16384          ->0xff80ce5776aa8d51
com.docke 88362             matt    0      PIPE 0xff80ce577ca2ed91       16384          ->0xff80ce5776aa8d51
com.docke 88363             matt    0      PIPE 0xff80ce577ca2ed91       16384          ->0xff80ce5776aa8d51
com.docke 88364             matt    0      PIPE 0xff80ce577ca2ed91       16384          ->0xff80ce5776aa8d51
com.docke 88365             matt    0      PIPE 0xff80ce577ca2ed91       16384          ->0xff80ce5776aa8d51
com.docke 88366             matt    0      PIPE 0xff80ce577ca2ed91       16384          ->0xff80ce5776aa8d51

尝试重新加载服务时,如果没有使用-watchdog fd:0选项,则会导致相同的错误。因此,似乎主Docker应用程序会进行一些设置才能运行VM。我无法找到处理watchdog选项的源代码,因此不确定它的期望值。也许可以在https://github.com/docker/for-mac上提出问题或功能请求,以获取有关从应用程序单独运行VM的详细信息。

3
哇,这就是我为什么喜欢 Stack Overflow 的原因。感谢你提供了出色的答案,你说得完全正确,“docker-machine” 是正确的选择。 - John
2
@John,你能取消这个答案的标记吗?我昨天尝试了一下,到教程的结尾发现它并不具有决定性。或者,Matt,你能更新一下答案,让它更清楚地表明这是不可能的吗? - Isaac
守护进程模块由单独的项目管理。我在这里创建了一个问题:https://github.com/moby/moby/issues/40239 请投票。 - Blago
1
@Isaac 我已经在第一段加粗了一些内容。 - Matt
1
使用VirtualBox虚拟机进行操作与使用Docker桌面版相比,性能是否有所损失?我认为两者都使用了虚拟机,但我想知道的是Docker桌面版和运行Docker的VirtualBox这两个虚拟机的性能是否相当。 - fivestones
1
@fivestones 我没有注意到任何问题,但从未进行过直接比较。一个好处是VirtualBox 在运行虚拟机时使用的主机CPU更少。 - Matt

1

如果您之前已经安装了Docker,请启动Docker桌面应用程序,然后Docker守护进程就会开始工作。在进行了一个小时的研究和查阅不同平台后,我尝试了这种方法。对我来说有效。


你可以设置应用程序在登录时自动启动,但是如何设置帐户在启动时自动登录? - Denis Howe
1
@DenisHowe 您可以在此配置自动登录: 系统偏好设置 > 用户与群组 > 自动登录: <用户> - Nick Sweeting
对于我来说,使用桌面版:启动Docker作为应用程序(我使用聚光灯),然后单击状态栏中的菜单,选择“首选项”,然后启用“登录时启动Docker桌面”。 - Michael Behrens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接