近幾年 Docker 風(fēng)靡技術(shù)圈,不少從業(yè)人員都或多或少使用過,也了解如何通過 Dockerfile 構(gòu)建鏡像,從遠(yuǎn)程鏡像倉庫拉取自己所需鏡像,推送構(gòu)建好的鏡像至遠(yuǎn)程倉庫,根據(jù)鏡像運(yùn)行容器等。這個(gè)過程十分簡(jiǎn)單,只需執(zhí)行 docker build、docker pull、docker push、docker run 等操作即可。但大家是否想過鏡像在本地到底是如何存儲(chǔ)的?容器又是如何根據(jù)鏡像啟動(dòng)的?推送鏡像至遠(yuǎn)程鏡像倉庫時(shí),服務(wù)器又是如何存儲(chǔ)的呢?下面我們就來簡(jiǎn)單聊一聊。 Docker 鏡像不是一個(gè)單一的文件,而是有多層構(gòu)成。我們可通過 docker images 獲取本地的鏡像列表及對(duì)應(yīng)的元信息, 接著可通過docker history 查看某個(gè)鏡像各層內(nèi)容及對(duì)應(yīng)大小,每層對(duì)應(yīng)著 Dockerfile 中的一條指令。Docker 鏡像默認(rèn)存儲(chǔ)在 /var/lib/docker/中,可通過 DOCKER_OPTS 或者 docker daemon 運(yùn)行時(shí)指定 –graph= 或 -g 指定。 Docker 使用存儲(chǔ)驅(qū)動(dòng)來管理鏡像每層內(nèi)容及可讀寫的容器層,存儲(chǔ)驅(qū)動(dòng)有 devicemapper、aufs、overlay、overlay2、btrfs、zfs 等,不同的存儲(chǔ)驅(qū)動(dòng)實(shí)現(xiàn)方式有差異,鏡像組織形式可能也稍有不同,但都采用棧式存儲(chǔ),并采用 Copy-on-Write(CoW) 策略。且存儲(chǔ)驅(qū)動(dòng)采用熱插拔架構(gòu),可動(dòng)態(tài)調(diào)整。那么,存儲(chǔ)驅(qū)動(dòng)那么多,該如何選擇合適的呢?大致可從以下幾方面考慮: Docker 容器其實(shí)是在鏡像的最上層加了一層讀寫層,通常也稱為容器層。在運(yùn)行中的容器里做的所有改動(dòng),如寫新文件、修改已有文件、刪除文件等操作其實(shí)都寫到了容器層。容器層刪除了,最上層的讀寫層跟著也刪除了,改動(dòng)自然也丟失了。若要持久化這些改動(dòng),須通過 docker commit [repository[:tag]] 將當(dāng)前容器保存成為一個(gè)新鏡像。若想將數(shù)據(jù)持久化,或是多個(gè)容器間共享數(shù)據(jù),需將數(shù)據(jù)存儲(chǔ)在 Docker volume 中,并將 volume 掛載到相應(yīng)容器中。 存儲(chǔ)驅(qū)動(dòng)決定了鏡像及容器在文件系統(tǒng)中的存儲(chǔ)方式及組織形式,下面分別對(duì)常見的 aufs、overlay 作一簡(jiǎn)單介紹。 AUFS AUFS 簡(jiǎn)介 AUFS 是 Debian (Stretch 之前的版本,Stretch默認(rèn)采用 overlay2) 或 Ubuntu 系統(tǒng)上 Docker 的默認(rèn)存儲(chǔ)驅(qū)動(dòng),也是 Docker 所有存儲(chǔ)驅(qū)動(dòng)中最為成熟的。具有啟動(dòng)快,內(nèi)存、存儲(chǔ)使用高效等特點(diǎn)。如果使用的 Linux 內(nèi)核版本為 4.0 或更高,且使用的是 Docker CE,可考慮使用overlay2 (比 AUFS 性能更佳)。 配置 AUFS 存儲(chǔ)驅(qū)動(dòng) ① 驗(yàn)證內(nèi)核是否支持 AUFS $ grep aufs /proc/filesystems nodev aufs ② 若內(nèi)核支持,可在 docker 啟動(dòng)時(shí)通過指定參數(shù) –storage-driver=aufs 選擇 AUFS AUFS 存儲(chǔ)驅(qū)動(dòng)工作原理 采用 AUFS 存儲(chǔ)驅(qū)動(dòng)時(shí),有關(guān)鏡像和容器的所有層信息都存儲(chǔ)在/var/lib/docker/aufs/ 目錄下,下面有三個(gè)子目錄: 采用 AUFS 后容器如何讀寫文件? 讀文件 容器進(jìn)行讀文件操作有以下三種場(chǎng)景:
修改文件或目錄 容器中進(jìn)行文件的修改同樣存在三種場(chǎng)景:
OverlayFS OverlayFS 簡(jiǎn)介 OverlayFS 是一種類似 AUFS 的現(xiàn)代聯(lián)合文件系統(tǒng),但實(shí)現(xiàn)更簡(jiǎn)單,性能更優(yōu)。OverlayFS 嚴(yán)格說來是 Linux 內(nèi)核的一種文件系統(tǒng),對(duì)應(yīng)的 Docker 存儲(chǔ)驅(qū)動(dòng)為 overlay 或者 overlay2,overlay2 需 Linux 內(nèi)核 4.0 及以上,overlay 需內(nèi)核 3.18 及以上。且目前僅 Docker 社區(qū)版支持。條件許可的話,盡量使用 overlay2,與 overlay 相比,它的 inode 利用率更高。 容器如何使用 overlay/overlay2 讀寫文件 讀文件 讀文件存在以下三種場(chǎng)景:
修改文件或目錄 寫文件存在以下三種場(chǎng)景:
遠(yuǎn)程鏡像倉庫如何存儲(chǔ)鏡像? 不少人可能經(jīng)常使用 docker,那么有沒有思考過鏡像推送至遠(yuǎn)程鏡像倉庫,是如何保存的呢?Docker 客戶端是如何與遠(yuǎn)程鏡像倉庫交互的呢? 我們平時(shí)本地安裝的 docker 其實(shí)包含兩部分:docker client 與 docker engine,docker client 與 docker engine 間通過 API 進(jìn)行通信。Docker engine 提供的 API 大致有認(rèn)證、容器、鏡像、網(wǎng)絡(luò)、卷、swarm 等,具體調(diào)用形式請(qǐng)參考:Docker Engine API。 Docker engine 與 registry (即:遠(yuǎn)程鏡像倉庫)的通信也有一套完整的 API,大致包含 pull、push 鏡像所涉及的認(rèn)證、授權(quán)、鏡像存儲(chǔ)等相關(guān)流程,具體請(qǐng)參考:Registry API。目前常用 registry 版本為 v2,registry v2 擁有斷點(diǎn)續(xù)傳、并發(fā)拉取鏡像多層等特點(diǎn)。能并發(fā)拉取多層是因?yàn)殓R像的元信息與鏡像層數(shù)據(jù)分開存儲(chǔ),當(dāng) pull 一個(gè)鏡像時(shí),先進(jìn)行認(rèn)證獲取到 token 并授權(quán)通過,然后獲取鏡像的 manifest 文件,進(jìn)行 signature 校驗(yàn)。校驗(yàn)完成后,依據(jù) manifest 里的層信息并發(fā)拉取各層。其中 manifest 包含的信息有:倉庫名稱、tag、鏡像層 digest 等, 更多,請(qǐng)參考:manifest 格式文檔。 各層拉下來后,也會(huì)先在本地進(jìn)行校驗(yàn),校驗(yàn)算法采用 sha256。Push 過程則先將鏡像各層并發(fā)推至 registry,推送完成后,再將鏡像的 manifest 推至 registry。Registry 其實(shí)并不負(fù)責(zé)具體的存儲(chǔ)工作,具體存儲(chǔ)介質(zhì)根據(jù)使用方來定,registry 只是提供一套標(biāo)準(zhǔn)的存儲(chǔ)驅(qū)動(dòng)接口,具體存儲(chǔ)驅(qū)動(dòng)實(shí)現(xiàn)由使用方實(shí)現(xiàn)。 目前官方 registry 默認(rèn)提供的存儲(chǔ)驅(qū)動(dòng)包括:微軟 azure、Google gcs、Amazon s3、Openstack swift、阿里云 oss、本地存儲(chǔ)等。若需要使用自己的對(duì)象存儲(chǔ)服務(wù),則需要自行實(shí)現(xiàn) registry 存儲(chǔ)驅(qū)動(dòng)。網(wǎng)易云目前將鏡像存儲(chǔ)在自己的對(duì)象存儲(chǔ)服務(wù) nos 上,故專門針對(duì) nos 實(shí)現(xiàn)了一套存儲(chǔ)驅(qū)動(dòng),另外認(rèn)證服務(wù)也對(duì)接了網(wǎng)易云認(rèn)證服務(wù),并結(jié)合自身業(yè)務(wù)實(shí)現(xiàn)了一套認(rèn)證、授權(quán)邏輯,并有效地限制了倉庫配額。 |
|