容器(8)--docker鏡像--docker 鏡像介紹及 dockerfile 自定義鏡像

Dockerfile自定義鏡像

1) Dockerfile介紹

Dockerfile 是自動(dòng)構(gòu)建 docker鏡像的配置文件, 用戶可以使用 Dockerfile 快速創(chuàng)建自定義的鏡像。Dockerfile 中的命令非常類似于linux 下的 shell 命令。
我們可以通過(guò)下面這幅圖來(lái)直觀地感受下 Docker 鏡像、容器和 Dockerfile 三者之間的關(guān)系。


image.png

我們從上圖中可以看到, Dockerfile 可以自定義鏡像,通過(guò) Docker 命令去運(yùn)行鏡像,從而達(dá)到啟動(dòng)容器的目的。

2) Dockerfile的基本結(jié)構(gòu)

Dockerfile 是由一行行命令語(yǔ)句組成,并且支持已 # 開(kāi)頭的注釋行。
一般來(lái)說(shuō),我們可以將 Dockerfile 分為四個(gè)部分:
基礎(chǔ)鏡像(父鏡像)信息指令 FROM
維護(hù)者信息指令 MAINTAINER
鏡像操作指令 RUN 、 EVN 、 ADD 和 WORKDIR 等
容器啟動(dòng)指令 CMD 、ENTRYPOINT 和 USER 等

3)使用 Dockerfile 定制鏡像/自定義鏡像

Q

為什么要自定義Docker鏡像?

A

工作中Docker中的鏡像并不滿足工作的需要,需要進(jìn)行自己的配置。
Docker Hub 中 99% 的鏡像都是通過(guò)在base 鏡像中安裝和配置需要的軟件構(gòu)建出來(lái)的

4) 使用 Docker build 構(gòu)建鏡像創(chuàng)建容器的步驟

第一步 編寫(xiě)Dockerfile文件
第二步 Docker build
第三步 Docker run

4-1 企業(yè)案例通過(guò)Dockerfile自定義Centos鏡像

docker pull centos


image.png

官方鏡像 docker run -i -t


Snipaste_2020-02-23_09-31-23.jpg

官方進(jìn)行我們執(zhí)行的命令不支持,顯然是不符合我們需求的


image.png

【注意】現(xiàn)在我們需要自定義一個(gè)鏡像來(lái)支持 VIM、ifconfig、并且登錄后的默認(rèn)路徑改做修改。

企業(yè)級(jí)案例

一、拉一個(gè)基礎(chǔ)centos鏡像

docker pull centos

二、編寫(xiě)dockerfile文件

vim Dockerfile

#從哪一個(gè)基礎(chǔ)鏡像構(gòu)建
FROM centos

#定義作者的信息
MAINTAINER 1907

#定義一個(gè)變量
ENV newpath /tmp

#設(shè)置登錄以后工作路徑(落腳點(diǎn))
WORKDIR $newpath

#干了什么(執(zhí)行你要的操作)
RUN yum install -y vim
RUN yum install -y net-tools
##如果有更多的需求 。。。RUN

#開(kāi)放指定的端口
EXPOSE 80
EXPOSE 22

#執(zhí)行命令
CMD echo $newpath
CMD echo "success   ok"
CMD /bin/bash
~              

三、通過(guò)dockerfile文件創(chuàng)建鏡像

[root@localhost home]#  docker build -f Dockerfile -t azkaban/custom_centos:v1 .
Sending build context to Docker daemon  5.632kB
Step 1/11 : FROM centos
 ---> 470671670cac
Step 2/11 : MAINTAINER 1907
 ---> Running in d24bf9043207
Removing intermediate container d24bf9043207
 ---> 159ad59927d2
Step 3/11 : ENV newpath /tmp
 ---> Running in 5fa9a2ebc28c
Removing intermediate container 5fa9a2ebc28c
 ---> c6bec0ee09b9
Step 4/11 : WORKDIR $newpath
 ---> Running in ab29e7e49eda
Removing intermediate container ab29e7e49eda
 ---> f79d02d81a18
Step 5/11 : RUN yum install -y vim
 ---> Running in 9474c83bfe6c
CentOS-8 - AppStream                            342 kB/s | 6.4 MB     00:19    
CentOS-8 - Base                                 113 kB/s | 5.0 MB     00:44    
CentOS-8 - Extras                               1.9 kB/s | 2.1 kB     00:01    
Dependencies resolved.
================================================================================
 Package             Arch        Version                   Repository      Size
================================================================================
Installing:
 vim-enhanced        x86_64      2:8.0.1763-13.el8         AppStream      1.4 M
Installing dependencies:
 gpm-libs            x86_64      1.20.7-15.el8             AppStream       39 k
 vim-common          x86_64      2:8.0.1763-13.el8         AppStream      6.3 M
 vim-filesystem      noarch      2:8.0.1763-13.el8         AppStream       48 k
 which               x86_64      2.21-10.el8               BaseOS          49 k

Transaction Summary
================================================================================
Install  5 Packages

Total download size: 7.8 M
Installed size: 31 M
Downloading Packages:
(1/5): gpm-libs-1.20.7-15.el8.x86_64.rpm         50 kB/s |  39 kB     00:00    
(2/5): vim-filesystem-8.0.1763-13.el8.noarch.rp 239 kB/s |  48 kB     00:00    
(3/5): which-2.21-10.el8.x86_64.rpm             121 kB/s |  49 kB     00:00    
(4/5): vim-common-8.0.1763-13.el8.x86_64.rpm    573 kB/s | 6.3 MB     00:11    
[MIRROR] vim-enhanced-8.0.1763-13.el8.x86_64.rpm: Curl error (28): Timeout was reached for http://mirrors.ustc.edu.cn/centos/8.1.1911/AppStream/x86_64/os/Packages/vim-enhanced-8.0.1763-13.el8.x86_64.rpm [Operation too slow. Less than 1000 bytes/sec transferred the last 30 seconds]
(5/5): vim-enhanced-8.0.1763-13.el8.x86_64.rpm   44 kB/s | 1.4 MB     00:31    
--------------------------------------------------------------------------------
Total                                           208 kB/s | 7.8 MB     00:38     
warning: /var/cache/dnf/AppStream-02e86d1c976ab532/packages/gpm-libs-1.20.7-15.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS-8 - AppStream                            1.6 MB/s | 1.6 kB     00:00    
Importing GPG key 0x8483C65D:
 Userid     : "CentOS (CentOS Official Signing Key) <security@centos.org>"
 Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                        1/1 
  Installing       : which-2.21-10.el8.x86_64                               1/5 
  Installing       : vim-filesystem-2:8.0.1763-13.el8.noarch                2/5 
  Installing       : vim-common-2:8.0.1763-13.el8.x86_64                    3/5 
  Installing       : gpm-libs-1.20.7-15.el8.x86_64                          4/5 
  Running scriptlet: gpm-libs-1.20.7-15.el8.x86_64                          4/5 
  Installing       : vim-enhanced-2:8.0.1763-13.el8.x86_64                  5/5 
  Running scriptlet: vim-enhanced-2:8.0.1763-13.el8.x86_64                  5/5 
  Running scriptlet: vim-common-2:8.0.1763-13.el8.x86_64                    5/5 
  Verifying        : gpm-libs-1.20.7-15.el8.x86_64                          1/5 
  Verifying        : vim-common-2:8.0.1763-13.el8.x86_64                    2/5 
  Verifying        : vim-enhanced-2:8.0.1763-13.el8.x86_64                  3/5 
  Verifying        : vim-filesystem-2:8.0.1763-13.el8.noarch                4/5 
  Verifying        : which-2.21-10.el8.x86_64                               5/5 

Installed:
  vim-enhanced-2:8.0.1763-13.el8.x86_64 gpm-libs-1.20.7-15.el8.x86_64          
  vim-common-2:8.0.1763-13.el8.x86_64   vim-filesystem-2:8.0.1763-13.el8.noarch
  which-2.21-10.el8.x86_64             

Complete!
Removing intermediate container 9474c83bfe6c
 ---> d1773a676980
Step 6/11 : RUN yum install -y net-tools
 ---> Running in c28e68f52b0e
Last metadata expiration check: 0:00:47 ago on Sun Feb 23 01:59:52 2020.
Dependencies resolved.
================================================================================
 Package         Architecture Version                        Repository    Size
================================================================================
Installing:
 net-tools       x86_64       2.0-0.51.20160912git.el8       BaseOS       323 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 323 k
Installed size: 1.0 M
Downloading Packages:
net-tools-2.0-0.51.20160912git.el8.x86_64.rpm   1.1 MB/s | 323 kB     00:00    
--------------------------------------------------------------------------------
Total                                           112 kB/s | 323 kB     00:02     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                        1/1 
  Installing       : net-tools-2.0-0.51.20160912git.el8.x86_64              1/1 
  Running scriptlet: net-tools-2.0-0.51.20160912git.el8.x86_64              1/1 
  Verifying        : net-tools-2.0-0.51.20160912git.el8.x86_64              1/1 

Installed:
  net-tools-2.0-0.51.20160912git.el8.x86_64                                     

Complete!
Removing intermediate container c28e68f52b0e
 ---> 9de3592d6946
Step 7/11 : EXPOSE 80
 ---> Running in 5569cdc7691d
Removing intermediate container 5569cdc7691d
 ---> 3a16923f249c
Step 8/11 : EXPOSE 22
 ---> Running in 272964d43403
Removing intermediate container 272964d43403
 ---> 66a7ac68030b
Step 9/11 : CMD echo $newpath
 ---> Running in 86d6d8655e4b
Removing intermediate container 86d6d8655e4b
 ---> bb617cf4c488
Step 10/11 : CMD echo "success   ok"
 ---> Running in 876412b8e523
Removing intermediate container 876412b8e523
 ---> 96915955be0c
Step 11/11 : CMD /bin/bash
 ---> Running in 809bd856d4fa
Removing intermediate container 809bd856d4fa
 ---> 2ba838e1b3ae
Successfully built 2ba838e1b3ae
Successfully tagged azkaban/custom_centos:v1

自己構(gòu)建的鏡像成功 docker images查看


image.png

四 通過(guò)Docker run 創(chuàng)建容器,,驗(yàn)證vim 以及net-tools

通過(guò)我們自定義的鏡像創(chuàng)建容器


image.png

測(cè)試ifconfig命令 OK
測(cè)試vim 命令OK


image.png

看看構(gòu)建過(guò)程是否是如前面所說(shuō),這也證實(shí)了鏡像的分層


image.png

4)Dockerfile鏡像分層

dockerfile中的每一條命令,都會(huì)構(gòu)建一層文件。


image.png

以下圖的Dockerfile為例分析構(gòu)建過(guò)程


image.png

image.png

當(dāng)容器啟動(dòng)時(shí),一個(gè)新的可寫(xiě)層被加載到鏡像的頂部。這一層通常被稱作“容器層”,“容器層”之下的都叫“鏡像層”。


image.png

所有對(duì)容器的改動(dòng) - 無(wú)論添加、刪除、還是修改文件都只會(huì)發(fā)生在容器層中。
只有容器層是可寫(xiě)的,容器層下面的所有鏡像層都是只讀的。
下面我們深入討論容器層的細(xì)節(jié)。
鏡像層數(shù)量可能會(huì)很多,所有鏡像層會(huì)聯(lián)合在一起組成一個(gè)統(tǒng)一的文件系統(tǒng)。如果不同層中有一個(gè)相同路徑的文件,比如 /a,上層的 /a 會(huì)覆蓋下層的 /a,也就是說(shuō)用戶只能訪問(wèn)到上層中的文件 /a。在容器層中,用戶看到的是一個(gè)疊加之后的文件系統(tǒng)。

1.添加文件
在容器中創(chuàng)建文件時(shí),新文件被添加到容器層中。
讀取文件
在容器中讀取某個(gè)文件時(shí),Docker 會(huì)從上往下依次在各鏡像層中查找此文件。一旦找到,打開(kāi)并讀入內(nèi)存。
修改文件
在容器中修改已存在的文件時(shí),Docker 會(huì)從上往下依次在各鏡像層中查找此文件。一旦找到,立即將其復(fù)制到容器層,然后修改之。
刪除文件
在容器中刪除文件時(shí),Docker 也是從上往下依次在鏡像層中查找此文件。找到后,會(huì)在容器層中記錄下此刪除操作。
只有當(dāng)需要修改時(shí)才復(fù)制一份數(shù)據(jù),這種特性被稱作 Copy-on-Write??梢?jiàn),容器層保存的是鏡像變化的部分,不會(huì)對(duì)鏡像本身進(jìn)行任何修改。
這樣就解釋了我們前面提出的問(wèn)題:容器層記錄對(duì)鏡像的修改,所有鏡像層都是只讀的,不會(huì)被容器修改,所以鏡像可以被多個(gè)容器共享。

5) Dockerfile指令詳解

一張圖搞定Dockerfile常見(jiàn)命令


image.png

Dockerfile中包括FROM、MAINTAINER、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、USER、WORKDIR、ONBUILD等13個(gè)指令。

FROM
格式為FROM image或FROM image:tag,并且Dockerfile中第一條指令必須是FROM指令,且在同一個(gè)Dockerfile中創(chuàng)建多個(gè)鏡像時(shí),可以使用多個(gè)FROM指令。

MAINTAINER
格式為MAINTAINER user_name user_email,指定維護(hù)者信息

RUN
格式為RUN command或 RUN ["EXECUTABLE","PARAM1","PARAM2".....],前者在shell終端中運(yùn)行命令,/bin/sh -c command,例如:/bin/sh -c "echo hello";后者使用exec執(zhí)行,指定其他運(yùn)行終端使用RUN["/bin/bash","-c","echo hello"]
每條RUN指令將當(dāng)前的鏡像基礎(chǔ)上執(zhí)行指令,并提交為新的鏡像,命令較長(zhǎng)的時(shí)候可以使用\來(lái)?yè)Q行。

CMD
支持三種格式:
CMD ["executable","param1","param2"],使用exec執(zhí)行,這是推薦的方式。
CMD command param1 param2 在/bin/sh中執(zhí)行。
CMD ["param1","param2"] 提供給ENTERYPOINT的默認(rèn)參數(shù)。
CMD用于指定容器啟動(dòng)時(shí)執(zhí)行的命令,每個(gè)Dockerfile只能有一個(gè)CMD命令,多個(gè)CMD命令只執(zhí)行最后一個(gè)。若容器啟動(dòng)時(shí)指定了運(yùn)行的命令,則會(huì)覆蓋掉CMD中指定的命令。

EXPOSE
格式為 EXPOSE port [port2,port3,...],例如EXPOSE 80這條指令告訴Docker服務(wù)器暴露80端口,供容器外部連接使用。
在啟動(dòng)容器的使用使用-P,Docker會(huì)自動(dòng)分配一個(gè)端口和轉(zhuǎn)發(fā)指定的端口,使用-p可以具體指定使用哪個(gè)本地的端口來(lái)映射對(duì)外開(kāi)放的端口。

ENV
格式為:EVN key value 。用于指定環(huán)境變量,這些環(huán)境變量,后續(xù)可以被RUN指令使用,容器運(yùn)行起來(lái)之后,也可以在容器中獲取這些環(huán)境變量。
例如
ENV word hello
RUN echo $word

ADD
格式:ADD src dest
該命令將復(fù)制指定本地目錄中的文件到容器中的dest中,src可以是一個(gè)絕對(duì)路徑,也可以是一個(gè)URL或一個(gè)tar文件,tar文件會(huì)自動(dòng)解壓為目錄。

COPY
格式為:COPY src desc
復(fù)制本地主機(jī)src目錄或文件到容器的desc目錄,desc不存在時(shí)會(huì)自動(dòng)創(chuàng)建。

ENTRYPOINT
格式有兩種:
ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1,param2 會(huì)在shell中執(zhí)行。
用于配置容器啟動(dòng)后執(zhí)行的命令,這些命令不能被docker run提供的參數(shù)覆蓋。和CMD一樣,每個(gè)Dockerfile中只能有一個(gè)ENTRYPOINT,當(dāng)有多個(gè)時(shí)最后一個(gè)生效。

VOLUME
格式為 VOLUME ["/data"]
作用是創(chuàng)建在本地主機(jī)或其他容器可以掛載的數(shù)據(jù)卷,用來(lái)存放數(shù)據(jù)。

USER
格式為:USER username
指定容器運(yùn)行時(shí)的用戶名或UID,后續(xù)的RUN也會(huì)使用指定的用戶。要臨時(shí)使用管理員權(quán)限可以使用sudo。在USER命令之前可以使用RUN命令創(chuàng)建需要的用戶。
例如:RUN groupadd -r docker && useradd -r -g docker docker

WORKDIR
格式: WORKDIR /path
為后續(xù)的RUN CMD ENTRYPOINT指定配置工作目錄,可以使用多個(gè)WORKDIR指令,若后續(xù)指令用得是相對(duì)路徑,則會(huì)基于之前的命令指定路徑。

ONBUILD
格式ONBUILD [INSTRUCTION]
該配置指定當(dāng)所創(chuàng)建的鏡像作為其他新建鏡像的基礎(chǔ)鏡像時(shí)所執(zhí)行的指令。
例如下面的Dockerfile創(chuàng)建了鏡像A:
ONBUILD ADD . /app
ONBUILD RUN python app.py

則基于鏡像A創(chuàng)建新的鏡像時(shí),新的Dockerfile中使用from A 指定基鏡像時(shí),自動(dòng)執(zhí)行ONBBUILD指令內(nèi)容,等價(jià)于在新的要構(gòu)建鏡像的Dockerfile中增加了兩條指令:
FROM A
ADD ./app
RUN python app.py

docker build
創(chuàng)建好Dockerfile之后,通過(guò)docker build命令來(lái)創(chuàng)建鏡像,該命令首先會(huì)上傳Dockerfile文件給Docker服務(wù)器端,服務(wù)器端將逐行執(zhí)行Dockerfile中定義的指令。
通常建議放置Dockerfile的目錄為空目錄。另外可以在目錄下創(chuàng)建.dockerignore文件,讓Docker忽略路徑下的文件和目錄,這一點(diǎn)與Git中的配置很相似。

通過(guò) -t 指定鏡像的標(biāo)簽信息,例如:docker build -t regenzm/first_image . ## "."指定的是Dockerfile所在的路徑

例:
簡(jiǎn)單 使用 Dockerfile文件事例

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容