由于最近一直在折腾Kubernetes集群版本升级、Docker版本升级,因此不停的把测试环境安装、还原、升级、降级,简直乱的不行。终于,在测试Docker版本升级后,启动Docker时,遇到了docker.service: Unit not found。问题虽然不大,可是却折磨了我几个小时,因此在此mark一下。docker
操做系统:Red Hat Enterprise Linux 7bash
最初在启动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
能够卸载docker,再从新安装,便可出现docker.socket。进程
建立一个/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
就如背景里描述的,我刚好在这台出问题的机器上,安装过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 unmask flanneld.service禁止flanneld服务,而后删除 /etc/systemd/system/docker.service.requires/flanneld.service,使用systemctl daemon-reload从新加载服务配置文件,最后systemctl start docker.service,发现docker启动成功了。