天天看點

docker鏡像建構Docker鏡像原理鏡像制作

Docker鏡像原理

Linux系統組成

要了解Docker鏡像原理,需要先了解linux作業系統。

作業系統的組成部分分為:程序排程子系統、程序通信子系統、記憶體管理子系統、裝置管理子系統、檔案管理子系統、網絡通信子系統、作業控制子系統等。從整體層面來說,linux系統都是由不同的檔案構成并運作的。

Docker鏡像的本質是一個分層檔案系統。而linux檔案系統由bootfs和rootfs兩部分組成(fs:file system的縮寫):

  • bootfs:包含bootloader(引導加載程式)和kernel(核心)。bootloader主要是引導加載kernel
  • rootfs:root檔案系統,包含的就是Linux系統中的/dev、/proc、/bin、/etc等标準目錄和檔案

我們經常接觸到的linux系統如ubuntu、RedHat、centos等系統,bootfs基本一樣,rootfs不同。

docker鏡像建構Docker鏡像原理鏡像制作

Docker鏡像原理

  • Docker鏡像是由特殊的檔案系統疊加而成的,其最低端使用了主機(主控端)的bootfs,其他應用是在其基礎上一層層往上疊加,提供給使用者的就是最頂層檔案提供的對接接口。

    以下以tomcat應用進行講解:

    我們想要運作tomcat服務,需要java可運作的環境(即jdk),jdk和tomcat又需要在linux系統上運作,是以鏡像如下圖:

    docker鏡像建構Docker鏡像原理鏡像制作

底層使用主控端的bootfs,第二層是rootfs(root檔案系統,被稱base image,即基礎鏡像),由于tomcat服務是基于jdk開發的,是以需要在實際的tomcat服務之前,疊加jdk鏡像,jdk鏡像之後,再疊加真正要使用的tomcat鏡像(使用者使用tomcat提供的服務),是以如果我們本地安裝tomcat服務時,下載下傳的安裝包隻有幾十MB,但是tomcat鏡像卻有400多MB,就是因為實際的tomcat鏡像包含了其他鏡像,隻是對使用者來說,需要的是最頂層的tomcat服務而已,tomcat官網的安裝包安裝前需要我們自己去安裝jdk等内容,而docker鏡像是一步到位。

我們在拉取tomcat鏡像時,可以看到有多個Pull,就是因為要下載下傳多個鏡像(但給使用者看到的是最頂層的tomcat鏡像)

docker鏡像建構Docker鏡像原理鏡像制作

我們在tomcat鏡像生成的容器中,檢視jdk版本和linux版本,是可以查到對應的資訊的

docker鏡像建構Docker鏡像原理鏡像制作

我們也可以通過

docker inspect tomcat:latest

指令檢視該鏡像的具體分層資訊:

docker鏡像建構Docker鏡像原理鏡像制作

總結

  • Docker鏡像時由特殊的檔案系統分層疊加而成
  • Docker容器是基于主控端的bootfs運作,第2層是rootfs(基礎鏡像),然後根據需求往上疊加其他鏡像檔案。
  • Docker鏡像使用了聯合檔案系統(Union File System)技術,該技術能夠基于基礎鏡像,将鏡像通過分層并繼承的方式制作成一個完整的、統一的鏡像,即一次同時加載多個檔案系統,但使用者隻能看到一個檔案系統(可以了解為:對使用者隐藏了頂層以下的鏡像檔案)。

鏡像制作

官方提供的鏡像有時候不能滿足日常使用,這個時候就需要制作符合自己個性化的鏡像,鏡像制作有2種方式:

  • 容器轉為鏡像:拉取鏡像,根據鏡像生成了docker容器,然後在容器的基礎上進行修改,修改完成後,将容器轉成鏡像,然後分享給其他人。
  • dockerfile建構:在建構檔案裡指定建構鏡像所需的指令和說明,然後通過docker bulid指令生成新的鏡像。

容器轉為鏡像

對于使用者來說,是沒有權限去修改鏡像檔案的(隻有隻讀權限),但是我們可以操作容器啊,鏡像啟動容器時,Docker會在最頂層加載一個讀寫檔案系統作為容器。

docker鏡像建構Docker鏡像原理鏡像制作

我們可以在容器内操作,然後根據容器生成鏡像:

docker commit 容器id或容器名稱 鏡像名稱:版本号

如果想要分享給其他人,可以将鏡像壓縮儲存(docker save)儲存到本地,然後将壓縮包分享給他人,他人可以通過裝載(docker load)壓縮包的方式安裝鏡像。

鏡像壓縮到本地:

docker save 鏡像名稱:版本号>路徑/xxx.tar

壓縮包安裝鏡像:

docker load<路徑/xxx.tar

以下以tomcat鏡像為例,想要修改tomcat預設打開的頁面:

docker鏡像建構Docker鏡像原理鏡像制作
docker鏡像建構Docker鏡像原理鏡像制作
docker鏡像建構Docker鏡像原理鏡像制作

Dockerfile建構鏡像

Dockerfile是一個文本檔案,包含了一條條的指令,在基于指定的鏡像上,一條指令建構一層,最終建構出一個新的鏡像。Dockerfile的關鍵字說明如下:

關鍵字 作用 備注 格式
FROM 指定父鏡像 指定基于哪個image開始建構

FROM <image>

FROM <image>:<tag>

MAINTAINER 作者或維護者資訊 标明這個dockerfile是誰寫的或維護的

MAINTAINER xxx xxx

LABEL 标簽 給鏡像添加中繼資料,以鍵值對的形式,可以了解類似注釋

LABEL <key>=<value> <key>=<value> <key>=<value>

RUN 制作鏡像時執行的指令 建構鏡像時運作的指令,預設是/bin/sh

RUN <指令行指令>

RUN ["可執行檔案", "參數1", "參數2"...,"參數n"]

(相當于:RUN 可執行檔案 參數1 參數2 … 參數n)
CMD 容器啟動時執行的指令 運作容器時執行的shell環境。每個 Dockerfile 隻能有一條 CMD 指令。如果指定了多條指令,隻有最後一條會被執行。

有3種格式:

1.exec執行:

CMD ["executable","param1","param2"]

2./bin/sh中執行:

CMD command param1 param2

3.提供給 ENTRYPOINT 的預設參數:

CMD ["param1","param2"]

ENTRYPOINT 入口 一般在制作一些執行就關閉的容器中會使用

ENTRYPOINT ["executable", "param1", "param2"]

COPY 複制檔案到鏡像中 建構的時候複制檔案到鏡像中

COPY 源路徑 目标路徑

(源路徑是主控端的路徑,目标路徑是容器的路徑)
ADD 添加檔案 建構時添加檔案到鏡像中(即将主控端的檔案添加到容器内),與COPY的差別是ADD會自動解壓

ADD 源路徑 目标路徑

(源路徑是主控端的路徑,目标路徑是容器的路徑)
ENV 環境變量 在建構鏡像時,設定環境變量,可以在啟動容器的時候,通過-e覆寫(即容器内也可以使用)

ENV <key> <value>

ARG 建構參數 用于指定傳遞給建構運作時的變量(給dockerfile傳參),相當于建構鏡像時可以在外部為裡面傳參

ARG <name>[=<default value>]

VOLUME 定義外部可以挂載的匿名資料卷 在啟動容器時若忘記挂載資料卷,會自動挂載到匿名卷

VOLUME ["/xxx/xx/xxxx", "xxx", ..., "xxx"]

EXPOSE 聲明容器的服務端口 僅僅聲明容器的服務端口(及提供服務的端口),幫助使用裡了解并使用該端口

EXPOSE 端口号

WORKDIR 工作目錄 指定容器的開始工作目錄(若沒有時會自動建立)。設定之後,Dockerfile中其後的指令RUN、CMD、ENTRYPOINT、ADD、COPY等指令都會在該目錄下執行

WORKDIR 最好是絕對路徑

USER 指定容器執行使用者 指定運作容器時的使用者名或ID執行使用者

USER user

dockerfile的注釋符号是

#

通過dockerfile建構鏡像指令格式為:

docker build -f dockerfile檔案路徑 -t 鏡像名稱:版本

示例1

以tomcat鏡像為例,想要修改tomcat預設打開的頁面:

步驟1:編輯dockerfile檔案(如tomcat_dockerfile檔案):

docker鏡像建構Docker鏡像原理鏡像制作

父鏡像tomcat:jre17-temurin的資訊我們可以在docker hub官網

docker鏡像建構Docker鏡像原理鏡像制作
docker鏡像建構Docker鏡像原理鏡像制作
docker鏡像建構Docker鏡像原理鏡像制作

選擇某個版本,點選之後,跳轉到的頁面會展示類似dockerfile檔案内容的資訊,我們可以看到,tomcat設定的工作目錄WORKDIR是/usr/local/tomcat,申明的服務端口是8080

docker鏡像建構Docker鏡像原理鏡像制作

步驟2:生成鏡像(docker build)

docker鏡像建構Docker鏡像原理鏡像制作

注:關于docker build指令末尾的

.

,本人還是沒搞懂,可以參考其他大神的文章:Docker學習:Docker核心指令 | 常用指令 | Docker build . 點的含義 | docker build和docker commit關系 | docker rm 與sleep用法

步驟3:驗證鏡像

docker鏡像建構Docker鏡像原理鏡像制作

通路伺服器的8080端口,顯示了自己編輯的内容

docker鏡像建構Docker鏡像原理鏡像制作

如果其他人也想使用該tomcat,你可以将鏡像打包(docker save)或直接将dockerfile檔案發送過去,dockerfile檔案建構鏡像的時候,還有一個友善的地方就是docker build的dockerfile可以是網際網路可通路的檔案,可以及時更新,友善通路。

使用網際網路url的dockerfile建構鏡像的指令是:

docker build url

注意:url不需要定位到具體的檔案,要定位到檔案所在路徑,然後該路徑下需要有檔案名稱是

Dockerfile

的檔案。

示例:

docker build github.com/creack/docker-firefox

docker鏡像建構Docker鏡像原理鏡像制作
docker鏡像建構Docker鏡像原理鏡像制作

示例2

題目:自定義centos:7鏡像,要求:預設登入路徑為/usr;可以使用vim

官網提供的centos:7預設登入路徑是根目錄,無法使用vim

docker鏡像建構Docker鏡像原理鏡像制作

預設登入路徑可以根據WORKDIR來設定,vim無法使用,是因為沒有安裝該應用(預設安裝了vi),如果需要使用,我們就需要安裝vim,是以dockerfile的RUN需要做2件事情:設定WORKDIR、安裝vim,dockerfile檔案内容如下:

# 基于centos:7的鏡像
FROM centos:7
# 維護者資訊
MAINTAINER wenxiaoba [email protected]
# 設定初始工作目錄
WORKDIR /usr
# 執行centos安裝vim指令
RUN yum -y install vim
# 定義容器啟動執行的指令
CMD /bin/bash
           

通過docker build生成鏡像

docker鏡像建構Docker鏡像原理鏡像制作
docker鏡像建構Docker鏡像原理鏡像制作

我們根據生成的鏡像vim_centos:7v去建立并啟動容器,驗證是否符合預期

docker鏡像建構Docker鏡像原理鏡像制作