您的位置:首頁>遊戲>正文

docker.service啟動失敗:Unit not found

背景

因為最近一直在折騰Kubernetes集群版本升級、Docker版本升級, 所以不停的把測試環境安裝、還原、升級、降級, 簡直亂的不行。 終於, 在測試Docker版本升級後,

啟動Docker時, 遇到了docker.service: Unit not found。 問題雖然不大, 但是卻折磨了我幾個小時, 所以在此mark一下。

作業系統:Red Hat Enterprise Linux 7

原因1:docker.socket

最初在啟動docker時遇到問題, 是因為docker.socket引起的, 雖然記不清問題是表現為Unit not found還是執行systemctl start docker.service命令時hang住了, 但是也一併記錄在這裡。

問題描述

我是從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, 在啟動時就會出錯。

解決辦法

刪除/usr/lib/systemd/system/docker.service的[UNIT]裡包含的docker.socket, 然後systemctl daemon-reload, 最後systemctl start docker.service, 發現啟動成功了。

類似情況

如果是類似的情況, 缺少docker.socket, 但是新版本需要docker.socket。 有兩種方法可以解決該問題:

可以卸載docker, 再重新安裝, 即可出現docker.socket。

創建一個/usr/lib/systemd/system/docker.socket檔, 然後systemctl daemon-reload, 最後systemctl start docker.service, 即可啟動成功。

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

[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 列出所有可用的Unitsystemctl list-units 列出所有正在運行的Unitsystemctl --failed 列出所有失敗單元systemctl mask httpd.service 禁用服務systemctl unmask httpd.servicesystemctl 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啟動成功了。

注:封面來自於:GRATISOGRAPHY

Next Article
喜欢就按个赞吧!!!
点击关闭提示