背景
因為最近一直在折騰Kubernetes集群版本升級、Docker版本升級, 所以不停的把測試環境安裝、還原、升級、降級, 簡直亂的不行。 終於, 在測試Docker版本升級後,
作業系統: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 unmask flanneld.service禁止flanneld服務, 然後刪除 /etc/systemd/system/docker.service.requires/flanneld.service, 使用systemctl daemon-reload重新載入服務設定檔, 最後systemctl start docker.service, 發現docker啟動成功了。
注:封面來自於:GRATISOGRAPHY