![Docker.service 耗时 1 分 30 秒,导致启动缓慢](https://linux22.com/image/1570078/Docker.service%20%E8%80%97%E6%97%B6%201%20%E5%88%86%2030%20%E7%A7%92%EF%BC%8C%E5%AF%BC%E8%87%B4%E5%90%AF%E5%8A%A8%E7%BC%93%E6%85%A2.png)
我在 Linux Mint 19 上使用 Cinnamon 3.8.8,
我有一台 Nvidia GT740 和 8GB RAM
我使用的是:
Docker 版本 18.06.1-ce,构建 e68fc7a docker-machine 版本 0.14.0,构建 89b8332 docker-compose 版本 1.21.2,构建 a133471
我注意到我的启动速度非常慢
所以我跑了:
systemd-analyze blame
我得到了以下信息:
1min 27.764s docker.service
39.269s plymouth-quit-wait.service
24.180s dev-sdb2.device
20.645s nmbd.service
18.437s snapd.service
13.111s systemd-journal-flush.service
12.475s udisks2.service
12.446s NetworkManager.service
10.969s keyboard-setup.service
10.734s libvirtd.service
10.418s NetworkManager-wait-online.service
10.168s networkd-dispatcher.service
10.065s smbd.service
9.736s apparmor.service
..... etc
正如您所看到的,docker.service 花费了大量的时间,有人知道如何解决这个问题吗?
答案1
我注意到这个问题已经存在好几年了,但是今天我在具有以下规格的开发系统上遇到了同样的问题:
- Ubuntu 20.04
- Docker 20.10.17
- docker-compose 1.25.0
Docker.service 在我的系统上花费了超过 10 分钟的时间,并且它在最终启动时劫持了 multi-user.target 和 graphic.target,导致我的系统在此过程中非常不稳定。(您可以在屏幕上移动光标,但您运行的程序需要等待很长时间才能真正启动)
由于我的系统是一台开发机器并且没有运行关键基础设施,所以我只是禁用了该服务:
sudo systemctl disable docker
删除启动时重启也有助于长期保持这种状态。检查您的服务单元文件。systemctl cat docker.service
如果您always
在服务节中写着“重新启动”,您可以将其更改为on-failure
仅在失败时重新启动(在您通过 docker.socket 激活有意运行它之后),这样它就不会在启动时启动,这将为您节省大量启动时间。这就是我现在使用它的方式:
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=on-failure
containerd 服务和 docker.socket 服务仍将运行,就我而言,从目前所见,它们不需要很长时间即可激活(30 秒以下)。
当需要时,docker.socket 会生成一个新的 docker.service(如果你运行 docker 或 docker-compose 命令),因为此时 docker 服务正在启动后整个系统已经启动并运行,等待时间大大减少,因为此时 docker.service 所依赖的任何其他东西都已在运行并处于活动状态。
这是我在系统上禁用 docker 服务并重新启动几次之后,在进行日常 web 开发工作时观察到的情况。
答案2
基于本文我跑了:
❯ systemd-analyze critical-chain
The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.
graphical.target @42.222s
└─multi-user.target @42.221s
└─docker.service @38.091s +4.129s
└─network-online.target @38.082s
└─NetworkManager-wait-online.service @4.450s +33.629s
└─NetworkManager.service @4.330s +69ms
└─network-pre.target @4.268s
这表明,docker 等待网络才是真正的罪魁祸首。
然后sudo systemctl edit docker
我复制了该After
行并删除了network-online.target
,最后得到如下结果:
After=docker.socket firewalld.service containerd.service time-set.target
这为那些希望在启动时准备好docker的人提供了一个合适的解决方案:)