中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Dockerfile怎么構建鏡像

發布時間:2022-02-16 15:09:18 來源:億速云 閱讀:124 作者:iii 欄目:開發技術

這篇文章主要介紹“Dockerfile怎么構建鏡像”,在日常操作中,相信很多人在Dockerfile怎么構建鏡像問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Dockerfile怎么構建鏡像”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

Dockerfile構建鏡像是以基礎鏡像為基礎的,Dockerfile是一個文本文件,內容是用戶編寫的一些docker指令,每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。

Dockerfile怎么構建鏡像

1.基于容器制作

聯合文件系統(UnionFS)掛載提供了容器的文件系統,任何對容器內文件系統的改動都會被寫入到新的文件層中,這個文件層歸創建它的容器所有。而我們就對做出改動的容器進行鏡像構建。我這兒使用 busybox 作為 base image,我們可以認為 busybox 為一個精簡的 linux 系統。在 busybox 上運行一個 httpd 程序,并將其制作為鏡像文件。 1.拉取鏡像

~]# docker image pull busybox:latest  #默認會從dockerhub上拉取...
~]# docker image lsREPOSITORY    TAG       IMAGE ID        CREATED             SIZE
busybox      latest    59788edf1f3e    2 months ago        1.15MB
12345

2.運行鏡像

~]# docker container run --name bbox -it busybox:latest  #啟動鏡像,并交互式登錄1

3.運行httpd busybox 自帶有 httpd 程序

/ # httpd -hUsage: httpd [-ifv[v]] [-c CONFFILE] [-p [IP:]PORT] [-u USER[:GRP]] [-r REALM] [-h HOME]
   httpd -d/-e/-m STRING
       -i              Inetd mode
       -f              Don't daemonize
       -v[v]           Verbose
       -p [IP:]PORT    Bind to IP:PORT (default *:80)
       -u USER[:GRP]   Set uid/gid after binding to port
       -r REALM        Authentication Realm for Basic Authentication
       -h HOME         Home directory (default .)
       -c FILE         Configuration file (default {/etc,HOME}/httpd.conf)
       -m STRING       MD5 crypt STRING
       -e STRING       HTML encode STRING
       -d STRING       URL decode STRING

/ # mkdir /data/html  #家目錄
/ # echo "httpd server" >> /data/html/index.html  #測試頁
/ # httpd -h /data/html  #指定家目錄,啟動服務
123456789101112131415161718

4.鏡像制作 新打開一個控制臺

~]# docker container commit --helpUsage:  docker container commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Options:
  -a, --author string    Author (e.g., "John Hannibal Smith ")
  -c, --change list      Apply Dockerfile instruction to the created image
  -m, --message string   Commit message
  -p, --pause            Pause container during commit (default true)

~]# docker container commit -p bbox test/mybbox:v0.1  #-p制作鏡像時,容器暫停運行,防止在制作鏡像時有數據寫入~]# docker image lstest/mybbox      v0.1     e07687dd8546    1 minutes ago     1.15MB
1234567891011

注:若是想對版本號或者鏡像名稱進行修改,可使用docker tag命令,但是修改后不會覆蓋原鏡像,會新生成一個鏡像,類似于硬鏈接。

5.更改啟動命令 當我們運行mybbox時,會發現雖然文件都有,但是并沒有運行httpd服務,這是因為每個鏡像都有一個運行時啟動的初始命令,我們若想鏡像啟動時就運行某個命令,需要我們在制作鏡像時就指定。

~]# docker image inspect -f {{.Config.Cmd}} test/mybbox:v0.1[sh]      #可見 mybbox 鏡像還是使用 busybox 的初始命令。~]# docker container commit -a "test " -c 'CMD ["/bin/httpd,"-h /data/html"]' -p bbox test/mybbox:v0.2~]# docker image inspect -f {{.Config.Cmd}} test/mybbox:v0.2        [/bin/sh -c ["/bin/httpd,"-h /data/html"]]
123456

6.推送至倉庫 鏡像制作完成,就可以推送至倉庫,默認是推送到dockerhub,我們可以自己在 dockerhub 創建賬號并創建倉庫,然后本地 docker login 登錄,就可以將本地鏡像 push 上去。需要注意的是在 dockerhub 上創建倉庫時,命名空間要為test,倉庫名為 mybbox(對于本次實驗),必須要嚴格一致。由于我這兒登不了 dockerhub,就不在演示了。

7.保存鏡像至本地 當鏡像制作好,可保存到本地進行分發,也就不需要上傳到倉庫了。

~]# docker image save -o /tmp/mybbox.gz test/mybbox:v0.2 #-o指定保存目錄,也可多個鏡像一起保存~]# docker image load -i /tmp/mybbox.gz   #使用時導入即可12

2. 基于Dockerfile制作鏡像

其實我們發現,基于容器構建鏡像,在對配置變動頻繁或需要重復構建鏡像時,效率是非常低下的。所以我們就需要使用Dockerfile來實現快速構建鏡像,Dockerfile是一個文件,它由構建鏡像的指令組成,指令由Docker鏡像構建者自上而下排列,能夠被用來修改鏡像的任何信息。

注意事項:

  1. Dockerfile文件需放置在一個目錄中,這個目錄中有構建鏡像的所有文件,可以創建子目錄。
  2. 在Dockerfile文件中,”#“號開頭表示注釋,每行為”INSTRUCTION arguments”,習慣大寫表示關鍵字(但并不區分大小寫),后面小寫表示值。
  3. 每個Dockerfile的第一行(注釋行除外),必須使用”FROM”關鍵字。
  4. 當我們在docker build構建鏡像時,會將我們的指定的上下文目錄(即Dockerfile所在目錄)打包傳遞給docker 引擎,而這個上下文中并非所有文件都會在Dockerfile中使用,這樣就會使傳送給docker引擎的目錄過大,影響構建速度,所以可以在此目錄中,定義.dockerignore文件,將不使用的文件文件名寫入到該文件即可,且支持通配符。
  5. 最小化鏡像的層數,Dockerfile中每一行命令就是一層,層數過多影響構建效率。
  6. Dockerfile文件中命令從上往下逐行執行。

2.1 Dockerfile命令

1.FROM: FROM 指令是最重的一個且必須為 Dockerfile 文件開篇的第一個非注釋行,用于為映像文件構建過程指定基準鏡像,后續的指令運行于此基準鏡像所提供的運行環境。實踐中,基準鏡像可以是任何可用鏡像文件,默認情況下,docker build 會在 docker 主機上查找指定的鏡像文件,在其不存在時,則會從Docker Hub Registry 上拉取所需的鏡像文件如果找不到指定的鏡像文件,docker build 會返回一個錯誤信息。

Syntax:
FROM [:]
FROM @ :指定作為base image的名稱,默認從dockerhub拉取鏡像,若使用其他倉庫可在鏡像前指定; :base image的標簽,為可選項,省略時默認為latest;

eg:
FROM busybox:latest
123456789

2.MAINTAINER: 用于讓鏡像制作者提供本人的詳細信息,Dockerfile 并不限制 MAINTAINER 指令可在出現的位置,但推薦將其放置于 FROM 指令之后,已經被 LABEL 取代,但仍可使用。

Syntax:
MAINTAINER 's detail>

s detail>:可是任何文本信息,但約定俗成地使用作者名稱及郵件地址
1234

3.LABEL: 效果同上,指定多個元數據

Syntax:
 LABEL = [= ...]

eg:
LABEL name=test mail=test@163.com
12345

4.COPY: 用于從 Docker 主機復制文件至創建的新映像文件

Syntax:
COPY  ... COPY ["",... ""]  :要復制的源文件或目錄,支持使用通配符 :目標路徑,即正在創建的image的文件系統路徑;
     建議為使用絕對路徑否則,COPY指定則以WORKDIR為其起始路徑;

文件復制準則:
1.必須是build上下文中的路徑,不能是其父目錄中的文件
2.如果是目錄,則其內部文件或子目錄會被遞歸復制,但目錄自身不會被復制
3.如果指定了多個,或在中使用了通配符,則必須是一個目錄,且必須以/結尾
4.如果事先不存在,它將會被自動創建,這包括其父目錄路徑

eg:
COPY index.html /data/web/  #最后不加斜線會改名為webCOPY src/ /data/web    #src/* 被拷貝到/data/web目錄下COPY test1 test2 /data/web/  #多文件最后必須加/123456789101112131415161718

5.ADD: ADD指令類似于 COPY 指令,ADD 支持使用 TAR 文件和 URL 路徑

Syntax:
ADD  ... ADD ["",... ""]

操作準則:同COPY指令
1.如果為URL且不以/結尾,則指定的文件將被下載并直接被創建為;
  如果以/結尾,則文件名URL指定的文件將被直接下載并保存為/。
2.如果是一個本地系統上的壓縮格式的tar文件,它將被展開為一個目錄,其行為類似于“tar -x”命令;
  然而,通過URL獲取到的tar文件將不會自動展開;
3.如果有多個,或其間接或直接使用了通配符,則必須是一個以/結尾的目錄路徑;
  如果不以/結尾,則其被視作一個普通文件,的內容將被直接寫入到;

eg:
ADD http://nginx.org/download/nginx-1.14.2.tar.gz  /data/  #nginx-1.14.2.tar.gz會放在/data/目錄下,不會解壓ADD nginx-1.14.2.tar.gz /date  #nginx-1.14.2目錄會放在/data/目錄下,會解壓123456789101112131415

6.WORKDIR: 用于為 Dockerfile 中所有的 RUN、CMD、ENTRYPOINT、COPY 和 ADD 指定設定工作目錄,其生效范圍為本次定義workdir到下一次定義之間,且還會影響到進入容器時的目錄

Syntax:
WORKDIR 注:在Dockerfile文件中,WORKDIR指令可出現多次,其路徑也可以為相對路徑,不過,其是相對此前一個WORKDIR指令指定的路徑另外,
WORKDIR也可調用由ENV指定定義的變量

eg:
WORKDIR /var/logWORKDIR $STATEPATH123456789

7.VOLUME: 用于在 image 中創建一個掛載點目錄,以掛載 Docker host 上的卷或其它容器上的卷,但需要注意的是此選項只能創建容器管理的卷,即在宿主機上隨機掛載一個目錄,而不能指定目錄掛載

Syntax:
VOLUME VOLUME [""]

注:如果掛載點目錄路徑下此前有文件存在,docker run 命令會在卷掛載完成后將此前的所有文件復制到新掛載的卷中。

eg:
VOLUME /data  #不能指定宿主機目錄,隨機掛載在 /var/lib/docker/volumes/...12345678

8.EXPOSE: 用于為容器打開指定要監聽的端口以實現與外部通信,但不能指定宿主機的端口綁定,并且即使在 Dockerfile 中定義了 EXPOSE ,也必須要在啟動容器時手動加上 -P 選項才會生效。

Syntax:
EXPOSE [/] [[/] ...]用于指定傳輸層協議,可為tcp或udp二者之一,默認為TCP協議

eg:
EXPOSE 11211/udp 11211/tcp #EXPOSE指令可一次指定多個端口123456

9.ENV: 用于為鏡像定義所需的環境變量,并可被 Dockerfile 文件中位于其后的其它指令(如ENV、ADD、COPY等)所調用,調用格式為 {variable_name}。

Syntax:
ENV   或
ENV = ...

注:
1.第一種格式中,之后的所有內容均會被視作其的組成部分,因此,一次只能設置一個變量;
2.第二種格式可用一次設置多個變量,每個變量為一個"="的鍵值對,如果中包含空格,可以以反斜線(\)進行轉義,
  也可通過對加引號進行標識;另外,反斜線也可用于續行;
3.定義多個變量時,建議使用第二種方式,以便在同一層中完成所有功能
4.docker run時可以使用 -e 參數指定環境變量,相同環境變量會覆蓋Dockerfile中的值

eg:
ENV name=zhang \
 age=15 \
 sex=N
123456789101112131415

10.ARG: 此參數和 ENV 有些相似,都是指定變量值,但是在使用 ENV 時,若要動態的傳遞變量值,只能在 docker run 時才能傳遞,而 ARG 可以在 docker build 過程中,通過–build-arg 來進行動態傳遞參數值。除此之外,ENV 的值會保留在鏡像的環境變量中,但 ARG 的值不會保存。所以若想在 build 鏡像的過程中修改變量的值,推薦使用 ARG

用法同上,下圖說明了構建過程,RUN 與 CMD 指令見下面介紹

Dockerfile怎么構建鏡像
在這里插入圖片描述

11.RUN: 用于指定 docker build 過程中運行的命令,其可以是基礎鏡像中存在的任何命令,見下圖所示。

Syntax:
RUN command>
RUN ["", "", ""]

注:
1.第一種格式中,command>通常是一個shell命令,且以“/bin/sh -c”來運行它,這意味著此進程在容器中的PID不為1,不能接收Unix信號,
  因此,當使用docker stop 命令停止容器時,此進程接收不到SIGTERM信號;即在運行該命令前會先起一個sh進程,然后運行此命令。
2.第二種語法格式中的參數是一個JSON格式的數組,其中為要運行的命令,后面的為傳遞給命令的選項或參數;
  然而,此種格式指定的命令不會以“/bin/sh -c”來發起,因此常見的shell操作如變量替換以及通配符(?,*等)替換將不會運行;
  不過,如果要運行的命令依賴于此shell特性的話,可以將其替換為類似的格式:RUN ["/bin/bash", "-c", "", ""]

eg:
RUN ls /data  #將會在構建的時候執行 "ls /data"命令RUN ["/bin/sh","-c","mkdir -p /data/hello"]
1234567891011121314

12.CMD: 類似于RUN指令,CMD 指令也可用于運行任何命令或應用程序,不過,二者的運行時間點不同,RUN指令運行于映像文件構建過程中(docker build),而CMD指令運行于基于 Dockerfile 構建出的新映像文件啟動一個容器時(docker run),CMD 指令的首要目的在于為啟動的容器指定默認要運行的程序,且其運行結束后,容器也將終止;不過,CMD 指定的命令其可以被 docker run 的命令行選項所覆蓋,在 Dockerfile 中可以存在多個 CMD 指令,但僅最后一個會生效。

Syntax:
CMD command>
CMD ["","",""]
CMD ["",""]

注:前兩種語法格式的意義同RUN,第一種用法雖然會先起sh進程,但是執行完command后,sh進程會退出,并由command的進程替代為1號進程,第三種則用于為ENTRYPOINT指令提供默認參數。

eg:
CMD /bin/httpd -f -h $DOC_ROOT #如下可見在運行命令之前會預先運sh命令~]# docker image inspect -f {{.Config.Cmd}} test [/bin/sh -c /bin/httpd -f -h $DOC_ROOT]

~]# docker container run --name NAME -it --rm IMAGE_NAME /bin/bash  #CMD 指定的命令可在 docker run 時指定命令修改12345678910111213

13.ENTRYPOINT: 類似 CMD 指令的功能,用于為容器指定默認運行程序,從而使得容器像是一個單獨的可執行程序,與 CMD 不同的是,由 ENTRYPOINT 啟動的程序不會被 docker run 命令行指定的參數所覆蓋,而且,這些命令行參數會被當作參數傳遞給 ENTRYPOINT 指定指定的程序。不過,docker run 命令的 –entrypoint 選項的參數可覆蓋 ENTRYPOINT 指令指定的程序。

Syntax:
ENTRYPOINT command>
ENTRYPOINT ["", "", ""]

注:
1.docker run命令傳入的命令參數會覆蓋CMD指令的內容并且附加到ENTRYPOINT命令最后做為其參數使用。
2.Dockerfile文件中也可以存在多個ENTRYPOINT指令,但僅有最后一個會生效。

eg:
CMD ["/bin/ls","/etc"]
ENTRYPOINT ["/bin/bash","-c"]  #會先啟動sh進程,CMD指定的命令會被當做參數傳給 /bin/bash -c~]# docker container run --name NAME -it --rm IMAGE_NAME /bin/bash  #使用entrypoint時,docker run時動態指定的命令將會被當做參數傳遞給entrypoint定義的命~]# docker container run --name NAME -it --rm --entrypoint "/bin/bash" IMAGE_NAME #entrypoint指定的命令可以在docker run時添加的 --entrypoint 后的命令所覆蓋1234567891011121314

14.USER: 用于指定運行image時的或運行 Dockerfile 中任何 RUN、CMD 或 ENTRYPOINT 指令指定的程序時的用戶名或 UID,默認情況下,container 的運行身份為root用戶。

Syntax:
USER |注:需要注意的是,可以為任意數字,但實踐中其必須為/etc/passwd中某用戶的有效UID,否則,docker run命令將運行失敗。
1234

15.HEALTHCHECK: 對容器進行健康狀態檢測。

Syntax:
HEALTHCHECK [OPTIONS] CMD commandOPTIONS:
--interval:多長時間檢測一次,默認30s
--timeout:超時時長,默認30s
--start-period:容器啟動后多久開始檢測,默認30s
--retries:重試次數:默認3次

響應碼:
0:success
1:unhealthy
2:reserved

eg:
HEALTHECK --interval=5m --timeout=30s CMD curl -f http://localhost/ || exit 1
12345678910111213141516

16.SHELL: 在使用 RUN、CMD 等命令時,有些格式在運行命令前會先啟動一個sh進程,默認使用的是 /bin/sh,但在有些時候我們需要改變默認的 SHELL。

Syntax:
SHELL ["executable","parameters"]
12

17.STOPSIGAL: 默認的 stop-signal 是 SIGTERM,在 docker stop 的時候會給容器內 PID 為1的進程發送這個 signal,通過 –stop-signal 可以設置自己需要的 signal,主要的目的是為了讓容器內的應用程序在接收到 signal 之后可以先做一些事情,實現容器的平滑退出,如果不做任何處理,容器將在一段時間之后強制退出,會造成業務的強制中斷,這個時間默認是10s。這個命令很少用到。

18.ONBUILD: 用于在 Dockerfile 中定義一個觸發器,Dockerfile 用于 build 映像文件,此映像文件亦可作為 base imag 被 另一個 Dockerfile 用作 FROM 指令的參數,并以之構建新的映像文件,在后面的這個 Dockerfile 中的 FROM 指令在 build 過程中被執行時,將會“觸發”創建其 base image 的 Dockerfile 文件中的 ONBUILD 指令定義的觸發器。簡單來說,就是別人基于你的鏡像重新制作鏡像時才會觸發此命令。

Syntax:
ONBUILD 注:
1.盡管任何指令都可注冊成為觸發器指令,但ONBUILD不能自我嵌套,且不會觸發FROM和MAINTAINER指令
2.使用包含ONBUILD指令的Dockerfile構建的鏡像應該使用特殊的標簽,例如ruby:2.0-onbuild
3.在ONBUILD指令中使用ADD或COPY指令應該格外小心,因為新構建過程的上下文在缺少指定的源文件時會失敗
123456

2.2 簡單示例

容器運行nginx:

~]# mkdir myng~]# cd myng~]# cat Dockerfile#Dockerfile for my nginxFROM nginx:1.14-alpine

LABEL maintainer="chuan "ENV DOC_ROOT="/data/web/html/"#ARG參數不會寫到容器的環境變量中,所以在此環境下,PORT不會傳遞給配置中的變量,此處應使用ENV#ARG PORT=80ENV PORT=80

COPY entrypoint.sh /bin/
ADD index.html $DOC_ROOTEXPOSE ${PORT}/tcp

ENTRYPOINT ["/bin/entrypoint.sh"]
CMD ["/usr/sbin/nginx","-g","daemon off;"]

HEALTHCHECK --interval=10s --start-period=10s CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT:-80}/index.html

~]# cat index.htmlhello world~]# cat entrypoint.sh    #exec命令表示用將要執行的進程代替當前進程,否則此程序將作為sh的子進程運行#!/bin/sh#cat > /etc/nginx/conf.d/www.conf $HOSTNAME;
        listen ${IP:-0.0.0.0}:${PORT:-8080};
        root ${DOC_ROOT:-/usr/share/nginx/html};
}
EOFexec "$@"~]# chmod a+x entrypoint.sh~]# docker image build . -t  test/myweb:v0.1  #PATH 要為Dockerfile文件的父目錄123456789101112131415161718192021222324252627282930313233343536373839404142

容器運行httpd:

~]# mkdir ap~]# cd ap~]# cat Dockerfile#Dockerfile for my httpdFROM centos:7

LABEL maintainer="chuan "ENV doc_root=/var/www/html \
       listen_port=80 \
    server_name=localhost

RUN yum makecache && \
    yum install -y httpd php php-mysql && \
    yum clean all

ADD phpinfo.php ${doc_root}ADD entrypoint.sh /bin/

EXPOSE 80/tcp

VOLUME ${doc_root}CMD ["/usr/sbin/httpd","-DFOREGROUND"]
ENTRYPOINT ["/bin/entrypoint.sh"]

]# cat phpinfo.php

~]# cat entrypoint.sh#!/bin/bashLISTEN_PORT=${listen_port:-80}SERVER_NAME=${server_name:-localhost}DOC_ROOT=${doc_root:-/var/www/html}cat > /etc/httpd/conf.d/myweb.conf $LISTEN_PORT$LISTEN_PORT>
        ServerName "$SERVER_NAME"        DocumentRoot "$DOC_ROOT"        "$DOC_ROOT">
                Options none
                AllowOverride none
                Require all granted
        EOFexec "$@"~]# chmod a+x entrypoint.sh~]# docker image build . -t  test/myweb:v0.2~]# docker container run --name myweb2 --rm -P test/myweb:v0.2

到此,關于“Dockerfile怎么構建鏡像”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

清流县| 加查县| 托克托县| 夏津县| 汝阳县| 尤溪县| 札达县| 鄂伦春自治旗| 荔浦县| 五莲县| 石河子市| 梨树县| 会理县| 甘孜| 济源市| 油尖旺区| 河南省| 双桥区| 富蕴县| 高平市| 徐水县| 手游| 突泉县| 安平县| 绥中县| 科技| 望奎县| 本溪市| 怀柔区| 施秉县| 巴塘县| 樟树市| 双鸭山市| 西乌珠穆沁旗| 襄垣县| 长寿区| 定远县| 新河县| 海南省| 科技| 安阳县|