Docker 的快取機制是提升映象建置效率的關鍵。Docker 映象採分層結構,每一步操作都會生成一個新的層。當 Dockerfile 沒有變更時,Docker 會直接使用快取的層,避免重複建置,進而縮短建置時間。這對於頻繁修改程式碼並重新建置映象的開發流程來說至關重要,尤其在 CI/CD 流程中,能有效減少每次建置所需的時間。瞭解 Docker 的快取機制,可以幫助開發者編寫更有效率的 Dockerfile,並最佳化容器化應用程式的佈署流程。
Docker 檔案製作與快取機制詳解
在容器化的開發流程中,Dockerfile 是定義容器環境的核心檔案。本章節將探討 Dockerfile 的製作過程,以及 Docker 的快取機制。
Docker 快取機制原理
Docker 映象的結構是由多個層(layer)堆積疊而成,每一層代表著對映象的無狀態變更。當重建映象時,Docker 會從上到下檢查每一層是否有變更。如果只有最上層的程式碼發生變化,那麼只有這一層需要被重建。
快取機制運作範例
首先,我們來檢視 Docker 快取的工作方式。假設我們有一個名為 joshuacook/gsl 的映象,其 Dockerfile 內容如下:
FROM gcc
LABEL maintainer=@joshuacook
RUN apt-get update && apt-get install -y gsl-bin libgsl0-dbg libgsl0-dev libgsl0ldbl
現在,我們在 Dockerfile 中新增一個安裝 gdb 的層:
RUN apt-get update && \
apt-get install -y gdb
內容解密:
FROM gcc:使用官方的 GCC 映象作為基礎映象。LABEL maintainer=@joshuacook:為映象新增維護者標籤。RUN apt-get update && apt-get install -y gsl-bin libgsl0-dbg libgsl0-dev libgsl0ldbl:安裝 GSL 相關套件。RUN apt-get install -y gdb:新增一個層來安裝 gdb 除錯工具。
執行建置指令:
$ docker build -t joshuacook/gsl gsl
輸出結果顯示,步驟 1-3 因為沒有變化而使用了快取,只有步驟 4 被執行。
Step 1/4 : FROM gcc
---
> 408d218617ca
Step 2/4 : LABEL maintainer @joshuacook
---
> Using cache
---
> ba0d6482c28a
Step 3/4 : RUN apt-get update && apt-get install -y gsl-bin libgsl0-dbg libgsl0-dev libgsl0ldbl
---
> Using cache
---
> 8706282586fc
Step 4/4 : RUN apt-get install -y gdb
---
> Running in c491003e5a95
...
---
> 53111721b96a
Removing intermediate container c491003e5a95
Successfully built 53111721b96a
再次執行相同的建置指令,會發現所有步驟都使用了快取:
$ docker build -t joshuacook/gsl gsl
Step 1/4 : FROM gcc
---
> 408d218617ca
Step 2/4 : LABEL maintainer @joshuacook
---
> Using cache
---
> ba0d6482c28a
Step 3/4 : RUN apt-get update && apt-get install -y gsl-bin libgsl0-dbg libgsl0-dev libgsl0ldbl
---
> Using cache
---
> 8706282586fc
Step 4/4 : RUN apt-get install -y gdb
---
> Using cache
---
> 53111721b96a
Successfully built 53111721b96a
快取機制優點
- 提升建置效率:未變更的層可以直接使用快取,避免重複建置。
- 冪等性:多次執行相同的建置指令不會產生額外效果。
建立 Miniconda3 映象
Miniconda 是 Anaconda 的精簡版本,用於管理 Python 和 R 語言環境。我們將建立一個自定義的 Miniconda3 映象。
建立 Miniconda3 映象步驟
- 建立專案目錄
$ mkdir miniconda3
$ touch miniconda3/Dockerfile
- 定義 Dockerfile
FROM debian
LABEL maintainer=@joshuacook
ARG DEBIAN_FRONTEND=noninteractive
內容解密:
FROM debian:使用 Debian 作為基礎映象。LABEL maintainer=@joshuacook:新增維護者資訊。ARG DEBIAN_FRONTEND=noninteractive:定義環境變數,避免互動式提示。建置 Miniconda3 映象
$ docker build -t miniconda3 miniconda3
- 檢視建置結果
$ docker images
輸出結果顯示,新建的 miniconda3 映象與 debian 映象共用相同的 IMAGE ID,因為它們實際上是相同的映象。
重複建置測試
再次執行建置指令,可以觀察到快取的使用情況:
$ docker build -t miniconda3 miniconda3
Step 1/3 : FROM debian
---
> a2ff708b7413
Step 2/3 : LABEL maintainer @joshuacook
---
> Using cache
---
> c140313c988e
Step 3/3 : ARG DEBIAN_FRONTEND=noninteractive
---
> Running in b927c25267f0
---
> da987fd59d24
Removing intermediate container b927c25267f0
Successfully built da987fd59d24
重點整理
- Docker 快取機制可以顯著提升映象建置效率。
- 適當使用 ARG 和 ENV 指令可以靈活組態容器環境。
- 建立自定義 Miniconda3 映象可以用於科學計算和資料分析環境。
透過本章節的學習,我們深入瞭解了 Dockerfile 的製作流程和 Docker 的快取機制,這些知識對於高效使用 Docker 技術至關重要。
第5章:Dockerfile 詳解
在前面的章節中,我們已經成功建立了一個基本的 Docker 映像檔。本章將探討 Dockerfile 的編寫,以建立一個完整的 Miniconda3 環境。
Dockerfile 的基本結構
Dockerfile 是一種特殊的檔案,用於定義 Docker 映像檔的構建過程。它包含了一系列的指令,用於指定基礎映像檔、安裝軟體、設定環境變數等。
編寫 Dockerfile
首先,我們需要建立一個名為 miniconda3 的目錄,並在其中建立一個名為 Dockerfile 的檔案。
步驟1:指定基礎映像檔
我們的第一步是指定基礎映像檔。在這個例子中,我們使用 Debian 作為基礎映像檔。
FROM debian
步驟2:新增 LABEL 和 ARG 指令
接下來,我們新增一個 LABEL 指令來指定維護者的資訊,並使用 ARG 指令來設定環境變數。
LABEL maintainer="@joshuacook"
ARG DEBIAN_FRONTEND=noninteractive
步驟3:佈建作業系統
為了讓我們的 Miniconda3 環境能夠正常運作,我們需要安裝一些必要的軟體套件。
RUN apt-get update --fix-missing && \
apt-get install -y \
wget bzip2 ca-certificates \
libglib2.0-0 libxext6 libsm6 libxrender1
#### 內容解密:
這段程式碼的作用是更新 Debian 的套件清單,並安裝必要的軟體套件。其中,apt-get update 用於更新套件清單,apt-get install 用於安裝指定的軟體套件。我們使用 -y 引數來自動確認安裝,並使用 \ 來將指令分成多行,以提高可讀性。
步驟4:安裝 Miniconda3
接下來,我們需要安裝 Miniconda3。
RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \
wget --quiet https://repo.continuum.io/miniconda/Miniconda3-4.3.11-Linux-x86_64.sh -O ~/miniconda.sh && \
/bin/bash ~/miniconda.sh -b -p /opt/conda && \
rm ~/miniconda.sh
#### 內容解密:
這段程式碼的作用是安裝 Miniconda3。首先,我們建立一個名為 conda.sh 的檔案,用於設定環境變數。然後,我們下載 Miniconda3 的安裝指令碼,並執行它。最後,我們刪除安裝指令碼,以節省空間。
步驟5:安裝 tini
為了避免容器中的 Zombie 程式,我們需要安裝 tini。
RUN apt-get install -y curl grep sed dpkg && \
TINI_VERSION=`curl https://github.com/krallin/tini/releases/latest | grep -o "/v.*\"" | sed 's:^..\(.*\).$:\1:'` && \
curl -L "https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini_${TINI_VERSION}.deb" > tini.deb && \
dpkg -i tini.deb && \
rm tini.deb && \
apt-get clean
#### 內容解密:
這段程式碼的作用是安裝 tini。首先,我們安裝必要的軟體套件,如 curl、grep 和 sed。然後,我們取得 tini 的最新版本,並下載對應的 deb 檔案。接著,我們安裝 tini,並刪除 deb 檔案。最後,我們清理套件快取,以節省空間。
建構 Docker 映像檔
完成 Dockerfile 的編寫後,我們可以使用 docker build 指令來建構 Docker 映像檔。
$ docker build -t miniconda3 miniconda3
這個指令會根據 Dockerfile 中的指令,逐步建構 Docker 映像檔。建構完成後,我們可以使用 docker images 指令來檢視映像檔的資訊。
提交變更
在每次修改 Dockerfile 後,我們都需要提交變更到本地儲存函式庫。
$ git add Dockerfile
$ git commit -m 'MINICONDA3 IMAGE. 新增 LABEL 和 ARG 指令.'
這樣,我們就可以追蹤每次變更的內容,並方便地回溯到之前的版本。
第 5 章:Dockerfile 詳解
本章主要介紹 Dockerfile 的基本概念及其在 Docker 環境中的重要性。Dockerfile 是一種文字檔案,用於定義 Docker 映像的構建過程。透過 Dockerfile,可以自動化地構建和佈署 Docker 映像。
組態環境變數
為了確保容器能夠正常執行,需要組態一些環境變數。在 Dockerfile 中,可以使用 ENV 指令來設定環境變數。
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
ENV PATH /opt/conda/bin:$PATH
內容解密:
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8:設定語言環境變數為C.UTF-8,確保容器內的語言設定正確。ENV PATH /opt/conda/bin:$PATH:將/opt/conda/bin新增到系統的PATH環境變數中,確保conda相關的命令可以被正確執行。
設定 ENTRYPOINT
ENTRYPOINT 指令用於指定容器啟動時要執行的程式。在本例中,使用 tini 作為容器內的初始化程式。
ENTRYPOINT [ "/usr/bin/tini", "--" ]
內容解密:
ENTRYPOINT [ "/usr/bin/tini", "--" ]:指定/usr/bin/tini為容器的入口點,並傳遞--引數。tini是一個輕量級的初始化系統,用於處理訊號和子程式。
建構 miniconda3 映像
使用 docker build 命令來建構 miniconda3 映像。
$ docker build -t miniconda3 miniconda3
內容解密:
$ docker build -t miniconda3 miniconda3:使用當前目錄下的 Dockerfile 建構一個名為miniconda3的映像。
建構 ipython 映像
在 miniconda3 映像的基礎上,建構 ipython 映像。首先建立一個新的目錄,並在其中建立 Dockerfile。
$ mkdir ipython
$ touch ipython/Dockerfile
內容解密:
$ mkdir ipython:建立一個名為ipython的目錄。$ touch ipython/Dockerfile:在ipython目錄下建立一個空的 Dockerfile。
定義 ipython 映像
在 Dockerfile 中,使用 FROM 指令指定基礎映像,並安裝 ipython。
FROM miniconda3
LABEL maintainer=@joshuacook
RUN conda update conda && \
conda install --quiet --yes ipython && \
conda clean -tipsy
CMD ["ipython"]
內容解密:
FROM miniconda3:指定miniconda3為基礎映像。LABEL maintainer=@joshuacook:新增維護者資訊。RUN conda update conda && conda install --quiet --yes ipython && conda clean -tipsy:更新conda,安裝ipython,並清理無用的檔案。CMD ["ipython"]:指定容器啟動時預設執行的命令為ipython。
建構和執行 ipython 映像
使用 docker build 命令建構 ipython 映像,並使用 docker run 命令執行該映像。
$ docker build -t ipython ipython
$ docker run -it ipython
內容解密:
$ docker build -t ipython ipython:建構ipython映像。$ docker run -it ipython:以互動模式執行ipython容器。
提交變更到 GitHub
將變更提交到本地倉函式庫,並推播到 GitHub。
$ git add ipython/Dockerfile
$ git commit -m 'IPYTHON. Initial build'
$ git push
內容解密:
$ git add ipython/Dockerfile:將ipython/Dockerfile新增到暫存區。$ git commit -m 'IPYTHON. Initial build':提交變更,並新增提交訊息。$ git push:將變更推播到 GitHub。
第 6 章:Docker Hub 詳解
Docker Hub 是 Docker 的官方倉函式庫,用於儲存和分發 Docker 映像。本章將介紹 Docker Hub 的基本概念和使用方法。
Docker Hub 簡介
Docker Hub 是 Docker 的官方倉函式庫,提供了豐富的 Docker 映像資源。使用者可以在 Docker Hub 上搜尋、下載和使用各種 Docker 映像。
使用 Docker Hub
使用者可以在 Docker Hub 上建立自己的倉函式庫,並上傳自己的 Docker 映像。同時,也可以瀏覽和下載其他使用者分享的 Docker 映像。
Docker Hub 的替代方案
除了 Docker Hub 之外,還有其他一些 Docker 倉函式庫可供選擇,例如 Quay.io 和 Google Container Registry。這些倉函式庫提供了不同的功能和特性,可以根據實際需求進行選擇。