天天看點

selinux踩坑篇-docker容器無法啟動

問題概述

主機重新開機後,docker上的容器無法啟動,報錯如下

# docker restart nginx-proxy
Error response from daemon: Cannot restart container nginx-proxy: error creating overlay mount to /var/lib/docker/overlay2/7431ad53435c5cb52cc24ecc7263b580d4087e2c25e0d4c4c14c577a32ad3607/merged: invalid argument
           

問題排查

首先懷疑可能是鏡像問題,于是嘗試用同一個鏡像去啟動一個新的容器,可以正常啟動成功,排除是鏡像的問題

# docker run -itd --name test nginx:1.14
17a4ab4080dc347828e34b576de2d1922d16f6a0929d9eb5f513313df0a32609
           

接着看了docker的日志,沒發現有用的資訊

由于報錯顯示的是mount過程中出現了異常,是以接着排查了系統日志,發現如下報錯

selinux踩坑篇-docker容器無法啟動

看到這段報錯頓時有種熟悉感,

system_u:object_r

這種字元串很明顯跟selinux有關,于是懷疑環境中肯定是開啟了selinux導緻容器挂載異常無法啟動

于是看了下selinux的狀态,發現是disabled的狀态。看到selinux是disabled的狀态時,差點将selinux排除在外,還好上面的的報錯我很确定是跟selinux有關

# getenforce 
Disabled
           

為了驗證是否跟selinux有關,我重新将selinux設定為啟動狀态,并重新開機了主機,果然容器可以啟動成功

# docker restart nginx-proxy
nginx-proxy
           

此時問題還未解決,因為selinux需要關閉,是以還需要進一步檢視容器為什麼無法啟動

接着再把selinux給關掉,再重新開機主機,果然容器又無法啟動了

由于新的容器可以啟動成功,而舊的容器則無法啟動,是以懷疑是不是容器配置有什麼不一樣的地方,于是檢視了下容器的配置,果然在容器的配置中發現了異常

cd /var/lib/docker/containers/<container_id>/
cat config.v2.json
           
selinux踩坑篇-docker容器無法啟動

從上圖中可以發現, MountLabel和ProcessLabel中都攜帶了selinux的參數,于是将這兩個參數的值都設定為空,然後重新開機docker(直接修改配置無法生效,需要重新開機docker才能生效),容器啟動成功了!

# vi config.v2.json
...
...
"MountLabel":"","ProcessLabel":""
...
...

# systemctl restart docker
# docker ps |grep nginx
037bd8327183        nginx:1.14                      "nginx -g 'daemon of…"   About 18 hour ago   Up 11 seconds                           nginx-proxy
           

至此問題解決

問題總結

該問題的主要原因是作業系統之前開啟過selinux,在此前提下啟動docker并建立了該容器,于是docker的啟動參數中會攜帶某些selinux配置,随後又修改了/etc/selinux/config的配置,将selinux設定為disabled的狀态,但是此時selinux的disabled還未生效,而要使selinux的disabled生效,需要重新開機主機。是以在重新開機主機前,selinux的狀态還是開啟的,容器都是能夠正常運作。

當重新開機主機後,/etc/selinux/config下的配置就開始生效,selinux就會被設定為disabled的狀态,此時容器的配置中還攜帶有selinux的配置,當啟動容器時,會攜帶這些配置去通路selinux服務,此時selinux是不可用的狀态,是以容器就會抛出異常無法啟動。

解決方法:

  1. 重新啟用selinux,然後重新開機主機即可。selinux 主要作用就是最大限度地減小系統中服務程序可通路的資源,但是如果對selinux不是很懂的情況下,開啟selinux可能還會引起其他問題,此時建議采用第二種方法
  2. 修改容器的配置,将 MountLabel 和 ProcessLabel 兩個參數的值設定為空

    "MountLabel":"","ProcessLabel":""

    ,然後重新開機docker服務,容器即可修複