Docker鏡像淺談

先拋出幾個我在學習過程當中產生的幾個問題.git

1. 容器鏡像是什麼和裝系統時的鏡像有什麼關係?github

2. 容器鏡像的做用是什麼?docker

3. 不一樣版本的ubuntu鏡像有什麼區別好比說 ubuntu:18.04ubuntn:16.04 的區別?shell

4. Docker 鏡像爲何要分層 每層都包含什麼 何時會建立新的一層 ?  每層的權限是如何 配置的只有最底層的鏡像層是隻讀的嗎 ?
 

1 Docker鏡像之初見

1.1 什麼是鏡像

      使用docker pull <image name>下載一個鏡像看看ubuntu

 

      能夠看到咱們僅僅是pull了一個ubuntu18.04的鏡像, docker pull的結果卻出現了多行這是由於鏡像是分紅多層的具體爲何要分層每一層又是什麼下文咱們會談到.緩存

      因爲docker 18.04採用的是overlayfs2做爲默認的存儲驅動因此下載的鏡像都存儲在/var/lib/docker/overlay2 .學習

 

     能夠看到這裏的目錄個數和鏡像層數是一致而且除了0c開頭的那一層其餘目錄都是有diffwork兩個子目錄 . 0c開頭的目錄就是整個鏡像最底層的只讀層 ui

l目錄下所有都是指向這些diff目錄的軟連接.讓咱們進入0c.../diff中看看能夠看到在diff目錄中是一套完整的根目錄因此說本質上根目錄就是一個rootfs. this

跟裝系統時的鏡像沒有一點點關係.spa

 

1.2 構建Docker鏡像

     本節來講說如何使用使用Dockerfile構建本身的鏡像, dockfile由一系列的命令構成。我目前用過的有FROM RUN CMD ADD COPY命令。

     From用來制定一個基礎鏡像層。

     RUN命令會在一個新的鏡像層上執行參數中所指定的任何命令commit命令的執行結果。

     CMD命令在我初次使用時RUN有所混淆可是其實兩者是徹底不一樣的, CMD只是指定了運行容器時的初始命令可是在鏡像構建時沒有commit任何命令的結果。

舉例來講下圖是一個Dockerfile. 在其中咱們先在一個新的鏡像層建立一個shell腳本而後在CMD中運行這個腳本。

 

 

      能夠看到容器執行CMD中指定的命令.

2 鏡像的特性

2.1 分層特性

  在咱們使用docker run命令啓動一個容器時就會在現有的只讀鏡像層之上在建立一個可讀寫的容器層. 當咱們將這些容器刪除時這些容器層也會被刪除

可是容器層之下的鏡像層卻不會改變.

 圖盜自(docker reference)

 

 

經過這種共享相同的鏡像層的方式, 容器即實現了必定的隔離(容器層之間), 又節省了空間.

2.2 寫時拷貝(COW)

      若是容器須要讀底層的文件或者目錄那麼直接讀取底層的文件可是若是容器須要修改底層的文件那麼容器層就會拷貝一個底層的文件.

雖然說都是COW策略可是實現起來不一樣的存儲驅動也是有所不一樣的.

      以overlayfs/overlayfs2爲例:

    1. 搜索全部的鏡像層找到要修改的文件這個過程從最新的一層直到最底層另外搜索結果會放到緩存中加速下一次的查找。

    2. 執行copy_up操做將文件拷貝到容器層

    3. 修改文件的拷貝同時底層的文件對於容器層是不可見的.

      只說了修改和讀取那麼當容器層要刪除一個鏡像層的文件時會發生什麼呢讓咱們看看。

      先直接在底層鏡像層中建立一個文件還記得上文中說到的那個只有diff目錄和link文件的目錄嗎?那個就是最底層的鏡像層

咱們直接在diff/tmp/目錄中建立一個文件文件名爲thisIsAFileCreateImageLayer

      而後運行一個容器進入tmp目錄能夠看到這個文件對於容器是可見的.

     在容器層刪除該文件

 

     在鏡像層看看

 

       由上圖能夠看到在鏡像層該文件是依然存在的這是由於在容器層在容器層刪除文件或者目錄

, overlayfs採用了whiteoutsopaque技術.

      Whiteouts是一個設備號爲0/0的字符設備文件當上層目錄中發現一個whiteout文件時在上層目錄中讀取底層的同名的文件時底層的文件就會被忽略.

以下圖所示在新建立的容器層中咱們能夠看到一個設備號爲0,0的字符設備文件.

 

接下來我來嘗試解答一下我以前的疑問:

其實前兩個問題已經獲得瞭解答, 先說說第三個問題

3. 不一樣版本的ubuntu鏡像有什麼區別好比說 ubuntu:18.04ubuntn:16.04  的區別?

     不一樣版本的ubuntu的區別我目前知道的區別是軟件庫的版本不一樣. 

4. Docker 鏡像爲何要分層 每層都包含什麼 何時會建立新的一層 ?  每層的權限是如何 配置的只有最底層的鏡像層是隻讀的嗎 ?
     分層實現了空間最小化的隔離, 在運行一個新的容器時會建立一個新的讀寫層, 在使用Dockerfile構建新的鏡像時會在已有的鏡像層的基礎上建立新的一層.
 

參考

https://docs.docker.com/storage/storagedriver/   //關於docker存儲驅動很好的講解
https://docs.docker.com/engine/reference/builder/#from //關於Dockerfile很好的資料
相關文章
相關標籤/搜索