Dockerfile自定義鏡像
1) Dockerfile介紹
Dockerfile 是自動構(gòu)建 docker鏡像的配置文件, 用戶可以使用 Dockerfile 快速創(chuàng)建自定義的鏡像桶蝎。Dockerfile 中的命令非常類似于linux 下的 shell 命令耐薯。
我們可以通過下面這幅圖來直觀地感受下 Docker 鏡像偎巢、容器和 Dockerfile 三者之間的關(guān)系血淌。
image.png
我們從上圖中可以看到注祖, Dockerfile 可以自定義鏡像皱碘,通過 Docker 命令去運行鏡像询一,從而達(dá)到啟動容器的目的。
2) Dockerfile的基本結(jié)構(gòu)
Dockerfile 是由一行行命令語句組成癌椿,并且支持已 # 開頭的注釋行健蕊。
一般來說,我們可以將 Dockerfile 分為四個部分:
基礎(chǔ)鏡像(父鏡像)信息指令 FROM
維護(hù)者信息指令 MAINTAINER
鏡像操作指令 RUN 踢俄、 EVN 绊诲、 ADD 和 WORKDIR 等
容器啟動指令 CMD 、ENTRYPOINT 和 USER 等
3)使用 Dockerfile 定制鏡像/自定義鏡像
Q
為什么要自定義Docker鏡像?
A
工作中Docker中的鏡像并不滿足工作的需要褪贵,需要進(jìn)行自己的配置掂之。
Docker Hub 中 99% 的鏡像都是通過在base 鏡像中安裝和配置需要的軟件構(gòu)建出來的
4) 使用 Docker build 構(gòu)建鏡像創(chuàng)建容器的步驟
第一步 編寫Dockerfile文件
第二步 Docker build
第三步 Docker run
4-1 企業(yè)案例通過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)在我們需要自定義一個鏡像來支持 VIM脆丁、ifconfig世舰、并且登錄后的默認(rèn)路徑改做修改。
企業(yè)級案例
一槽卫、拉一個基礎(chǔ)centos鏡像
docker pull centos
二跟压、編寫dockerfile文件
vim Dockerfile
#從哪一個基礎(chǔ)鏡像構(gòu)建
FROM centos
#定義作者的信息
MAINTAINER 1907
#定義一個變量
ENV newpath /tmp
#設(shè)置登錄以后工作路徑(落腳點)
WORKDIR $newpath
#干了什么(執(zhí)行你要的操作)
RUN yum install -y vim
RUN yum install -y net-tools
##如果有更多的需求 。歼培。震蒋。RUN
#開放指定的端口
EXPOSE 80
EXPOSE 22
#執(zhí)行命令
CMD echo $newpath
CMD echo "success ok"
CMD /bin/bash
~
三、通過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
四 通過Docker run 創(chuàng)建容器,,驗證vim 以及net-tools
通過我們自定義的鏡像創(chuàng)建容器
image.png
測試ifconfig命令 OK
測試vim 命令OK
image.png
看看構(gòu)建過程是否是如前面所說躲庄,這也證實了鏡像的分層
image.png
4)Dockerfile鏡像分層
dockerfile中的每一條命令查剖,都會構(gòu)建一層文件。
以下圖的Dockerfile為例分析構(gòu)建過程
當(dāng)容器啟動時噪窘,一個新的可寫層被加載到鏡像的頂部笋庄。這一層通常被稱作“容器層”,“容器層”之下的都叫“鏡像層”。
image.png
所有對容器的改動 - 無論添加直砂、刪除菌仁、還是修改文件都只會發(fā)生在容器層中。
只有容器層是可寫的静暂,容器層下面的所有鏡像層都是只讀的济丘。
下面我們深入討論容器層的細(xì)節(jié)。
鏡像層數(shù)量可能會很多洽蛀,所有鏡像層會聯(lián)合在一起組成一個統(tǒng)一的文件系統(tǒng)闪盔。如果不同層中有一個相同路徑的文件,比如 /a辱士,上層的 /a 會覆蓋下層的 /a泪掀,也就是說用戶只能訪問到上層中的文件 /a。在容器層中颂碘,用戶看到的是一個疊加之后的文件系統(tǒng)异赫。
1.添加文件
在容器中創(chuàng)建文件時,新文件被添加到容器層中头岔。
讀取文件
在容器中讀取某個文件時塔拳,Docker 會從上往下依次在各鏡像層中查找此文件。一旦找到峡竣,打開并讀入內(nèi)存靠抑。
修改文件
在容器中修改已存在的文件時,Docker 會從上往下依次在各鏡像層中查找此文件适掰。一旦找到颂碧,立即將其復(fù)制到容器層,然后修改之类浪。
刪除文件
在容器中刪除文件時载城,Docker 也是從上往下依次在鏡像層中查找此文件。找到后费就,會在容器層中記錄下此刪除操作诉瓦。
只有當(dāng)需要修改時才復(fù)制一份數(shù)據(jù),這種特性被稱作 Copy-on-Write力细〔窃瑁可見,容器層保存的是鏡像變化的部分眠蚂,不會對鏡像本身進(jìn)行任何修改煞聪。
這樣就解釋了我們前面提出的問題:容器層記錄對鏡像的修改,所有鏡像層都是只讀的河狐,不會被容器修改米绕,所以鏡像可以被多個容器共享瑟捣。
5) Dockerfile指令詳解
一張圖搞定Dockerfile常見命令
image.png
Dockerfile中包括FROM馋艺、MAINTAINER栅干、RUN、CMD捐祠、EXPOSE碱鳞、ENV、ADD踱蛀、COPY窿给、ENTRYPOINT、VOLUME率拒、USER崩泡、WORKDIR、ONBUILD等13個指令猬膨。
FROM
格式為FROM image或FROM image:tag角撞,并且Dockerfile中第一條指令必須是FROM指令,且在同一個Dockerfile中創(chuàng)建多個鏡像時勃痴,可以使用多個FROM指令谒所。
MAINTAINER
格式為MAINTAINER user_name user_email,指定維護(hù)者信息
RUN
格式為RUN command或 RUN ["EXECUTABLE","PARAM1","PARAM2".....]沛申,前者在shell終端中運行命令劣领,/bin/sh -c command,例如:/bin/sh -c "echo hello"铁材;后者使用exec執(zhí)行尖淘,指定其他運行終端使用RUN["/bin/bash","-c","echo hello"]
每條RUN指令將當(dāng)前的鏡像基礎(chǔ)上執(zhí)行指令,并提交為新的鏡像著觉,命令較長的時候可以使用\來換行德澈。
CMD
支持三種格式:
CMD ["executable","param1","param2"],使用exec執(zhí)行固惯,這是推薦的方式梆造。
CMD command param1 param2 在/bin/sh中執(zhí)行。
CMD ["param1","param2"] 提供給ENTERYPOINT的默認(rèn)參數(shù)葬毫。
CMD用于指定容器啟動時執(zhí)行的命令镇辉,每個Dockerfile只能有一個CMD命令,多個CMD命令只執(zhí)行最后一個贴捡。若容器啟動時指定了運行的命令忽肛,則會覆蓋掉CMD中指定的命令。
EXPOSE
格式為 EXPOSE port [port2,port3,...]烂斋,例如EXPOSE 80這條指令告訴Docker服務(wù)器暴露80端口屹逛,供容器外部連接使用础废。
在啟動容器的使用使用-P,Docker會自動分配一個端口和轉(zhuǎn)發(fā)指定的端口罕模,使用-p可以具體指定使用哪個本地的端口來映射對外開放的端口评腺。
ENV
格式為:EVN key value 。用于指定環(huán)境變量淑掌,這些環(huán)境變量蒿讥,后續(xù)可以被RUN指令使用,容器運行起來之后抛腕,也可以在容器中獲取這些環(huán)境變量芋绸。
例如
ENV word hello
RUN echo $word
ADD
格式:ADD src dest
該命令將復(fù)制指定本地目錄中的文件到容器中的dest中,src可以是一個絕對路徑担敌,也可以是一個URL或一個tar文件摔敛,tar文件會自動解壓為目錄。
COPY
格式為:COPY src desc
復(fù)制本地主機src目錄或文件到容器的desc目錄全封,desc不存在時會自動創(chuàng)建马昙。
ENTRYPOINT
格式有兩種:
ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1,param2 會在shell中執(zhí)行。
用于配置容器啟動后執(zhí)行的命令售貌,這些命令不能被docker run提供的參數(shù)覆蓋给猾。和CMD一樣,每個Dockerfile中只能有一個ENTRYPOINT颂跨,當(dāng)有多個時最后一個生效敢伸。
VOLUME
格式為 VOLUME ["/data"]
作用是創(chuàng)建在本地主機或其他容器可以掛載的數(shù)據(jù)卷,用來存放數(shù)據(jù)恒削。
USER
格式為:USER username
指定容器運行時的用戶名或UID池颈,后續(xù)的RUN也會使用指定的用戶。要臨時使用管理員權(quán)限可以使用sudo钓丰。在USER命令之前可以使用RUN命令創(chuàng)建需要的用戶躯砰。
例如:RUN groupadd -r docker && useradd -r -g docker docker
WORKDIR
格式: WORKDIR /path
為后續(xù)的RUN CMD ENTRYPOINT指定配置工作目錄,可以使用多個WORKDIR指令携丁,若后續(xù)指令用得是相對路徑琢歇,則會基于之前的命令指定路徑。
ONBUILD
格式ONBUILD [INSTRUCTION]
該配置指定當(dāng)所創(chuàng)建的鏡像作為其他新建鏡像的基礎(chǔ)鏡像時所執(zhí)行的指令梦鉴。
例如下面的Dockerfile創(chuàng)建了鏡像A:
ONBUILD ADD . /app
ONBUILD RUN python app.py
則基于鏡像A創(chuàng)建新的鏡像時李茫,新的Dockerfile中使用from A 指定基鏡像時,自動執(zhí)行ONBBUILD指令內(nèi)容肥橙,等價于在新的要構(gòu)建鏡像的Dockerfile中增加了兩條指令:
FROM A
ADD ./app
RUN python app.py
docker build
創(chuàng)建好Dockerfile之后魄宏,通過docker build命令來創(chuàng)建鏡像,該命令首先會上傳Dockerfile文件給Docker服務(wù)器端存筏,服務(wù)器端將逐行執(zhí)行Dockerfile中定義的指令宠互。
通常建議放置Dockerfile的目錄為空目錄味榛。另外可以在目錄下創(chuàng)建.dockerignore文件,讓Docker忽略路徑下的文件和目錄予跌,這一點與Git中的配置很相似搏色。
通過 -t 指定鏡像的標(biāo)簽信息澈段,例如:docker build -t regenzm/first_image . ## "."指定的是Dockerfile所在的路徑
例:
簡單 使用 Dockerfile文件事例