docker.service启动失败:Unit not found

由于最近一直在折腾Kubernetes集群版本升级、Docker版本升级,因此不停的把测试环境安装、还原、升级、降级,简直乱的不行。终于,在测试Docker版本升级后,启动Docker时,遇到了docker.service: Unit not found。问题虽然不大,可是却折磨了我几个小时,因此在此mark一下。docker

操做系统:Red Hat Enterprise Linux 7bash

缘由1:docker.socket


最初在启动docker时遇到问题,是由于docker.socket引发的,虽然记不清问题是表现为Unit not found仍是执行systemctl start docker.service命令时hang住了,可是也一并记录在这里。socket

问题描述

我是从Docker 1.10.3升级到1.13.1版本,经过rpm包安装的。因为要保留自定义的一些Docker配置,因此在升级后,使用原来的/usr/lib/systemd/system/docker.service覆盖了新的docker.service。可是在1.10.3版本中,docker.service的[UNIT]里规定了Requires=docker.socket,也就是说,docker.service默认依赖于docker.socket,由于须要使用docker.socket来获取容器的信息。测试

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target docker.socket
Requires=docker.socket

可是在1.13.1版本中,已经再也不依赖于docker.socket了,因此系统里没有docker.socket,而我继续使用原来的docker.service,在启动时就会出错。ui

解决办法

删除/usr/lib/systemd/system/docker.service的[UNIT]里包含的docker.socket,而后systemctl daemon-reload,最后systemctl start docker.service,发现启动成功了。操作系统

相似状况

若是是相似的状况,缺乏docker.socket,可是新版本须要docker.socket。有两种方法能够解决该问题:code

  1. 能够卸载docker,再从新安装,便可出现docker.socket。进程

  2. 建立一个/usr/lib/systemd/system/docker.socket文件,而后systemctl daemon-reload,最后systemctl start docker.service,便可启动成功。ip

/usr/lib/systemd/system/docker.socket文件以下:get

[Unit]
Description=Docker Socket for the API
PartOf=docker.service

[Socket]
ListenStream=/var/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker

[Install]
WantedBy=sockets.target

缘由2:flanneld.service


就如背景里描述的,我刚好在这台出问题的机器上,安装过Kubernetes,以及flannel,而后又删掉了我以前觉得的“全部”相关的文件。正是因为flannel的文件没有删除干净,致使出现了docker.service: Unit not found的问题。

问题描述

在肯定不是由于docker.socket的问题致使的以后,我第一反应就是删除flannel致使的,由于我了解flanneld.service与docker.service直接是有启动顺序的关联的:

[Unit]
Description=Flanneld overlay address etcd agent
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service

真正困扰了我好久的是,/usr/lib/systemd/system/flanneld.service我已经删除了,也systemctl daemon-reload了,究竟还有哪一个文件漏删了。

通过检查,/etc/systemd/system/flanneld.service依然存在,而且存在/etc/systemd/system/docker.service.requires目录,在该目录下包含了软链接flanneld.service,该软连接指向了真正的flanneld.service,从而实现了两个服务的启动顺序的关联。

定位该类问题,常常会用到的命令有:

  • systemctl list-unit-files 列出全部可用的Unit
  • systemctl list-units 列出全部正在运行的Unit
  • systemctl --failed 列出全部失败单元
  • systemctl mask httpd.service 禁用服务
  • systemctl unmask httpd.service
  • systemctl kill httpd 杀死服务
  • systemd-analyze critical-chain:分析启动时的关键链
  • systemd-analyze blame 分析启动时各个进程花费的时间

解决办法

使用systemctl unmask flanneld.service禁止flanneld服务,而后删除 /etc/systemd/system/docker.service.requires/flanneld.service,使用systemctl daemon-reload从新加载服务配置文件,最后systemctl start docker.service,发现docker启动成功了。

相关文章
相关标签/搜索