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