Docker 容器為什麼傲嬌?全靠映象撐腰!

作者 | 飛向星的客機

來源 | CSDN部落格

🌟 前言

Docker 映象是 Docker 容器的基石,容器是映象的運行實例,有了映象才能啟動容器。

Docker 映象是一個只讀的模板,一個獨立的檔案系統,包括運行一個容器所需的資料,可以用來創建容器。

base映象

base(基礎) 映象是指完全從零開始構建的映象, 它不會依賴其他映象,甚至會成為被依賴的映象,其他映象以它為基礎進行擴展。

通常 base 映象都是 Linux 的系統映象, 如 Ubuntu、CentOS、Debian 等。

下面通過 Docker 拉取一個 base 映象並查看, 這裡以 CentOS 為例, 示例程式碼如下:

從以上示例中可以看出,一個 CentOS 映象大小只有 202MB,但在安裝系統時,一個 CentOS 大概有幾 GB,這與作業系統有關。

先觀察 Linux 原本的作業系統結構,如圖所示👇

先觀察 Linux 原本的作業系統結構,如圖所示

Kernel 是核心空間。bootfs 檔案系統在 Linux 啟動時載入。rootfs 是包含操作命令的檔案系統。

base 映象的創建過程中,Kernel、 bootfs 與 rootfs 都會載入,然後 bootfs 檔案系統 (包括 Kernel) 被卸載掉,映象只保留 rootfs 檔案系統,供使用者進行操作。bootfs 與 Kernel 將與宿主機共享。

另外,為了增加 Docker 的靈活性,base 映象提供的都是最小安裝的 Linux 系統。

Linux 系統不同的發行版之間最大的區別就是 rootfs 的不同,例如,Ubuntu 系統的應用程序管理器是 apt,而 CentOS 是 yum。

由此可見,只要提供不同的 rootfs 檔案系統就可以同時支持多種作業系統,如圖所示👇

由此可見,只要提供不同的 rootfs 檔案系統就可以同時支持多種作業系統,如圖所示

從上圖中可以看到,兩個不同的 Linux 發行版提供了各自的 rootfs 檔案系統,而它們共用的是底層宿主機的 Kernel。

假設宿主機的系統是 Ubuntu 16.04,Kernel 版本是 4.4.0,無論 base 映象原本的發行版 Kernel 版本如何,在這臺宿主機上都是 4.4.0。

下面通過示例來驗證,示例程式碼如下:

從上述示例中可以看出,base 映象與宿主機的 Kernel 版本都是 3.10。

base 映象的 Kernel 是與宿主機共享的,其版本與宿主機一致,並且不能進行修改。

映象的本質

Docker 映象是一個只讀的檔案系統,由一層一層的檔案系統組成,每一層僅映象的本質包含前一層的差異部分,這種層級檔案系統被稱為 UnionFS。

大多數 Docker 映象都在 base 映象的基礎上進行創建,每進行一次新的創建就會在映象上構建一個新的 UnionFS。

查看 ubuntu:15.04 映象的層級結構,示例程式碼如下:

通常,對 Docker 的操作命令都是以 「docker」 開頭。pull 是下載映象的命令,在英文中是 「拉」 的意思,所以下載映象又叫作 拉取映象。

以上示例中,第 5 行到第 8 行是每一層 UnionFS 的 ID 號,第 9 行是整個映象的 ID 號,這個 ID 號可以用來操控映象。

然後,查看映象,示例程式碼如下:

然後,查看映象,示例程式碼如下

在以上示例中,不僅可以看到先前下載的 Ubuntu15.04 映象,還可以看到其他映象,說明 docker images 是查看本地所有映象的命令。而查看到的資訊中,除了映象名稱,還有版本號、映象 ID 號、創建時間以及映象大小。

接著,通過命令查看映象的構建過程,示例程式碼如下:

這裡使用 「history」 與映象 ID 號組合的命令查看映象構建過程,所顯示的資訊包括映象 ID 號、創建時間、由什麼命令創建以及映象大小。

從以上示例中的資訊可以看出,ubuntu:15.04 映象由四個只讀層 (Read Layer) 構建而成,每一層都是由一條命令構成的,最終得到 ID 號為 dlb55fd07600 的映象,但以使用者的視角只能看到最上層。

當使用者將這個映象放在容器中運行時,四層之上會創建出一個可讀可寫層(Read-Write Layer),使用者對 Docker 的操作都通過可讀可寫層進行。如果使用者修改了一個已存在的檔案,那該檔案將會從可讀可寫層下的只讀層複製到可讀可寫層,該檔案的只讀版本仍然存在,只是已經被可讀可寫層中該檔案的副本所隱藏。

可讀可寫層又叫作容器層,只讀層又叫作映象層,容器層之下均為映象層,層級結構如圖所示👇

可讀可寫層又叫作容器層,只讀層又叫作映象層,容器層之下均為映象層,層級結構如圖所示

映象的這種分層機制最大的一個好處就是:共享資源。

例如,有很多個映象都基於一個基礎映象構建而來,那麼在本地的倉庫中就只需要保存一份基礎映象,所有需要此基礎映象的容器都可以共享它,而且映象的每一層都可以被共享,從而節省磁碟空間。

因為有了分層機制,本地保存的基礎映象都是隻讀的檔案系統,不用擔心對容器的操作會對映象有什麼影響。

為了將零星的資料整合起來,人們提出了映象層 (Image Layer) 這個概念,如圖所示👇

下圖所示為一個映象層,我們能夠發現,一個層並不僅僅包含檔案系統的改變,它還能包含其他重要的資訊。

元資料 (Metadata) 就是關於這個層的額外資訊,包括 Docker 運行時的資訊與父映象層的資訊,並且只讀層與可讀可寫層都包含元資料,如圖所示👇

元資料 (Metadata) 就是關於這個層的額外資訊,包括 Docker 運行時的資訊與父映象層的

除此之外,每一層還有一個指向父映象層的指針。如果沒有這個指針,說明它處於最底層,是一個基礎映象,如圖所示👇

除此之外,每一層還有一個指向父映象層的指針如果沒有這個指針,說明它處於最底層,是一個基礎映象,如圖所

查找本地映象

Docker 本地映象通常是儲存在伺服器上的,下面驗證本地映象的儲存路徑,示例程式碼如下:

從以上示例中可以看到,Docker 本地映象儲存路徑是 /var/Iib/Docker。

在本地查看映象時,通常使用 docker images 命令,示例程式碼如下:

從以上示例中可以看到,結果顯示中有多項映象資訊,下面對資訊進行解釋。

🍇 REPOSITORY

映象倉庫,即一些關聯映象的集合。

例如,Ubuntu 的每個映象對應著不同的版本。與 Docker Registry 不同,映象倉庫提供 Docker 映象的儲存服務。

即 Docker Registry 中有很多映象倉庫,映象倉庫中有很多映象 (相互獨立)。

🍇 TAG

映象的標籤,常用來區分不同的版本,默認標籤為 latest。

🍇 IMAGE ID

映象的ID號,映象的唯一標識,常用於操作映象 (預設值只列出前 12 位)。

🍇 CREATED

映象創建的時間。

🍇 SIZE

映象的大小。

🍇 參數用法

在 docker images 命令後加上不同的參數就形成了不同的查詢方式,導致不同的查詢結果。

下面介紹各參數的含義以及用法。

  • -a

表示顯示所有本地映象,默認不顯示中間層映象,這是工作中經常使用到的參數,用來從本地映象中尋找符合生產條件的映象。

示例程式碼如下:

示例程式碼如下
  • -q

表示只顯示本地所有映象 ID 號。

示例程式碼如下:

  • -no-trunc

表示使用不截斷的模式顯示,並顯示完整的映象 ID 號。

示例程式碼如下:

示例程式碼如下

構建映象

Docker 的官方映象庫 Docker Hub 發佈了成千上萬的公共映象供全球使用者使用。使用者可以直接拉取(下載)所需要的映象,提高了工作效率。但是在很多工作環境中,一旦對映象有特殊需求,就需要我們手動去構建映象。

本文章將會介紹基於 docker commit 命令與 Dockerfile 兩種方式來構建自己的 Docker 映象。

🍑 使用 docker commit 命令構建映象

使用 docker commit 命令將容器的可讀可寫層轉換為一個只讀層,這樣就把一個容器轉換成了一個不可變的映象,如圖所示👇

使用 docker commit 命令將容器的可讀可寫層轉換為一個只讀層,這樣就把一個容器轉換成了一

下面我們給一個 Centos 的映象安裝一個 Vim 服務,設置開機啟動,並將其構建成一個新的映象,以免每次啟動容器都要再次安裝 Vim。

首先啟動一個 Centos 的容器,示例程式碼如下:

從以上示例中可以看到,容器啟動之後,主機名發生了改變,說明使用者直接進入了容器,再進行操作就是對容器的操作。

然後,在容器中安裝 Vim,示例程式碼如下:

安裝完成之後,退出容器,示例程式碼如下

安裝完成之後,退出容器,示例程式碼如下:

使用 exit 命令退出容器之後, 該容器將默認關閉。

下面使用 docker commit 命令在 CentOS 映象的基礎上創建新的映象,示例程式碼如下:

在命令中需要用映象 ID 號來指定基礎映象,並不需要將 ID 號都輸入進去,只要輸入幾個字符使 ID 號與其他映象不衝突即可。

此時可以看到剛剛構建的新映象,程式碼如下:

此時可以看到剛剛構建的新映象,程式碼如下

從以上示例中可以看到, 新映象的大小是 326MB,而此前的 CentOS 映象只有 202MB, 這是因為在安裝 Vim 時還安裝了許多依賴包。

然後, 查看映象中是否已經自動安裝了 Vim, 示例程式碼如下:

從以上示例中可以看到,新映象已經包含了 Vim。

這種構建新映象的方式在工作中並不常見,原因如下。

(1)效率低下,如果要給 Ubuntu 映象也添加一個Vim,需要將上述全部過程重複一遍。

(2)不透明,使用者使用時不知道映象是如何構建的,難以對映象做出正確的判斷。

🍑 使用 Dockerfile 構建映象

映象可以基於 Dockerfile 構建。Dockerfile 是一個描述檔案,包含若干條命令,每條命令都會為基礎檔案系統創建新的層次結構,這正好彌補了 docker commit 構建映象效率低下的缺點。

Dockerfile 定義容器內部環境中發生的事情。網路接口和磁碟驅動器等資源的訪問在此環境內虛擬化,與系統的其餘部分隔離。

Dockerfile 主要使用 docker build 命令,根據 Dockerfile 檔案中的指令,執行若干次 docker commit 命令構建映象,每次執行 docker commit 命令時都會生成一個新的層,因此許多新的層會被創建,如圖所示👇

🍑 Dockerfile常用命令

下面介紹 Dockerfile 中常用的命令,完整說明見官方文件。

  • FROM

指定源映象,必須是已經存在的映象,必須是Dockerfile中第一條非註釋的命令,因為其後的所有指令都使用該映象。

  • MAINTAINER

指定作者資訊。

  • RUN

在當前容器中運行指定的命令。

  • EXPOSE

指定運行容器時要使用的埠。可以使用多個EXPOSE命令。

  • CMD

指定容器啟動時運行的命令,Dockerfile 可以出現多個 CMD 指令,但只有最後一個生效。CMD 可以被啟動容器時添加的命令覆蓋。

  • ENTRYPOINT

CMD 或容器啟動時添加的命令會被當做參數傳遞給 ENTRYPOINT。

  • COPY

檔案或目錄複製到當前容器中。

  • ADD

將檔案或者目錄複製到當前容器中,源檔案如果是歸檔(壓縮)檔案,則會被自動解壓到目標位置。

  • VOLUME

為容器添加容器卷,可以存在於一個或多個目錄,用來提供共享儲存。該命令會在容器資料卷部分詳細介紹。

  • WORKDIR

在容器內設置工作目錄。

  • ENV

設置環境變數。

  • USER

指定容器以什麼使用者身份運行,默認是 root。

🍑 運行一個Dockerfile

下面演示使用 Docker file 創建 centos/vim,示例程式碼如下:

這裡在宿主機的 root 目錄下創建了一個 Dockerfile 檔案。

接著,向 Docker file 檔案中添加內容, 示例程式碼如下:

添加完成之後,保存並退出。

有了 Dockerfile 檔案之後即可創建新的映象,示例程式碼如下:

通過 docker build 命令執行 Dockerfile 檔案,-t 用來指定新映象名為 centos/vim-Dockerfile,命令列末尾的 . 表示 Dockerfile 檔案在當前目錄,Docker 默認從指定的目錄尋找 Dockerfile 檔案,也可以使用 -f 參數指定 Dockerfile 檔案的位置。

構建完成之後,查看映象是否構建成功,示例程式碼如下:

從以上示例中可以看到,新映象已經構建成功

從以上示例中可以看到,新映象已經構建成功。

使用 Dockerfile 構建映象基本可以分為以下五步。

(1) 選擇一個基礎映象,運行一個臨時容器。

(2) 執行一條命令,對容器做修改。

(3) 執行類似 docker commit 的操作,生成一個新的映象。

(4) 刪除臨時容器,再基於剛剛構建好的新映象運行一個臨時容器。

(5) 重複 (2) (3) (4) 步,直到執行完 Dockerfile 中的所有指令。

centos/vim-Dockerfile 由 CentOS 基礎映象和 RUN yum -y install vim 構成,現在兩個映象都包含了 ID 號為 lel148e4cc2c 的只讀層,如圖所示👇

centos/vim-Dockerfile 由 CentOS 基礎映象和 RUN yum -y in

以上結論可以使用 docker history 命令驗證,docker history 命令專門用來查看映象的結構,示例程式碼如下:

這裡可以看到 CentOS 映象中確實包含了 ID 號為 1e1148e4cc2c 的只讀層。

接著再查看新映象 centos/vim-Dockerfile 的結構,示例程式碼如下:

從以上示例中可以看到,兩個映象都含有一個相同的只讀層,並且這個只讀層是共享的。

Docker 構建映象時有快取機制,如果構建映象層時該映象層已經存在,就直接使用,無須重新構建。

下面為先前的 Dockerfile 檔案添加一點內容,安裝一個 ntp 服務,重新構建一個新的映象,示例程式碼如下:

這裡多加了一條安裝 ntp 服務的命令。

添加完成後,開始創建映象,示例程式碼如下:

添加完成後,開始創建映象,示例程式碼如下

在示例的第 6 行程式碼中可以看到,Docker 沒有重新安裝 Vim,而是直接使用了先前安裝過的快取。

Dockerfile 檔案是從上至下依次執行的,上層依賴於下層。無論什麼時候,只要某一層發生變化,其上面所有層的快取都會失效。

改變先前的 Dockerfile 檔案中兩條 RUN 命令的上下順序,觀察 Docker 還會不會使用快取機制,示例程式碼如下:

將 Dockerfile 中兩條 RUN 命令的順序互換之後,開始創建映象,示例程式碼如下:

由以上驗證可知,將兩條 RUN 命令交換順序導致映象層次發生改變,Docker 會重建映象層。由此可見 Docker 的映象層級結構特性:只有下面的層次內容、順序完全一致才會使用快取機制。

如果在構建映象時不想使用快取,可以在 docker build 命令中添加 –no-cache 參數,否則默認使用快取。

除了在使用 Dockerfile 構建映象時有快取機制,在從倉庫拉取映象時也會有快取機制,即已經拉取到本地的映象層可以被多個映象共同使用,可以說是一次拉取多次使用,前提是下層映象完全相同。

通常使用 Dockerfile 構建映象時,如果由於某些原因映象構建失敗,我們能夠得到前一個指令成功執行構建出的映象,繼而可以運行這個映象查找指令失敗的原因,這對調試 Dockerfile 有極大的幫助。

從 Docker Hub 拉取的 CentOS 映象是最小化的,其中沒有 vim 命令。下面測試錯誤構建 Docker 映象的結果,示例程式碼如下:

將 Dockerfile 中任意一條 RUN 命令改為錯誤的,再開始創建映象,示例程式碼如下:

在示例中,由於第三步報錯,映象沒有創建成功。但也生成了一個新映象,這個映象是第二步操作構建的,通常可以通過這個新映象排查錯誤,示例程式碼如下:

Docker 容器技術中,編寫 Dockerfile 檔案是非常重要的部分,下面總結編寫 Dockerfile 檔案的一些小技巧,相信可以幫助大家更好地使用 Docker 與 Dockerfile。

(1)容器中只運行單個應用。

從技術角度講,在一個容器中可以實現整個 LNMP (Linux+Nginx+MySQL+PHP) 架構。但這樣做有很大的弊端。首先,映象構建的時間會非常長,每次修改都要重新構建;

其次,映象檔案會非常大,大大降低容器的靈活性。

(2)將多個 RUN 指令合併成一個。

眾所周知,Docker 映象是分層的,Dockerfile 中的每一條指令都會創建一個新的映象層,映象層是隻讀的。

Docker映象層類似於洋蔥,想要更改內層,需要將外層全部撕掉。

(3)基礎映象的標籤儘量不要使用 latest。

當映象的標籤沒有指定時,默認使用 latest 標籤。

當映象更新時,latest 標籤會指向不同的映象,可能會對服務產生影響。

(4)執行 RUN 命令後刪除多餘檔案。

假設執行了更新 yum 源的命令,會自動下載解壓一些軟體包,但是在運行容器的時候不需要這些包。最好將它們刪除,因為這些軟體包會使映象 SIZE 變大。

(5)合理調整 COPY 與 RUN 的順序。

將變化少的部分放在 Dockerfile 檔案的前面,充分利用映象快取機制。

(6)選擇合適的基礎映象。

最好選擇滿足環境需要而且體積小巧的映象,比如 Alpine 版本的 node 映象。

Alpine 是一個極小化的 Linux 發行版,只有 5.5MB,非常適合作為基礎映象。

Docker Hub

🍑 docker search 命令

Docker Hub 上有許多映象, 但並不都是 Docker 官方人員製作的, 一些映象是由 Docker 使用者上傳並維護的。工作中可以通過 docker search 命令從映象倉庫中查找所需要的映象。

示例程式碼如下:

以上示例中,查找的是與 CentOS 有關的映象,Docker Hub 中有關 CentOS 的映象遠不止這些,這裡顯示的只是其中一部分。

下面對映象的每項資訊進行講解。

  • NDEX

映象索引,這裡代表映象倉庫。

  • NAME

映象名稱。

  • DESCRIPTION

關於映象的描述,使使用者可以有方向性地選擇映象。

  • STARS

映象的星標數,反映 Docker 使用者對映象的收藏情況,值越高代表使用的使用者越多。

  • OFFICIAL

有此標記的都是 Docker 官方維護的映象,沒有此標記的通常是使用者上傳的映象。

  • AUTOMATED

用來區分是否為自動化構建的映象,有此標記的為自動化構建的映象,否則不是。

🍑 docker search 參數運用

給 docker search 命令添加不同的參數,就會得到不同的查詢結果,下面對各參數進行解釋。

  • –automated

表示只列出自動化構建的映象,示例程式碼如下:

  • –no-trunc

表示顯示完整的映象描述,示例程式碼如下:

  • -s

表示列出星標數不小於指定值的映象,需要在參數後添加指定值,示例程式碼如下:

🍑 映象推送

使用者向 Docker Hub 推送映象需要有一個 Docker Hub 賬號。在 Docker 客戶端使用 docker login 命令登入 Docker Hub 賬號,如圖所示👇

下面使用 docker push 命令向 Docker Hub 推送映象,示例程式碼如下:

這裡第 6 行出現了報錯,映象沒有推送成功,報錯資訊顯示請求資源被拒絕。這是因為 DockerHub 上的映象都有一個 tag 標籤,使用者上傳映象時需要給映象添加 tag 標籤。

下面使用 docker tag 命令給映象添加 tag 標籤,示例程式碼如下:

tag 標籤添加完之後,再查看一遍映象,確保準確無誤,示例程式碼如下:

可以看到,先前的映象並沒有發生改變,Docker 只是在它的基礎上又創建了一個新映象。與先前的映象相比,新映象只是修改了名字,映象大小不變。

有了新映象就可以將其推送給 Docker Hub 了,示例程式碼如下:

映象推送完成之後, 可以登入 Docker Hub 查看, 驗證映象是否推送成功, 如圖所示👇

從上圖可以看出,映象已經推送成功,這個映象在 Docker Hub 上可以供所有使用者下載並使用。

嘗試拉取先前推送的映象,示例程式碼如下:

映象拉取完成後,查看是否拉取成功,示例程式碼如下:

從以上示例中可以看出,已經成功拉取了先前推送的映象,拉取的映象與本地的映象相比,ID 號和映象大小都是相同的。這就體現出了 DockerHub 官方映象庫的方便之處,使用者可以將映象上傳到雲端,做到隨用隨取,也可以將自己優秀的映象與廣大開源愛好者共享。

Docker Hub 在給使用者帶來便利的同時,也暴露出了極大的安全問題。任何 Docker 使用者都可以隨時隨地上傳映象到 Docker Hub,將其推送給其他 Docker 使用者,任何使用者都可以拉取使用這些映象,但誰都無法辨別所下載的映象是否包含惡意資訊。

2018 年發生了一起安全事故,一名 Docker 使用者上傳了 17 個帶有惡意軟體的映象,攻擊者利用這些惡意 Docker 映象在受害者的計算機上安裝基於 XMRig 的門羅幣挖礦軟體。其中一些映象已經安裝超過一百萬次,還有一些則被使用了數十萬次。Docker 官方網站維護人員調查確認後刪除了這些惡意映象,風波才得以平息。

在使用 Docker 映象時要先在測試環境中安裝運行,最安全的方法是儘可能使用自制的 Docker 映象或使用經過驗證的映象。

Docker映象最佳化

Docker 映象採用的是層級結構,一個映象最多擁有 127 層 UnionFS。每條 Dockerfile 命令都會創建一個映象層,增加映象大小。在生產環境中使用 Docker 容器時,要儘可能地精簡 Docker 映象,減少 UnionFS 的層數。

精簡映象不僅能縮短新映象的構建時間,還能減少磁碟用量。由於精簡後的映象更小,使用者在拉取映象時能節省時間,部署服務的效率也能得到提升。精簡映象包含的檔案更少,更加不容易被攻擊,提高了映象的安全性。

🍑 base映象最佳化

base 映象最佳化就是在滿足環境要求的前提下使用最小的 base 映象。常用的 Linux base 映象有 CentOS、Ubuntu、Alpine 等,其中一些比較小的 base 映象適合作為精簡映象的基礎映象,如 Alpine、BusyBox 等。

下面分別拉取 Alpine 與 BusyBox 的映象進行對比,示例程式碼如下:

Scratch 是一個空映象,只能用於構建其他映象,常用於執行一些包含了所有依賴的二進位制檔案。如果以 Scratch 為 base 映象,意味著不以任何映象為基礎,下面的指令將作為映象的第一層存在。

BusyBox 相對於 Scratch 多了一些常用的 Linux 命令,BusyBox 的官方映象大小只有 1MB 多一點,非常適合構建小映象。

Alpine 是一款高度精簡又包含了基本工具的輕量級 Linux 發行版,官方 base 映象只有 5MB 多一點,很適合當作 base 映象使用。

🍑 Dockerfile 最佳化

使用者在定義 Dockerfile 檔案時,使用太多的 RUN 命令,會導致映象非常靡腫,甚至超出可構建的最大層數。根據最佳化原則,應該將多條 RUN 命令合併為一條命令,精心設計每一個 RUN 命令,減小映象體積,並且精心編排,最大化地利用快取。

下面創建一個 Dockerfile 檔案,示例程式碼如下:

接著, 使用這個 Dockerfile 構建一個新的映象, 示例程式碼如下:

從以上示例中可以看到,整個映象構建的過程是十分煩瑣的。

查看新映象的大小與 UnionFS 的層數,示例程式碼如下:

從以上示例中可以看到,新映象 centos/vim-bulky 的大小是 509MB,而映象的 UnionFS 層數是 8 層。

這樣編寫 Dockerfile 導致新映象非常龐大,既增加了構建部署的時間,也很容易出錯。

下面對 Dockerfile 進行最佳化,示例程式碼如下:

在Dockerfile中使用 「&」 與 ‘’**” 將多條命令合成一條,”&&」 表示命令還沒有結束,‘’**”表示換行。

下面通過最佳化過的 Dockerfile 構建新映象,示例程式碼如下:

從以上示例可以看出,最佳化後的 Dockerfile 構建映象的過程比最佳化前精簡了一些。

查看並對比兩個新映象,示例程式碼如下:

查看並對比兩個新映象,示例程式碼如下

從以上示例中可以看到,映象 centos/vim-portable 只有 305MB,比映象 centos/vim-bulky 節省了 204MB 的資源,甚至比源映象 centos/vim 還小了 21MB。

接著,查看映象 centos/vim-portable 的 UnionFS 層數,示例程式碼如下:

從以上示例中可以看到,映象 centos/vim-portable 的 UnionFS 只有 6 層,而先前的映象 centos/vim-bulky 有 8 層 UnionFS。

🍑 清理無用的檔案

在 RUN 命令中使用 yum、apt、apk 等工具時,可以藉助這些工具自帶的參數進行最佳化。如執行 apt-get install-y 時添加 –no-install-recommends 選項,就可以不安裝建議性的依賴包,這些依賴包都是不必要的。

元件的安裝和清理要放置在同一條命令裡面,因為 Dockerfile 的每條命令都會產生一個新的映象層,在執行下一條命令時,上一條命令所產生的映象層已經為只讀層,不可修改。Ubuntu 或 Debian 系統使用 rm -rf/var/lib/apt/lists/* 清理映象中的快取檔案,CentOS 等系統使用 yum clean all 命令清理。

Docker 社區中還有許多最佳化映象的工具,如壓縮映象的工具 Docker-squash,用起來簡單方便。

本章小結

本章介紹了 Docker 映象的構成,採用了層級結構,層層遞進;

然後介紹了映象的倉庫,包括官方公有倉庫 Docker Hub 和 私有倉庫;

最後詳細講解了如何構建 Docker 映象,並對 Dockerfile 檔案進行了簡單的最佳化。

相信大家通過本章的學習,已經掌握了映象的原理以及操作方式。

相關文章

最強 AI ChatGPT 真要取代程式設計師?

最強 AI ChatGPT 真要取代程式設計師?

【CSDN 編者按】ChatGPT 一出,「程式設計師要失業了」、「程式設計師要下崗了」之聲不絕於耳,引得程式設計師們不由得一陣驚慌,最強 ...