1. 程式人生 > 實用技巧 >Dockerfile 常用的指令以及Docker映象實現原理

Dockerfile 常用的指令以及Docker映象實現原理

映象操作

映象是一個只讀的 Docker 容器模板,包含啟動容器所需要的所有檔案系統結構和內容。簡單來講,映象是一個特殊的檔案系統,它提供了容器執行時所需的程式、軟體庫、資源、配置等靜態資料。即映象不包含任何動態資料,映象內容在構建後不會被改變。

Dockerfile指令

看了這麼多指令,感覺有點懵?別擔心,我通過一個例項讓你來熟悉它們。這是一個 Dockerfile:

FROM centos:7
COPY nginx.repo /etc/yum.repos.d/nginx.repo
RUN yum install -y nginx
EXPOSE 80
ENV HOST=mynginx
CMD ["nginx","-g","daemon off;"]

好,我來逐行分析一下上述的 Dockerfile。

  • 第一行表示我要基於 centos:7 這個映象來構建自定義映象。這裡需要注意,每個 Dockerfile 的第一行除了註釋都必須以 FROM 開頭。
  • 第二行表示拷貝本地檔案 nginx.repo 檔案到容器內的 /etc/yum.repos.d 目錄下。這裡拷貝 nginx.repo 檔案是為了新增 nginx 的安裝源。
  • 第三行表示在容器內執行yum install -y nginx命令,安裝 nginx 服務到容器內,執行完第三行命令,容器內的 nginx 已經安裝完成。
  • 第四行宣告容器內業務(nginx)使用 80 埠對外提供服務。
  • 第五行定義容器啟動時的環境變數 HOST=mynginx,容器啟動後可以獲取到環境變數 HOST 的值為 mynginx。
  • 第六行定義容器的啟動命令,命令格式為 json 陣列。這裡設定了容器的啟動命令為 nginx ,並且添加了 nginx 的啟動引數 -g 'daemon off;' ,使得 nginx 以前臺的方式啟動。

上面這個 Dockerfile 的例子基本涵蓋了常用的映象構建指令。學習了映象的各種操作,下面我們深入瞭解一下映象的實現原理。

映象的實現原理

其實 Docker 映象是由一系列映象層(layer)組成的,每一層代表了映象構建過程中的一次提交。下面以一個映象構建的 Dockerfile 來說明映象是如何分層的。

FROM busybox
COPY test /tmp/test
RUN mkdir /tmp/testdir

上面的 Dockerfile 由三步組成:

第一行基於 busybox 建立一個映象層;

第二行拷貝本機 test 檔案到映象內;

第三行在 /tmp 資料夾下建立一個目錄 testdir。

為了驗證映象的儲存結構,我們使用docker build命令在上面 Dockerfile 所在目錄構建一個映象:

$ docker build -t mybusybox .

這裡我的 Docker 使用的是 overlay2 檔案驅動,進入到/var/lib/docker/overlay2目錄下使用tree .命令檢視產生的映象檔案:

$ tree .
# 以下為 tree . 命令輸出內容
|-- 3e89b959f921227acab94f5ab4524252ae0a829ff8a3687178e3aca56d605679
|   |-- diff  # 這一層為基礎層,對應上述 Dockerfile 第一行,包含 busybox 映象所有檔案內容,例如 /etc,/bin,/var 等目錄
... 此次省略部分原始映象檔案內容
|   `-- link 
|-- 6591d4e47eb2488e6297a0a07a2439f550cdb22845b6d2ddb1be2466ae7a9391
|   |-- diff   # 這一層對應上述 Dockerfile 第二行,拷貝 test 檔案到 /tmp 資料夾下,因此 diff 資料夾下有了 /tmp/test 檔案
|   |   `-- tmp
|   |       `-- test
|   |-- link
|   |-- lower
|   `-- work
|-- backingFsBlockDev
|-- bec6a018080f7b808565728dee8447b9e86b3093b16ad5e6a1ac3976528a8bb1
|   |-- diff # 這一層對應上述 Dockerfile 第三行,在 /tmp 資料夾下建立 testdir 資料夾,因此 diff 資料夾下有了 /tmp/testdir 資料夾
|   |   `-- tmp
|   |       `-- testdir
|   |-- link
|   |-- lower
|   `-- work
...

通過上面的目錄結構可以看到,Dockerfile 的每一行命令,都生成了一個映象層,每一層的 diff 夾下只存放了增量資料,如圖 2 所示。

分層的結構使得 Docker 映象非常輕量,每一層根據映象的內容都有一個唯一的 ID 值,當不同的映象之間有相同的映象層時,便可以實現不同的映象之間共享映象層的效果。

總結一下, Docker 映象是靜態的分層管理的檔案組合,映象底層的實現依賴於聯合檔案系統(UnionFS)。充分掌握映象的原理,可以幫助我們在生產實踐中構建出最優的映象,同時也可以幫助我們更好地理解容器和映象的關係。

本文源自:拉勾教育課程:由淺入深吃透 Docker,郭少 前 360 高階容器技術專家