欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

徹底搞懂Docker鏡像分層的實現(xiàn)

 更新時間:2022年02月21日 09:25:11   作者:postnull  
本文我們會深入的學習Docker的鏡像分層的原理和實現(xiàn),通過實例和與git的類比,幫助我們加深對鏡像的理解,對Docker鏡像分層相關知識感興趣的朋友一起看看吧

創(chuàng)建測試鏡像

我們創(chuàng)建一個最簡單的鏡像:

1.構建測試鏡像v1.0:docker build -t image_test:1.0 .

FROM alpine:3.15.0 #除了繼承基礎鏡像,啥也不做

2.構建測試鏡像v2.0:docker build -t image_test:2.0 .

FROM alpine:3.15.0
RUN dd if=/dev/zero of=file1 bs=10M count=1 #添加一個10M的文件file1

3.構建測試鏡像v3.0:docker build -t image_test:3.0 .

FROM alpine:3.15.0
RUN dd if=/dev/zero of=file1 bs=10M count=1 #添加一個10M的文件file1
RUN dd if=/dev/zero of=file2 bs=10M count=1 #添加一個10M的文件file2

這樣本地就構建了3個測試鏡像:

查看鏡像

我們有2種方法查看鏡像:

  1. 使用docker inspect:獲取鏡像的元數(shù)據(jù)
  2. 使用docker history:查看鏡像的構建歷史 使用docker inspect

使用docker inspect

查看鏡像的元數(shù)據(jù)。
其中Parent可以看到父鏡像, Layers這一項下面可以看到鏡像的所有層。

使用docker history

使用docker history可以看到鏡像的構建歷史。
我們每一行列出了鏡像包含的層。

使用docker history我們看到有一行很特別,就是鏡像ID為的行,這一行是什么呢?
看了 官方文檔 的描述,我們知道這些構建步驟要么是構建在另一個系統(tǒng),要么是鏡像的部分是從DockerHub上拉取下來的,要么是使用的是另一種構建工具BuildKit構建的。
很顯然,我們這里就是第二種情況,因為我們的Dockerfile中第一句指令就是FROM alpine:3.15.0.

鏡像分層圖

根據(jù)上面的docker history命令,我們可以輕松的畫出三個鏡像的分層圖:

從上面的圖可以看到,我們的鏡像是分層的,我們的Dockerfile中新增一條指令,就會新增一層!
如果我們將多個命令合成一個,那么也只會生成一層。修改一下上面的image_test:3.0,把兩條RUN合并成一條:

FROM alpine:3.15.0
RUN dd if=/dev/zero of=file1 bs=10M count=1 && \
    dd if=/dev/zero of=file2 bs=10M count=1

使用docker history 查看image_test:4.0,可以看到,只有2層了!

鏡像分層的好處

知道了鏡像是分層的,那么我們是不是好奇為啥要這么設計呢?
試想一下我們如果不分層會有什么問題?

以拉取鏡像為例!
拉取鏡像的鏡像很大,比如Redis的鏡像有100多M
第一次我們拉取6.2版本的Redis,下載了完成的100M到本地,下次我要下載6.2.6版本的,是不是又得下載100M。
盡管可能兩個版本之間就改了幾行配置文件。

這樣是非常低效的。如果能只下載有差異的部分就好了!

這個痛點,也就是鏡像分層要解決的問題。實際上,Docker也是這么實現(xiàn)的。
第一次下載redis:6.2時,因為之前沒有下載過,所以下載了所有的層,總共113M。網(wǎng)絡慢點的話還是需要花一些時間的!

第二次下載redis:7.0-rc,就變得快了很多!因為前面3層是redis:6.2是一樣的,這些層已經下載過了!

這種思想和我們常用的版本管理工具git也是一樣的!
如果版本2是基于版本1的基礎上,那么版本2不需要copy一份全量的數(shù)據(jù),只需一份和版本1差異化的增量數(shù)據(jù)即可!

這樣的最終好處是,可以體現(xiàn)在以下方面:

  • 拉取更快:因為分層了,只需拉取本地不存在的層即可!
  • 存儲更少:因為共同的層只需存儲一份即可!
  • 運行時存儲更少:容器運行時可以共享相同的層!

對于第3點,多個基于相同鏡像運行的容器,都可以直接使用相同的鏡像層,每個容器只需一個自己的可寫層即可:

鏡像分層的實現(xiàn)

前面說過,Docker鏡像分層和Git的版本很像!我們不妨以此類比!只是為了方便我們理解:

GitDocker
版本分層
在前一個版本的基礎上在前一層的基礎上
修改了代碼Dockerfile中加了RUN等指令
commit了修改,新增了一個版本新建一個鏡像層
新版本只包含差異新鏡像只包含了差異修改
已提交的commit是不能修改的舊的鏡像層是不能修改的

總而言之,鏡像層是只讀的,新的鏡像層是基于前一個鏡像層的修改,只保留了增量修改的部分!
使用了聯(lián)合文件系統(tǒng),對文件系統(tǒng)的修改作為一次提交來一層層的疊加!

容器本質上也是在鏡像的基礎上加了一層可寫層!這個在另外的章節(jié)再詳細討論!

Copy-on-write策略

Copy-on-write是一種提高文件共享和復制效率的策略。
如果一個文件和目錄在低一層的鏡像層中存在,并且其它層想要讀取這個文件,就直接使用這個文件。
如果其它層想要修改這個文件(不管是構建鏡像時,還是在容器運行的過程中),這個文件都會被先拷貝到新的一層中,然后再修改它。

這樣做的好處是可以大大減少每一層的大??!
更具體的實現(xiàn)請參考官方文檔中:Copy-on-write策略

到此這篇關于徹底搞懂Docker鏡像分層的文章就介紹到這了,更多相關Docker鏡像分層內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • docker(alpine+golang)?中?hosts?不生效問題解決方法

    docker(alpine+golang)?中?hosts?不生效問題解決方法

    這篇文章主要介紹了docker(alpine+golang)?中?hosts?不生效問題解決大全,本文給大家分享了三種解決方法,每種方法給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • docker容器狀態(tài)出現(xiàn)Exit(1)的問題及解決

    docker容器狀態(tài)出現(xiàn)Exit(1)的問題及解決

    這篇文章主要介紹了docker容器狀態(tài)出現(xiàn)Exit(1)的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • docker運行nginx綁定配置文件失敗原因以及問題解決

    docker運行nginx綁定配置文件失敗原因以及問題解決

    最近工作中在使用docker運行nginx的時候遇到了些問題,下面分享給大家,這篇文章主要給大家介紹了關于docker運行nginx綁定配置文件失敗原因以及問題解決的相關資料,需要的朋友可以參考下
    2023-02-02
  • 以示例講解Clickhouse Docker集群部署以及配置

    以示例講解Clickhouse Docker集群部署以及配置

    這篇文章主要介紹了Clickhouse Docker集群部署及配置,示例講解的非常詳細,希望可以幫助到有需要的小伙伴
    2021-08-08
  • 解決docker run中使用 ./ 相對路徑掛載文件或目錄失敗的問題

    解決docker run中使用 ./ 相對路徑掛載文件或目錄失敗的問題

    這篇文章主要介紹了解決docker run中使用‘./‘相對路徑掛載文件或目錄失敗的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • 修改已有docker容器中的內容方法

    修改已有docker容器中的內容方法

    這篇文章主要介紹了修改已有docker容器中的內容方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • Linux下docker安裝mysql8并配置遠程連接

    Linux下docker安裝mysql8并配置遠程連接

    本文主要介紹了Linux下docker安裝mysql8并配置遠程連接,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • 詳解如何在 docker 容器中捕獲信號

    詳解如何在 docker 容器中捕獲信號

    本篇文章主要介紹了如何在 docker 容器中捕獲信號,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 在Ubuntu上使用Grafana監(jiān)控Docker的方法

    在Ubuntu上使用Grafana監(jiān)控Docker的方法

    如今越來越多的公司開始使用Docker,一談起Docker總是會跟著讓人聯(lián)想到輕量這個詞,甚至會有一種通過Docker啟動一個服務會節(jié)省很多資源的錯覺。然而Docker的「輕」也只是相對于傳統(tǒng)虛擬機而已。Docker如何監(jiān)控呢?本文就給大家介紹在Ubuntu上如何使用Grafana監(jiān)控Docker。
    2016-12-12
  • Docker?compose啟動服務遇到的問題小結

    Docker?compose啟動服務遇到的問題小結

    這篇文章主要介紹了Docker?compose啟動服務遇到的問題小結,這個是檢驗我們的docker?compose掌握程度,因此里面的鏡像沒有提前拉取,掛載數(shù)據(jù)卷的目錄也沒有提前創(chuàng)建,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2023-11-11

最新評論