elasticsearch入門系列">elasticsearch入門系列
742
2022-05-30
文章目錄
一、鏡像分層與容器層
二、為什么會產生分層?
三、什么是寫時復制?
一、鏡像分層與容器層
在進行docker pull 下載鏡像的時候,通過下面的腳本運行過程可以看到鏡像是分層下載并解壓的。如nginx:1.20.2的鏡像,其鏡像是分為6層。下文中以<一串數字>:Pull Complete表示完成一個鏡像層的下載和解壓,一共是6個分層。
# docker pull nginx:1.20.2 1.20.2: Pulling from library/nginx c229119241af: Already exists 2906ff8f593b: Pull complete 605202120923: Pull complete b0013ba53a96: Pull complete f2e7470d98f2: Pull complete 8da6a894027c: Pull complete
1
2
3
4
5
6
7
8
當我們運行一個新的容器的時候,實際上是在鏡像分層的基礎上新添加了一層:container layer(容器層)。之后所有容器運行時對文件系統產生的修改實際都只影響這一層。并且針對這一層所作的修改(寫操作),在容器重啟之后會全部丟失。所以說在使用docker的過程中,在需要修改運行時容器文件數據的時候,盡量去重新構建鏡像而不是直接修改容器內文件。如果重構鏡像解決不了的問題,使用數據卷。
構建鏡像的方法是通過Dockerfile定義,數據卷的使用詳解,專欄后續文章筆者會詳細介紹。
注意 :對于運行時的容器而言,鏡像層只讀的,容器層可讀也可寫。對于鏡像層的只讀文件,容器層如果想做修改,實際上是進行了寫時復制操作。(下文介紹)。
二、為什么會產生分層?
通過上文的介紹,我們已經知道鏡像是分層的,那么鏡像分層的依據是什么?或者說構建鏡像的時候究竟是什么動作產生了分層?我們來看下面的這張圖,使用docker history查看鏡像的構建歷史。
注意上圖中紅色邊框的部分,我們可以看到:在進行ADD、COPY、執行shell腳本等操作的時候操作步驟對應的SIZE不等于0,正好是6個操作,和我們上文中nginx:1.20.2鏡像分層的數量是一樣的。所以我們可以做一個大膽的猜想:在鏡像構建過程中需要向鏡像寫入數據的時候會產生分層,一個寫操作指令產生一個分層。 大家可以自己去觀察更多的鏡像去驗證這個猜想。筆者要說的是:我讀過Dokcer的源碼,所以這是一個可以被信任的結論。
FROM debian:bullseye-slim #寫指令 LABEL maintainer="NGINX Docker Maintainers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
上面的這段代碼是nginx:1.20.2的Dockerfile(鏡像構建過程定義文檔),也就是構建nginx:1.20.2鏡像的構建步驟定義文檔(官方)。其中FROM(ADD)指令–添加基礎鏡像或文件、RUN指令–執行命令行腳本、COPY指令–文件復制,這些都是寫操作命令,都會產生新的鏡像分層。
三、什么是寫時復制?
上文中我們提到了一個概念:寫時復制。這個概念如果用專業名詞的方式說明還是比較難以理解,所以我用白話的方式說明一下。舉個例子:
一個授課老師寫了一本練習冊(原始鏡像)。
然后老師留作業了,練習冊第12頁。全班同學把練習冊的第12頁全都復印了一份,帶回家做作業。
老師的練習冊是原始文稿(正本)(原始文稿構建之后就只讀不寫,鏡像層文件也是),同學們的練習冊是在需要使用到的時候復印出來的,并在復印本(副本)上完成作業書寫,不影響原來老師那本練習冊(正本)的內容。這個就是典型的“寫時復制”。
對于容器而言,復制出來的文件在面向容器內的運行時軟件時,會覆蓋原始鏡像文件(對于學生而言也只看自己復制出來那份–不要抬杠:抄作業的除外,不看老師的原始文件)。也就是說發生寫時復制之后原始鏡像文件被隱藏,容器讀寫操作都只認復制出來的副本文件。注意:該副本文件存在于容器層,容器重啟之后容器層重新建立,上一次容器運行時對于文件的修改全部丟失!
Docker 容器 鏡像服務
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。