docker存儲(chǔ)驅(qū)之overlayFS

一、概述

成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供尼開(kāi)遠(yuǎn)網(wǎng)站建設(shè)、尼開(kāi)遠(yuǎn)做網(wǎng)站、尼開(kāi)遠(yuǎn)網(wǎng)站設(shè)計(jì)、尼開(kāi)遠(yuǎn)網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、尼開(kāi)遠(yuǎn)企業(yè)網(wǎng)站模板建站服務(wù),10余年尼開(kāi)遠(yuǎn)做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

    docker鏡像采用分層分層構(gòu)建設(shè)計(jì),每層稱為"layer", layer存放在/data/docker/存儲(chǔ)驅(qū)動(dòng)/目錄下面

這些存儲(chǔ)驅(qū)動(dòng)有,AUFS,OverlayFS等,可以通過(guò)docker info命令查看存儲(chǔ)驅(qū)動(dòng),centos7.1+默認(rèn)采用OverlayFS模式.
二、OverlayFS介紹

OverlayFS是一種堆疊文件系統(tǒng),建立在其他文件系統(tǒng)之上,并不參與磁盤(pán)底層劃分,只是將底層文件系統(tǒng)目錄"合并",實(shí)際是偽合并,只是呈現(xiàn)給用戶好像一個(gè)文件系統(tǒng)結(jié)構(gòu),這也就是聯(lián)合掛載技術(shù),對(duì)比于AUFS,OverlayFS速度更快,實(shí)現(xiàn)更簡(jiǎn)單,因?yàn)镺verlayFS只分兩層,只讀層,和讀寫(xiě)層, Linux 內(nèi)核為Docker提供的OverlayFS驅(qū)動(dòng)有兩種:overlay和overlay2。而overlay2是相對(duì)于overlay的一種改進(jìn),在inode利用率方面比overlay更有效。但是overlay有環(huán)境需求:docker版本17.06.02+,宿主機(jī)文件系統(tǒng)需要是ext4或xfs格式.

聯(lián)合掛載技術(shù):
overlayfs通過(guò)三個(gè)目錄:lower目錄、upper目錄、以及work(不太理解這個(gè)目錄怎么工作的)目錄實(shí)現(xiàn),其中l(wèi)ower目錄可以是多個(gè),work目錄為工作基礎(chǔ)目錄,掛載后內(nèi)容會(huì)被清空,且在使用過(guò)程中其內(nèi)容用戶不可見(jiàn),最后聯(lián)合掛載完成給用戶呈現(xiàn)的統(tǒng)一視圖稱為為merged目錄。以下使用mount將演示其如何工作的
docker 存儲(chǔ)驅(qū)之overlayFS

然后使用mount聯(lián)合掛載到/tmp/test 下:
mount -t overlay overlay -o lowerdir=A:B,upperdir=C,workdir=worker /tmp/test
掛載之后三個(gè)目錄會(huì)合并成一個(gè),并且相同文件名的文件會(huì)進(jìn)行“覆蓋”,這里覆蓋并不是真正的覆蓋,而是當(dāng)合并時(shí)候目錄中兩個(gè)文件名稱都相同時(shí),merged(/tmp/test)層目錄會(huì)顯示離它最近層的文件(lowerdir=A:B,A離他最近)
看看掛載情況:
docker 存儲(chǔ)驅(qū)之overlayFS

docker 存儲(chǔ)驅(qū)之overlayFS

docker官網(wǎng)overlay驅(qū)動(dòng)模型:
docker 存儲(chǔ)驅(qū)之overlayFS

在上述圖中可以看到三個(gè)層結(jié)構(gòu),即:lowerdir、uperdir、merged,其中l(wèi)owerdir是只讀的image layer,其實(shí)就是rootfs,對(duì)比我們上述演示的目錄A和B,我們知道image layer可以分很多層,所以對(duì)應(yīng)的lowerdir是可以有多個(gè)目錄。而upperdir則是在lowerdir之上的一層,這層是讀寫(xiě)層,在啟動(dòng)一個(gè)容器時(shí)候會(huì)進(jìn)行創(chuàng)建,所有的對(duì)容器數(shù)據(jù)更改都發(fā)生在這里層,對(duì)比示例中的C。最后merged目錄是容器的掛載點(diǎn),也就是給用戶暴露的統(tǒng)一視角,對(duì)比示例中的/tmp/test。而docker目錄層都保存在了/var/lib/docker/overlay2/或者/var/lib/docker/overlay/(如果使用overlay)

容器示例:
創(chuàng)建一個(gè)容器:
docker run -it centos /bin/bash
查看掛載情況:
docker 存儲(chǔ)驅(qū)之overlayFS

容器修改數(shù)據(jù)時(shí),overlay怎么工作?
讀:
1.如果文件在容器層(upperdir),直接讀取文件
2.如果文件不在容器層(upperdir),則從鏡像層(lowerdir)讀取
寫(xiě):
1.首次寫(xiě)入: 如果在upperdir中不存在,overlay和overlay2執(zhí)行copy_up操作,把文件從lowdir拷貝到upperdir,由于overlayfs是文件級(jí)別的(即使文件只有很少的一點(diǎn)修改,也會(huì)產(chǎn)生的copy_up的行為),后續(xù)對(duì)同一文件的在此寫(xiě)入操作將對(duì)已經(jīng)復(fù)制到容器的文件的副本進(jìn)行操作。這也就是常常說(shuō)的寫(xiě)時(shí)復(fù)制(copy-on-write)
2.刪除文件和目錄: 當(dāng)文件在容器被刪除時(shí),在容器層(upperdir)創(chuàng)建whiteout文件,鏡像層(lowerdir)的文件是不會(huì)被刪除的,因?yàn)樗麄兪侵蛔x的,但without文件會(huì)阻止他們顯示,當(dāng)目錄在容器內(nèi)被刪除時(shí),在容器層(upperdir)一個(gè)不透明的目錄,這個(gè)和上面whiteout原理一樣,阻止用戶繼續(xù)訪問(wèn),即便鏡像層仍然存在

注意:
1.copy_up操作只發(fā)生在文件首次寫(xiě)入,以后都是只修改副本
2.容器層的文件刪除只是偽刪除,是靠whiteout文件將其遮擋,image層并沒(méi)有刪除,這也就是為什么使用docker commit 提交保存的鏡像會(huì)越來(lái)越大,無(wú)論在容器層怎么刪除數(shù)據(jù),image層都不會(huì)改變

過(guò)程演示:
docker 存儲(chǔ)驅(qū)之overlayFS

發(fā)現(xiàn)修改操作只在C目錄發(fā)生也就是upperdir層發(fā)生

三、overlay2 鏡像存儲(chǔ)結(jié)構(gòu)

docker pull ubuntu
docker 存儲(chǔ)驅(qū)之overlayFS
四層layer存儲(chǔ)位置:
docker 存儲(chǔ)驅(qū)之overlayFS

這里面多了一個(gè)l目錄包含了所有層的軟連接,短鏈接使用短名稱,避免mount時(shí)候參數(shù)達(dá)到頁(yè)面大小限制(演示中mount命令查看時(shí)候的短目錄)
docker 存儲(chǔ)驅(qū)之overlayFS

處于底層的鏡像目錄包含了一個(gè)diff和一個(gè)link文件,diff目錄存放了當(dāng)前層的鏡像內(nèi)容,而link文件則是與之對(duì)應(yīng)的短名稱
docker 存儲(chǔ)驅(qū)之overlayFS

在這之上的鏡像還多了work目錄和lower文件,lower文件用于記錄父層的短名稱,work目錄用于聯(lián)合掛載指定的工作目錄。
docker 存儲(chǔ)驅(qū)之overlayFS

而這些目錄和鏡像的關(guān)系是通過(guò)元數(shù)據(jù)關(guān)聯(lián)。元數(shù)據(jù)分為image元數(shù)據(jù)和layer元數(shù)據(jù):

image鏡像原數(shù)據(jù):

鏡像元數(shù)據(jù)存儲(chǔ)在了/var/lib/docker/image/<storage_driver>/imagedb/content/sha256/目錄下,名稱是以鏡像ID命名的文件,鏡像ID可通過(guò)docker images查看,這些文件以json的形式保存了該鏡像的rootfs信息、鏡像創(chuàng)建時(shí)間、構(gòu)建歷史信息、所用容器、包括啟動(dòng)的Entrypoint和CMD等等:

ubuntu鏡像id
docker 存儲(chǔ)驅(qū)之overlayFS

進(jìn)入鏡像元數(shù)據(jù)目錄
cd /data/docker/image/overlay2/imagedb/content/sha256/
vim 775349758637aff77bf85e2ff0597e86e3e859183ef0baba8b3e8fc8d3cba51c
docker 存儲(chǔ)驅(qū)之overlayFS
上面的 diff_id 對(duì)應(yīng)的的是一個(gè)鏡像層,其排列也是有順序的,從上到下依次表示鏡像層的最低層到最頂層

docker 利用 rootfs 中的每個(gè)diff_id 和歷史信息計(jì)算出與之對(duì)應(yīng)的內(nèi)容尋址的索引(chainID) ,而chaiID則關(guān)聯(lián)了layer層,進(jìn)而關(guān)聯(lián)到每一個(gè)鏡像層的鏡像文件

layer元數(shù)據(jù):

鏡像層只包含一個(gè)具體的鏡像層文件包。用戶在 docker 宿主機(jī)上下載了某個(gè)鏡像層之后,docker 會(huì)在宿主機(jī)上基于鏡像層文件包和 image 元數(shù)據(jù)構(gòu)建本地的 layer 元數(shù)據(jù),包括 diff、parent、size 等。而當(dāng) docker 將在宿主機(jī)上產(chǎn)生的新的鏡像層上傳到 registry 時(shí),與新鏡像層相關(guān)的宿主機(jī)上的元數(shù)據(jù)也不會(huì)與鏡像層一塊打包上傳。
Docker 中定義了 Layer 和 RWLayer 兩種接口,分別用來(lái)定義只讀層和可讀寫(xiě)層的一些操作,又定義了 roLayer 和 mountedLayer,分別實(shí)現(xiàn)了上述兩種接口。其中,roLayer 用于描述不可改變的鏡像層,mountedLayer 用于描述可讀寫(xiě)的容器層。具體來(lái)說(shuō),roLayer 存儲(chǔ)的內(nèi)容主要有索引該鏡像層的 chainID、該鏡像層的校驗(yàn)碼 diffID、父鏡像層 parent、storage_driver 存儲(chǔ)當(dāng)前鏡像層文件的 cacheID、該鏡像層的 size 等內(nèi)容。這些元數(shù)據(jù)被保存在

docker 存儲(chǔ)驅(qū)之overlayFS

每個(gè)chainID目錄下會(huì)存在三個(gè)文件cache-id、diff、size
docker 存儲(chǔ)驅(qū)之overlayFS
cache-id文件:
docker隨機(jī)生成的uuid,內(nèi)容是保存鏡像層的目錄索引,也就是/var/lib/docker/overlay2/中的目錄,這就是為什么通過(guò)chainID能找到對(duì)應(yīng)的layer目錄。以chainID為565879c6effe6a013e0b2e492f182b40049f1c083fc582ef61e49a98dca23f7e 對(duì)應(yīng)的目錄為 0b7bbc608eca835ac9bdb31a1794016a8fd1dacc8f58fbcf2763db1dc40d3f32,也就保存在/data/docker/overlay2/0b7bbc608eca835ac9bdb31a1794016a8fd1dacc8f58fbcf2763db1dc40d3f32
docker 存儲(chǔ)驅(qū)之overlayFS

diff文件:
保存了鏡像元數(shù)據(jù)中的diff_id(與元數(shù)據(jù)中的diff_ids中的uuid對(duì)應(yīng)
docker 存儲(chǔ)驅(qū)之overlayFS

size文件:
保存了鏡像層的大小
docker 存儲(chǔ)驅(qū)之overlayFS

在 layer 的所有屬性中,diffID 采用 SHA256 算法,基于鏡像層文件包的內(nèi)容計(jì)算得到。而 chainID 是基于內(nèi)容存儲(chǔ)的索引,它是根據(jù)當(dāng)前層與所有祖先鏡像層 diffID 計(jì)算出來(lái)的,具體算如下:
1.如果該鏡像層是最底層(沒(méi)有父鏡像層),該層的 diffID 便是 chainID
2.該鏡像層的 chainID 計(jì)算公式為 chainID(n)=SHA256(chain(n-1) diffID(n)),也就是根據(jù)父鏡像層的 chainID 加上一個(gè)空格和當(dāng)前層的 diffID,再計(jì)算 SHA256 校驗(yàn)碼
mountedLayer 信息存儲(chǔ)的可讀init層以及容器掛載點(diǎn)信息包括:容器 init 層ID(init-id)、聯(lián)合掛載使用的ID(mount-id)以及容器層的父層鏡像的 chainID(parent)。相關(guān)文件位于/var/lib/docker/image/<storage_driver>/layerdb/mounts/<container_id>/ 目錄下

docker 存儲(chǔ)驅(qū)之overlayFS
可以看到initID是在mountID后加了一個(gè)-init,同時(shí)initID就是存儲(chǔ)在/var/lib/docker/overlay2/的目錄名稱:
docker 存儲(chǔ)驅(qū)之overlayFS
查看mountID還可以直接通過(guò)mount命令查看對(duì)應(yīng)掛載的mountID,對(duì)應(yīng)著/data/docker/overlay2/目錄,這也是overlayfs呈現(xiàn)的merged目錄
docker 存儲(chǔ)驅(qū)之overlayFS

在容器中創(chuàng)建一個(gè)文件,在merged目錄將能看到:
docker 存儲(chǔ)驅(qū)之overlayFS

關(guān)于init層:
init層是以一個(gè)uuid+-init結(jié)尾表示,夾在只讀層和讀寫(xiě)層之間,作用是專門(mén)存放/etc/hosts、/etc/resolv.conf等信息,需要這一層的原因是當(dāng)容器啟動(dòng)時(shí)候,這些本該屬于image層的文件或目錄,比如hostname,用戶需要修改,但是image層又不允許修改,所以啟動(dòng)時(shí)候通過(guò)單獨(dú)掛載一層init層,通過(guò)修改init層中的文件達(dá)到修改這些文件目的。而這些修改往往只讀當(dāng)前容器生效,而在docker commit提交為鏡像時(shí)候,并不會(huì)將init層提交。該層文件存放的目錄為/data/docker/overlay2/<init_id>/diff

網(wǎng)站欄目:docker存儲(chǔ)驅(qū)之overlayFS
鏈接分享:http://bm7419.com/article16/pcdjgg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站移動(dòng)網(wǎng)站建設(shè)、響應(yīng)式網(wǎng)站、App設(shè)計(jì)、企業(yè)建站定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)