1、問題來源
最近項目上服務器磁盤滿了,項目上小哥為了騰出來點空間,把docker的overlay2文件給刪了部分,導致部分容器啟動時候報錯:
docker: Error response from daemon: open /var/lib/docker/overlay2/ffe5563b8c6a834b21dadb22106209d9fa1ab64ebe063e3ec040a05f1c: no such file or directory
大體意思就是overlay2下面的這個文件沒了
處理方式:
1、首先保證之前業務數據庫有備份 2、把現在運行的容器關掉、刪除 3、把相關鏡像備份下,然后清理掉 4、按順序重新導入新的鏡像,然后重新啟動容器並導入備份的數據
2、問題根源
問題根源在於docker的 Root Dir滿了,這個默認路徑在 /var/lib/docker
我們可以在部署docker時候修改這個默認路徑,改成一個相對較大路徑下
1、systemctl stop docker
關閉docker 2、修改 /etc/docker/daemon.json配置文件 vi /etc/docker/daemon.json { "data-root": "/data/lib/docker" } 3、rsnyc -avz source dest -a包含子目錄 同時同步元信息(比如修改時間、權限等) -v控制台輸出信息 -z先壓縮再傳輸 它可以在本地計算機與遠程計算機之間,或者兩個本地目錄之間同步文件(但不支持兩台遠程計算機之間的同步) 沒安裝的可以用 yum install rsync安裝或者用 cp mv等命令遷移 4、systemctl enable docker
設置開機啟動docker 5、驗證路徑是否改變 docker info|grep 'Root Dir' 6、驗證鏡像是否存在 docker images
但是遷移到大磁盤治標不治本,需要找出來根本原因,我們去docker的Root Dir 輸入命令
du -h --max-depth=1|sort -n
查看大文件路徑,可以發現兩個目錄容易比較大 一個是container目錄 一個是overlay2目錄
對於overlay2目錄,可以使用
docker system prune -a
清理磁盤,刪除關閉的容器、無用的數據卷和網絡,以及dangling鏡像(即無tag的鏡像),
-a 命令清理得更加徹底,可以將沒有容器使用Docker鏡像都刪掉
對於container目錄,基本是容器運行日志造成的,進入 container目錄 輸入命令 可以看到大文件,都是一些日志文件
du -h --max-depth=1|sort -n
對於日志
cat /dev/null > *-json.log清空日志
同時對於容器加啟動限制
docker run ...... --log-opt max-size=10m --log-opt max-file=1
或者 修改/etc/docker/daemon.json配置文件
{ "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3", "labels": "production_status", "env": "os,customer" } }
或者在啟動的docker-compose.yml添加限制
logging: options: max-size: '12m' max-file: '5' driver: json-file
3、另外說明
/var/lib/docker下的幾個目錄 及docker的幾個id
3.1、 /var/lib/docker下目錄結構為:
container image network swarm volumes overlay2 ...
可以看到docker涉及到的一些概念容器、鏡像、網絡、掛載等都在這里有對應的目錄,這是docker的存儲目錄
3.2、docker存儲驅動:
現在docker支持很多種文件驅動類型,比如AUFS、OverlayFS,OverlayFS實現方式和AUFS類似,但是更快、且實現起來簡單 ---> 說明文章
對於linux內核4.0及以上版本 或者紅帽、centos 3.10.0-514版本可以使用overlay2存儲驅動,其他低版本使用overlay(更推進 overlay2, 對於inode管理更好 效率更高)
我們可以通過修改配置文件 /etc/docker/daemon.json 來調整驅動類型
{ "storage-driver": "overlay2" }
3.3、container目錄:
container目錄內部是啟動容器的一些配置信息
hosts、hostname域名等信息;
config.v2.json配置文件,我們使用docker inspect 容器時候獲取到的容器配置信息;
*-json.log容器產品日志文件
3.4、image目錄:
distribution 目錄
diffid-by-digest 保存了digest(layerID)->diffID的映射關系
v2metadata-by-diffid 保存了diffid -> (digest,repository)的映射關系
digest(layerID) 就是 pull 鏡像時的 hash ID,拉取是 鏡像層文件是壓縮文件,壓縮態
diffid 是 docker inspect 查看到的 鏡像層 hash ID,此時 鏡像層文件是解壓縮的,解壓縮態
因此雖說這兩種 ID 都表示 鏡像層 hash ID,但一個是壓縮的,一個是解壓縮的,所以 hash 運算后不一致
imagedb、layerdb 這倆都是元數據文件
imagedb可以看到鏡像的元數據信息, cat下看到內部寫着 dfffid
repositories.json 記錄本地鏡像列表, 鏡像名稱-版本:imageId
rootfs:
diffid: sha256 記錄各層解壓后經過sha256算法計算得來的值,
兩個優勢 一個方便校驗、一個方便共享
3.5、layerdb目錄
sha目錄,內部記錄ChainID
如果layer是最底層,沒有任何父layer,那么diffID = chainID;
否則,chainID(n)=sha256sum(chainID(n-1)) diffID(n))
舉個例子: 兩層的 diffid diffid2 進行shasum256運算得出chainID
echo -n "sha256:5dacd731af1b0386ead06c8b1feff9f65d9e0bdfec032d2cd0bc03690698feda sha256:dd0338cdfab32cdddd6c30efe8c89d0229d9f939e2bb736fbb0a52f27c2b0ee9" | shasum -a 256
找到chainID之后,進去具體某個目錄則看到 cache-id,指向具體真實的的overlay2文件
mounts
每啟動一個容器,則在 layerdb下面會多一個 mounts文件(就是啟動容器之后 回顯的文件)
3.6、Overlay2:
- lower:底層文件系統。對於Docker來說,就是只讀的鏡像層;
- upper:上層文件系統。對於Docker來說,就是可讀寫的容器層;
- merged:作為統一視圖的聯合掛載點。對於Docker來說,就是用戶視角下的文件系統;
- work:提供輔助功能。