關(guān)于Docker存儲overlay2相關(guān)問題
最近項目上服務(wù)器磁盤滿了,項目上小哥為了騰出來點空間,把docker的overlay2文件給刪了部分,導致部分容器啟動時候報錯:
docker: Error response from daemon: open /var/lib/docker/overlay2/ffe5563b8c6a834b21dadb22106209d9fa1ab64ebe063e3ec040a05f1c: no such file or directory
大體意思就是overlay2下面的這個文件沒了
處理方式:
1、首先保證之前業(yè)務(wù)數(shù)據(jù)庫有備份
2、把現(xiàn)在運行的容器關(guān)掉、刪除
3、把相關(guān)鏡像備份下,然后清理掉
4、按順序重新導入新的鏡像,然后重新啟動容器并導入備份的數(shù)據(jù)
問題根源在于docker的 Root Dir滿了,這個默認路徑在 /var/lib/docker
我們可以在部署docker時候修改這個默認路徑,改成一個相對較大路徑下
1、systemctl stop docker <br> 關(guān)閉docker
2、修改 /etc/docker/daemon.json配置文件
vi /etc/docker/daemon.json
{
"data-root": "/data/lib/docker"
}
3、rsnyc -avz source dest
-a包含子目錄 同時同步元信息(比如修改時間、權(quán)限等)
-v控制臺輸出信息
-z先壓縮再傳輸
它可以在本地計算機與遠程計算機之間,或者兩個本地目錄之間同步文件(但不支持兩臺遠程計算機之間的同步)
沒安裝的可以用 yum install rsync安裝或者用 cp mv等命令遷移
4、systemctl enable docker <br> 設(shè)置開機啟動docker
5、驗證路徑是否改變
docker info|grep 'Root Dir'
6、驗證鏡像是否存在
docker images
但是遷移到大磁盤治標不治本,需要找出來根本原因,我們?nèi)ocker的Root Dir 輸入命令
du -h --max-depth=1|sort -n
查看大文件路徑,可以發(fā)現(xiàn)兩個目錄容易比較大 一個是container目錄 一個是overlay2目錄
對于overlay2目錄,可以使用
docker system prune -a
清理磁盤,刪除關(guān)閉的容器、無用的數(shù)據(jù)卷和網(wǎng)絡(luò),以及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
/var/lib/docker下的幾個目錄 及docker的幾個id
1、 /var/lib/docker下目錄結(jié)構(gòu)為:
container
image
network
swarm
volumes
overlay2
...
可以看到docker涉及到的一些概念容器、鏡像、網(wǎng)絡(luò)、掛載等都在這里有對應(yīng)的目錄,這是docker的存儲目錄
2、docker存儲驅(qū)動:
現(xiàn)在docker支持很多種文件驅(qū)動類型,比如AUFS、OverlayFS,OverlayFS實現(xiàn)方式和AUFS類似,但是更快、且實現(xiàn)起來簡單
對于linux內(nèi)核4.0及以上版本 或者紅帽、centos 3.10.0-514版本可以使用overlay2存儲驅(qū)動,其他低版本使用overlay(更推進 overlay2, 對于inode管理更好 效率更高)
我們可以通過修改配置文件 /etc/docker/daemon.json 來調(diào)整驅(qū)動類型
{
"storage-driver": "overlay2"
}
3、container目錄:
container目錄內(nèi)部是啟動容器的一些配置信息
hosts、hostname域名等信息;
config.v2.json配置文件,我們使用docker inspect 容器時候獲取到的容器配置信息;
*-json.log容器產(chǎn)品日志文件
4、image目錄:
distribution 目錄
diffid-by-digest 保存了digest(layerID)->diffID的映射關(guān)系
v2metadata-by-diffid 保存了diffid -> (digest,repository)的映射關(guān)系
digest(layerID) 就是 pull 鏡像時的 hash ID,拉取是 鏡像層文件是壓縮文件,壓縮態(tài)
diffid 是 docker inspect 查看到的 鏡像層 hash ID,此時 鏡像層文件是解壓縮的,解壓縮態(tài)
因此雖說這兩種 ID 都表示 鏡像層 hash ID,但一個是壓縮的,一個是解壓縮的,所以 hash 運算后不一致
imagedb、layerdb 這倆都是元數(shù)據(jù)文件
imagedb可以看到鏡像的元數(shù)據(jù)信息, cat下看到內(nèi)部寫著 dfffid
repositories.json 記錄本地鏡像列表, 鏡像名稱-版本:imageId
rootfs:
diffid: sha256 記錄各層解壓后經(jīng)過sha256算法計算得來的值,
兩個優(yōu)勢 一個方便校驗、一個方便共享
5、layerdb目錄
sha目錄,內(nèi)部記錄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文件(就是啟動容器之后 回顯的文件)
6、Overlay2:
lower:底層文件系統(tǒng)。對于Docker來說,就是只讀的鏡像層;upper:上層文件系統(tǒng)。對于Docker來說,就是可讀寫的容器層;merged:作為統(tǒng)一視圖的聯(lián)合掛載點。對于Docker來說,就是用戶視角下的文件系統(tǒng);work:提供輔助功能。
最后說明下,回到最開頭的問題,如果誤刪了文件導致docker容器無法啟動,可以將磁盤上的/var/lib/docker目錄重命名,然后重啟docker服務(wù),讓docker重新拉取鏡像,但如果以前的文件系統(tǒng)沒有映射,會丟失文件,所以還是建議存儲的內(nèi)容一定要做好目錄映射。