本篇文章給大家分享的是有關(guān)怎么在docker中利用Dockerfile構(gòu)建鏡像,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

1、使用 commit 命令構(gòu)建
docker commit 命令是創(chuàng)建新鏡像最直觀的方法,其過(guò)程包含三個(gè)步驟:
運(yùn)行容器;
修改容器;
將容器保存為新的鏡像。
先從創(chuàng)建一個(gè)新容器開(kāi)始,這個(gè)容器我們就使用很常見(jiàn)的 ubuntu 鏡像,操作步驟如下
1.1 運(yùn)行一個(gè)要進(jìn)行修改的容器
root@ubuntu:~# docker run -ti ubuntu /bin/bash root@733a4b080491:/#
1.2 安裝 Apache 軟件包
root@733a4b080491:/# apt-get update ... ... root@733a4b080491:/# apt-get install -y apache2 ... ...
我們啟動(dòng)了一個(gè)容器,并在里面安裝了 Apache 。我們將會(huì)拿這個(gè)容器作為一個(gè) Web 服務(wù)器來(lái)運(yùn)行,我們需要把它保存下來(lái),這樣就不用每次都運(yùn)行這個(gè)步驟了。
1.3 提交定制容器
root@ubuntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 733a4b080491 ubuntu "/bin/bash" 11 minutes ago Exited (0) 5 seconds ago suspicious_mestorf
root@ubuntu:~# docker commit 733a4b080491 wzlinux/ubuntu_with_apache sha256:902ac2c87147fefc5b70c741ce9550dcda426cea9f824f442d5cc2744bdc90ae
root@ubuntu:~# docker images REPOSITORY TAG IMAGE ID CREATED SIZE wzlinux/ubuntu_with_apache latest 902ac2c87147 33 seconds ago 261MB ubuntu latest 20c44cd7596f 10 days ago 123MB
可以看到,我們使用 docker commit 提交了修改過(guò)的容器,從 size 上可以看到鏡像因?yàn)榘惭b軟件而變大了,docker commit 提交的只是創(chuàng)建容器的鏡像與容器的當(dāng)前狀態(tài)之間有差異的部分,這使得該更新非常輕量。
以上演示了如何用 docker commit 創(chuàng)建新鏡像。然而,Docker 并不建議用戶通過(guò)這種方式構(gòu)建鏡像。因?yàn)檫@是一種手工創(chuàng)建鏡像的方式,容易出錯(cuò),效率低且可重復(fù)性弱。比如要在 debian base 鏡像中也加入 apache,還得重復(fù)前面的所有步驟。更重要的:使用者并不知道鏡像是如何創(chuàng)建出來(lái)的,里面是否有惡意程序。也就是說(shuō)無(wú)法對(duì)鏡像進(jìn)行審計(jì),存在安全隱患。
不過(guò),為了對(duì) Docker 有一個(gè)更全面的了解,我們還是要了解一下如何使用 docker commit 構(gòu)建 Docker 鏡像。因?yàn)榧幢闶怯?Dockerfile(推薦方法)構(gòu)建鏡像,底層也 docker commit 一層一層構(gòu)建新鏡像的。學(xué)習(xí) docker commit 能夠幫助我們更加深入地理解構(gòu)建過(guò)程和鏡像的分層結(jié)構(gòu)。
2、使用 Dockerfile 構(gòu)建
Dockerfile 使用基本的基于DSL(Domain Specific Language)語(yǔ)法的指令來(lái)構(gòu)建一個(gè) Docker 鏡像,我們推薦使用 Dockerfile 方法來(lái)代替 docker commit,因?yàn)橥ㄟ^(guò)前者構(gòu)建鏡像更具備可重復(fù)性、透明性以及冪等性。
一旦有了 Dockerfile,我們就可以使用 docker build 命令基于該 Dockerfile 中的指令構(gòu)建一個(gè)新的鏡像。
2.1 我們的第一個(gè) Dockerfile
用 Dockerfile 創(chuàng)建上面的 ubuntu_with_apache,內(nèi)容如下。
# Version 0.0.1 FROM ubuntu RUN sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list RUN sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list RUN apt-get -y update && apt-get -y install apache2 EXPOSE 80
執(zhí)行 docker build 命令時(shí),Dockerfile 中的所有指令都會(huì)被執(zhí)行并且提交,并且在該命令成功結(jié)束后返回一個(gè)新鏡像。
root@ubuntu:~/sample# docker build -t ubuntu_with_apache_dockerfile . ① Sending build context to Docker daemon 6.144kB ② Step 1/5 : FROM ubuntu ③ ---> 20c44cd7596f Step 2/5 : RUN sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list ---> Running in bac6dc3b900f ---> c66ad94ad8a4 Removing intermediate container bac6dc3b900f Step 3/5 : RUN sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list ---> Running in 5158558b6403 ---> 0a4c480147c5 Removing intermediate container 5158558b6403 Step 4/5 : RUN apt-get -y update && apt-get -y install apache2 ④ ---> Running in f547ce7a1b39 ⑤ …… …… ---> 118bde35120a ⑥ Removing intermediate container f547ce7a1b39 ⑦ Step 5/5 : EXPOSE 80 ---> Running in e546786de05b ---> f55d7b07365b Removing intermediate container e546786de05b Successfully built f55d7b07365b ⑧ Successfully tagged ubuntu_with_apache_dockerfile:latest

① 運(yùn)行 docker build 命令,-t 將新鏡像命名為 ubuntu-with-apache-dockerfile,命令末尾的 . 指明 build context 為當(dāng)前目錄。Docker 默認(rèn)會(huì)從 build context 中查找 Dockerfile 文件,我們也可以通過(guò) -f 參數(shù)指定 Dockerfile 的位置。
② 從這步開(kāi)始就是鏡像真正的構(gòu)建過(guò)程。 首先 Docker 將 build context 中的所有文件發(fā)送給 Docker daemon。build context 為鏡像構(gòu)建提供所需要的文件或目錄。
Dockerfile 中的 ADD、COPY 等命令可以將 build context 中的文件添加到鏡像。此例中,build context 為當(dāng)前目錄 /sample,該目錄下的所有文件和子目錄都會(huì)被發(fā)送給 Docker daemon。
所以,使用 build context 就得小心了,不要將多余文件放到 build context,特別不要把 /、/usr 作為 build context,否則構(gòu)建過(guò)程會(huì)相當(dāng)緩慢甚至失敗。
③ Step 1:執(zhí)行 FROM,將 ubuntu 作為 base 鏡像。ubuntu 鏡像 ID 為 452a96d81c30。
④ Step 4:執(zhí)行 RUN,安裝 apache,具體步驟為 ⑤ ~ ?。
⑤ 啟動(dòng) ID 為 e38bc83df8b1 的臨時(shí)容器,在容器中通過(guò) apt-get 安裝 apache。
⑥ 安裝成功后,將容器保存為鏡像,其 ID 為 fbc9af08328d。這一步底層使用的是類似 docker commit 的命令。
⑦ 刪除臨時(shí)容器 02a4f3243dda。
⑧ 鏡像構(gòu)建成功。
通過(guò) docker images 查看鏡像信息。
root@ubuntu:~/sample# docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu_with_apache_dockerfile latest f55d7b07365b 27 minutes ago 261MB wzlinux/ubuntu_with_apache latest 902ac2c87147 About an hour ago 261MB ubuntu latest 20c44cd7596f 10 days ago 123MB
2.2 查看鏡像分成結(jié)構(gòu)
ubuntu_with_apache_dockerfile 是通過(guò)在 base 鏡像的頂部添加幾個(gè)新的鏡像層而得到的。

上圖是從原文中拷貝的,下圖是在我的電腦上面實(shí)驗(yàn)得到的數(shù)據(jù),IMAGE的ID不同,但是其他都是相同的。

查看我本機(jī)的Ubuntu的IMAGE歷史如下:

從輸出的結(jié)果可以看出來(lái),每個(gè)命令都會(huì)生成一個(gè)鏡像層。
docker history 會(huì)顯示鏡像的構(gòu)建歷史,也就是 Dockerfile 的執(zhí)行過(guò)程。
ubuntu_with_apache_dockerfile 與 ubuntu 鏡像相比,確實(shí)只是多了幾層,Dockerfile 中的每個(gè)指令都會(huì)創(chuàng)建一層,docker history 也向我們展示了鏡像的分層結(jié)構(gòu),每一層由上至下排列。
2.3 鏡像的緩存特性
由于每一步的構(gòu)建過(guò)程都會(huì)將結(jié)果提交為鏡像,所以 Docker 的構(gòu)建鏡像過(guò)程就顯得非常聰明。它會(huì)將之前的鏡像層看作緩存。
比如我們把 EXPOSE 80 改為 EXPOSE 8080。
root@ubuntu:~/sample# docker build -t ubuntu_with_apache_8080 . Sending build context to Docker daemon 6.144kB Step 1/5 : FROM ubuntu ---> 20c44cd7596f Step 2/5 : RUN sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list ---> Using cache ---> c66ad94ad8a4Step 3/5 : RUN sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list ---> Using cache ---> 0a4c480147c5 Step 4/5 : RUN apt-get -y update && apt-get -y install apache2 ---> Using cache ---> 118bde35120a Step 5/5 : EXPOSE 8080 ---> Running in c89f8210c56a ---> ac88967e578e Removing intermediate container c89f8210c56a Successfully built ac88967e578e Successfully tagged ubuntu_with_apache_8080:latest
我們可以看到,之前的指令都是一樣的,所以 docker 直接利用之前的緩存,只構(gòu)建我們更改的指令,新的鏡像層如下。

如果我們希望在構(gòu)建鏡像時(shí)不使用緩存,可以在 docker build 命令中加上 --no-cache 參數(shù)。
Dockerfile 中每一個(gè)指令都會(huì)創(chuàng)建一個(gè)鏡像層,上層是依賴于下層的。無(wú)論什么時(shí)候,只要某一層發(fā)生變化,其上面所有層的緩存都會(huì)失效。也就是說(shuō),如果我們改變 Dockerfile 指令的執(zhí)行順序,或者修改或添加指令,都會(huì)使緩存失效。比如我們?cè)谇懊嫣砑又噶?MAINTAINER wzlinux "admin@wzlinux.com"。如下:
# Version 0.0.1 FROM ubuntu MAINTAINER wzlinux "admin@wzlinux.com" RUN sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list RUN sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list RUN apt-get -y update && apt-get -y install apache2 EXPOSE 80
然后使用docker進(jìn)行構(gòu)建,查看其過(guò)程。
root@ubuntu:~/sample# docker build -t ubuntu_with_apache_author . Sending build context to Docker daemon 6.144kB Step 1/6 : FROM ubuntu ---> 20c44cd7596f Step 2/6 : MAINTAINER wzlinux "admin@wzlinux.com" ---> Running in 637bb3457407 ---> 829b24531d69 Removing intermediate container 637bb3457407 Step 3/6 : RUN sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list ---> Running in 416ae8aefb61 ---> 84643fe8447a Removing intermediate container 416ae8aefb61 Step 4/6 : RUN sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list ---> Running in 58d8375fd5c3 ---> 1cb5776982d3 Removing intermediate container 58d8375fd5c3 Step 5/6 : RUN apt-get -y update && apt-get -y install apache2 ---> Running in 0514a7d04814 …… …… Processing triggers for sgml-base (1.26+nmu4ubuntu1) ... ---> 30eb21527fee Removing intermediate container 0514a7d04814 Step 6/6 : EXPOSE 80 ---> Running in 476ca5f98886 ---> 30672998f3d0 Removing intermediate container 476ca5f98886 Successfully built 30672998f3d0 Successfully tagged ubuntu_with_apache_author:latest

從輸出的結(jié)果生成了很多新的鏡像層,緩存已經(jīng)失效。
2.4 調(diào)試 Dockerfile
包括 Dockerfile 在內(nèi)的任何腳本和程序都會(huì)出錯(cuò)。有錯(cuò)并不可怕,但必須有辦法排查,那我們測(cè)試一下在構(gòu)建的過(guò)程中指令出現(xiàn)錯(cuò)誤怎么辦,比如我們把第二個(gè)sed指令寫錯(cuò)了,寫錯(cuò)了sd。
# Version 0.0.1 FROM ubuntu MAINTAINER wzlinux "admin@wzlinux.com" RUN sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list RUN sd -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list RUN apt-get -y update && apt-get -y install apache2 EXPOSE 80
執(zhí)行 docker build,如下。

Dockerfile 在執(zhí)行第四步 RUN 指令時(shí)失敗。我們可以利用第三步創(chuàng)建的鏡像 84643fe8447a 進(jìn)行調(diào)試,方式是通過(guò) docker run -it 啟動(dòng)鏡像的一個(gè)容器。
root@ubuntu:~/sample# docker run -ti 84643fe8447a /bin/bash root@422ecce78664:/# sd bash: sd: command not found
其實(shí)我們肯定不會(huì)傻到連 sd 不存在也不知道,我這里只是作為一個(gè)例子,其他更難的排錯(cuò)方法我們就使用這種方式。
2.5 Dockerfile 指令
FROM
指定 base 鏡像。
MAINTAINER
設(shè)置鏡像的作者,可以是任意字符串。
COPY
將文件從 build context 復(fù)制到鏡像。
COPY 支持兩種形式:
COPY src destCOPY ["src", "dest"]
注意:src 只能指定 build context 中的文件或目錄。
ADD
與 COPY 類似,從 build context 復(fù)制文件到鏡像。不同的是,如果 src 是歸檔文件(tar, zip, tgz, xz 等),文件會(huì)被自動(dòng)解壓到 dest。
ENV
設(shè)置環(huán)境變量,環(huán)境變量可被后面的指令使用。例如:
ENV MY_VERSION 1.3RUN apt-get install -y mypackage=$MY_VERSION
EXPOSE
指定容器中的進(jìn)程會(huì)監(jiān)聽(tīng)某個(gè)端口,Docker 可以將該端口暴露出來(lái)。
VOLUME
將文件或目錄聲明為 volume。
WORKDIR
為后面的 RUN, CMD, ENTRYPOINT, ADD 或 COPY 指令設(shè)置鏡像中的當(dāng)前工作目錄。
RUN
在容器中運(yùn)行指定的命令。
CMD
容器啟動(dòng)時(shí)運(yùn)行指定的命令。
Dockerfile 中可以有多個(gè) CMD 指令,但只有最后一個(gè)生效。CMD 可以被 docker run 之后的參數(shù)替換。
ENTRYPOINT
設(shè)置容器啟動(dòng)時(shí)運(yùn)行的命令。
Dockerfile 中可以有多個(gè) ENTRYPOINT 指令,但只有最后一個(gè)生效。CMD 或 docker run 之后的參數(shù)會(huì)被當(dāng)做參數(shù)傳遞給 ENTRYPOINT。
以上就是怎么在docker中利用Dockerfile構(gòu)建鏡像,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)站標(biāo)題:怎么在docker中利用Dockerfile構(gòu)建鏡像-創(chuàng)新互聯(lián)
文章來(lái)源:http://chinadenli.net/article28/dgpjjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、網(wǎng)站排名、品牌網(wǎng)站設(shè)計(jì)、定制開(kāi)發(fā)、微信小程序、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容