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啓動成功了。

相關文章
相關標籤/搜索