摘要:例如,以下命令將啟動(dòng)一個(gè)默認(rèn)監(jiān)控端口的命令行參數(shù)將被追加到以形式的所有元素后面,并且覆蓋使用指定的所有元素。這種形式將使用處理代替環(huán)境變量,并且將忽略任何或者命令的命令行參數(shù)。下表顯示了對(duì)不同組合執(zhí)行的命令
Docker可以從Dockerfile中讀取指令來自動(dòng)構(gòu)建鏡像。Dockerfile是一個(gè)文本文件,它包含了用戶可以在命令調(diào)用以制作鏡像的命令。用戶可以使用docker build連續(xù)執(zhí)行一些命令行指令來開啟一個(gè)自動(dòng)構(gòu)建。
此文檔描述了在Dockerfile中可以使用的命令。當(dāng)你讀完這個(gè)文檔時(shí),請(qǐng)參閱Dockfile最佳實(shí)踐獲取進(jìn)階指南。
使用docker build命令從Dockerfile和上下文構(gòu)建鏡像。構(gòu)建上下文是特定路徑或URL的文件集合。該路徑是你本地文件系統(tǒng)的一個(gè)目錄。URL是一個(gè)Git倉庫地址。
上下文會(huì)被遞歸處理。所以,路徑包含的任意字母路合URL包含的倉庫及其子模塊也會(huì)被處理。一下實(shí)例展示了一個(gè)使用當(dāng)前目錄作為上下文的build命令:
$ docker build . Sending build context to Docker daemon 6.51 MB ...
構(gòu)建由Docker daemon執(zhí)行, 而非cli。構(gòu)建進(jìn)程的第一件事是(遞歸的)發(fā)送上下文給守護(hù)進(jìn)程(daemon)。在大多數(shù)情況下,最好以一個(gè)空目錄下作為上下文發(fā)送給守護(hù)進(jìn)程并且保持Dockerfile在該目錄下。只為構(gòu)建Dockerfile增加必須的文件。
CMDCMD指令有三種用法:
CMD ["executable","param1","param2"] (exec形式, 這是首選形式)
CMD ["param1","param2"] (作為ENTRYPOINT默認(rèn)參數(shù))
CMD command param1 param2 (shell 形式)
一個(gè)Dockerfile里只能有一個(gè)CMD指令。如果你有多個(gè)CMD指令,只有 最后一個(gè) 生效。
CMD的主要目的是為運(yùn)行容器提供默認(rèn)值。 默認(rèn)值可以包含一個(gè)可執(zhí)行文件,也忽略可執(zhí)行文件,在此情況下必須同時(shí)指定ENTRYPOINT指令。
注: 如果CMD用于為ENTRYPOINT指令提供默認(rèn)參數(shù),CMD和ENTRYPOINT都應(yīng)該使用json數(shù)組格式。注: exec形式傳遞json數(shù)組,意味著你必須使用雙引號(hào)(")而不是單引號(hào)(")引用字符
注: 與shell形式不同,exec形式不會(huì)像,那樣調(diào)用命令行shell。這意味著沒有通常的shell處理。例如,CMD [ "echo", "$HOME" ]將不會(huì)對(duì)$HOME做變量替換。如果你想使用shell處理可使用shell形式或直接執(zhí)行一個(gè)shell,例如:["sh", "-c", "echo $HOME"]。當(dāng)使用exec形式并且直接執(zhí)行一個(gè)shell,在這種情況下shell形式,執(zhí)行環(huán)境變量擴(kuò)展的是shell,而不是docker。
當(dāng)使用shell或exec格式時(shí),CMD指令設(shè)置鏡像運(yùn)行時(shí)執(zhí)行的命令。
如果你使用CMD的shell形式,
FROM ubuntu CMD echo "This is a test." | wc -
如果你想不使用shell運(yùn)行你的
FROM ubuntu CMD ["/usr/bin/wc","--help"]
如果你系統(tǒng)容器每次運(yùn)行相同的可執(zhí)行文件,你應(yīng)該考慮ENTRYPOINT和CMD結(jié)合使用。
如果用戶為docker run指定了參數(shù),那么他們將覆蓋CMD中指定的默認(rèn)參數(shù)。
注:不要混淆RUN和CMD。RUN實(shí)際上運(yùn)行命令并提交結(jié)果;CMD在構(gòu)建時(shí)什么都不執(zhí)行,只是指定鏡像將要執(zhí)行的命令。EXPOSE
EXPOSE[ ...]
EXPOSE指令通知Docker容器運(yùn)行時(shí)監(jiān)聽指定的網(wǎng)絡(luò)端口。EXPOSE不會(huì)使容器端口對(duì)宿主機(jī)可訪問。要那么做,你必須使用-p標(biāo)記來發(fā)布一系列端口或者-P標(biāo)記發(fā)布所有暴露端口。你可以暴露一個(gè)端口號(hào)并可以使用另一個(gè)端口對(duì)外發(fā)布。
要在宿主機(jī)系統(tǒng)上設(shè)置端口重定向,使用-P標(biāo)記。Docker網(wǎng)絡(luò)功能支持網(wǎng)絡(luò)內(nèi)創(chuàng)建網(wǎng)絡(luò)而不需要暴露端口,詳細(xì)信息請(qǐng)查看功能概述。
ADDADD有兩種形式:
ADD
ADD ["
ADD指令
ENTRYPOINTENTRYPOINT有2中形式:
ENTRYPOINT ["executable", "param1", "param2"] (exec 形式, 首選)
ENTRYPOINT command param1 param2 (shell 形式)
ENTRYPOINT允許你配置一個(gè)將作為可執(zhí)行程序運(yùn)行的容器。
例如,以下命令將啟動(dòng)一個(gè)nginx默認(rèn)監(jiān)控80端口:
docker run -i -t --rm -p 80:80 nginx
docker run
shell形式阻止任何CMD或者run的命令行參數(shù)被使用,但是有個(gè)弊端,你的ENTRYPOINT將被作為/bin/sh -c的一個(gè)子命令啟動(dòng),不能傳遞信號(hào)。這意味著可執(zhí)行程序不是容器ID為1的進(jìn)程 - 并且不會(huì)接受Unix信號(hào) - 所以你的可執(zhí)行程序不會(huì)接受來自docker stop
只有Dockerfile最后一個(gè)ENTRYPOINT指令會(huì)生效。
VOLUMEVOLUME ["/data"]
VOLUME指令創(chuàng)建一個(gè)具有指定名稱的掛載點(diǎn)并且將其標(biāo)記作為從宿主機(jī)或者其他容器外部掛載卷。值可以是一個(gè)JSON數(shù)組,VOLUME ["/var/log"],或者有多參數(shù)的純字符串,比如:VOLUME /var/log或者VOLUME /var/log /var/db。更多Docker客戶端的掛載指令信息/例子,移步文檔通過卷共享目錄。
docker run命令使用基礎(chǔ)鏡像內(nèi)指定位置存在的任意數(shù)據(jù)初始化新創(chuàng)建的卷。比如,認(rèn)為以下Dockerfile片段:
FROM ubuntu RUN mkdir /myvol RUN echo "hello world" > /myvol/greeting VOLUME /myvol
這個(gè)Dockerfile的結(jié)果是致使docker run會(huì)創(chuàng)建一個(gè)新的掛載點(diǎn)/myvol并且拷貝gretting文件到新創(chuàng)建的卷。
指定volumes的注意事項(xiàng)關(guān)于Dockerfile中的volumes,請(qǐng)注意以下事項(xiàng)。
基于Windows容器的Volumes: 當(dāng)使用基于Windows的容器,容器內(nèi)volume的目標(biāo)位置必須是以下之一:
一個(gè)不存在的或者空目錄
C盤以外的驅(qū)動(dòng)器:
從Dockerfile內(nèi)更改卷: 如果任何構(gòu)建步驟在volume聲明之后修改了數(shù)據(jù),這些修改將會(huì)被丟棄。
JSON 格式: 列表將會(huì)被作為一個(gè)JSON數(shù)組解析。你必須使用雙引號(hào)(")而不是單引號(hào)(")將單詞包起來。
主機(jī)目錄在容器運(yùn)行時(shí)聲明: 主機(jī)目錄(掛載點(diǎn))本質(zhì)上是與主機(jī)相關(guān)的。這是為了保證鏡像的可移植性。因?yàn)橐粋€(gè)指定的主機(jī)目錄不能保證在所有的主機(jī)上可用。因此,你不能在Dockerfile內(nèi)掛載一個(gè)主機(jī)目錄。VOLUME指令不支持指定一個(gè)主機(jī)目錄參數(shù)。你必須在容器創(chuàng)建或運(yùn)行時(shí)指定掛載點(diǎn)。
Exec形式ENTRYPOINT實(shí)例你可以使用ENTRYPOINT的exec形式設(shè)置相當(dāng)穩(wěn)定的默認(rèn)命令和參數(shù),然后使用CMD任意一種形式設(shè)置額外的更可能被修改的其他附加默認(rèn)值。
FROM ubuntu ENTRYPOINT ["top", "-b"] CMD ["-c"]
但你運(yùn)行該容器時(shí),你僅僅可以看到top進(jìn)程:
$ docker run -it --rm --name test top -H top - 08:25:00 up 7:27, 0 users, load average: 0.00, 0.01, 0.05 Threads: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 2056668 total, 1616832 used, 439836 free, 99352 buffers KiB Swap: 1441840 total, 0 used, 1441840 free. 1324440 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 19744 2336 2080 R 0.0 0.1 0:00.04 top
要進(jìn)一步檢查結(jié)果,可以使用docker exec:
$ docker exec -it test ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 2.6 0.1 19752 2352 ? Ss+ 08:24 0:00 top -b -H root 7 0.0 0.1 15572 2164 ? R+ 08:25 0:00 ps aux
并且你可以使用docker stop test請(qǐng)求top優(yōu)雅的退出。
以下Dockerfile展示了使用ENTRYPOINT在前端運(yùn)行Apache(例如,PID為1)。
FROM debian:stable RUN apt-get update && apt-get install -y --force-yes apache2 EXPOSE 80 443 VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"] ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
如果你需要為單個(gè)可執(zhí)行程序?qū)懸粋€(gè)啟動(dòng)腳本,你可以使用exec和gosu命令來確保最終執(zhí)行程序可以收到Unix信號(hào)。
#!/usr/bin/env bash set -e if [ "$1" = "postgres" ]; then chown -R postgres "$PGDATA" if [ -z "$(ls -A "$PGDATA")" ]; then gosu postgres initdb fi exec gosu postgres "$@" fi exec "$@"
最后,如果你需要在退出時(shí)做一些額外的清理(或者與其他容器通信),或者配合執(zhí)行多個(gè)可執(zhí)行文件,你可能需要確保ENTRYPOINT腳本接受Unix信號(hào),傳遞他們并做更多工作:
#!/bin/sh # Note: I"ve written this using sh so it works in the busybox container too # USE the trap if you need to also do manual cleanup after the service is stopped, # or need to start multiple services in the one container trap "echo TRAPed signal" HUP INT QUIT TERM # start service in background here /usr/sbin/apachectl start echo "[hit enter key to exit] or run "docker stop"" read # stop service and clean up here echo "stopping apache" /usr/sbin/apachectl stop echo "exited $0"
如果你使用docker run -it -p 80:80 --name test apache運(yùn)行該鏡像,然后你可以使用docker exec檢查容器進(jìn)程,或者docker top,并且可以通過腳本停止Apache。
$ docker exec -it test ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.1 0.0 4448 692 ? Ss+ 00:42 0:00 /bin/sh /run.sh 123 cmd cmd2 root 19 0.0 0.2 71304 4440 ? Ss 00:42 0:00 /usr/sbin/apache2 -k start www-data 20 0.2 0.2 360468 6004 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start www-data 21 0.2 0.2 360468 6000 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start root 81 0.0 0.1 15572 2140 ? R+ 00:44 0:00 ps aux $ docker top test PID USER COMMAND 10035 root {run.sh} /bin/sh /run.sh 123 cmd cmd2 10054 root /usr/sbin/apache2 -k start 10055 33 /usr/sbin/apache2 -k start 10056 33 /usr/sbin/apache2 -k start $ /usr/bin/time docker stop test test real 0m 0.27s user 0m 0.03s sys 0m 0.03s
注:你可以使用--entrypoint覆蓋ENTRYPOINT配置,但是這只會(huì)將二進(jìn)制設(shè)置為exec(sh -c不會(huì)被使用)。Shell形式ENTRYPOINT實(shí)例注:exec形式被解析為JSON數(shù)組,意味著你必須使用雙引號(hào)(")包裹單詞而不是單引號(hào)(")。
注:不像shell形式,exec形式并不會(huì)調(diào)用shell命令。這意味著不會(huì)做普通的shell處理。例如,ENTRIPOIN ["echo", "$HOME"]將不能對(duì)$HOME做變量置換。如果你既想shell處理又想使用shell形式或直接執(zhí)行一shell,例如:ENTRYPOINT ["sh", "-c", "echo $HOME"]。當(dāng)使用exec形式和直接執(zhí)行shell時(shí),在shell形式這種情況下,是shell做的環(huán)境變量擴(kuò)展,而不是docker。
你可以為ENTRYPOINT指定一個(gè)純文本的字符串,它會(huì)以/bin/sh -c的形式運(yùn)行。這種形式將使用shell處理shell代替shell環(huán)境變量,并且將忽略任何CMD或者docker run命令的命令行參數(shù)。為了確保docker stop能夠正常發(fā)出信號(hào)給任何長時(shí)間運(yùn)行的ENTRYPOINT可執(zhí)行文件,您需要記住使用exec啟動(dòng)它:
FROM ubuntu ENTRYPOINT exec top -b
當(dāng)你啟動(dòng)鏡像,你會(huì)看到PID為1的進(jìn)程:
$ docker run -it --rm --name test top Mem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cached CPU: 5% usr 0% sys 0% nic 94% idle 0% io 0% irq 0% sirq Load average: 0.08 0.03 0.05 2/98 6 PID PPID USER STAT VSZ %VSZ %CPU COMMAND 1 0 root R 3164 0% 0% top -b
它將會(huì)在執(zhí)行docker stop時(shí)徹底退出:
$ /usr/bin/time docker stop test test real 0m 0.20s user 0m 0.02s sys 0m 0.04s
如果你忘記了在ENTRYPOINT開頭增加exec:
FROM ubuntu ENTRYPOINT top -b CMD --ignored-param1
你可以啟動(dòng)它(為了下一步給它指定名稱):
$ docker run -it --name test top --ignored-param2 Mem: 1704184K used, 352484K free, 0K shrd, 0K buff, 140621524238337K cached CPU: 9% usr 2% sys 0% nic 88% idle 0% io 0% irq 0% sirq Load average: 0.01 0.02 0.05 2/101 7 PID PPID USER STAT VSZ %VSZ %CPU COMMAND 1 0 root S 3168 0% 0% /bin/sh -c top -b cmd cmd2 7 1 root R 3164 0% 0% top -b
你可以看到top的輸出,ENTRYPOINT指定的不是PID 1。
如果你接下來執(zhí)行docker stop test,容器不會(huì)被徹底退出 - 超時(shí)以后top命令會(huì)被發(fā)送一個(gè)SIGKILL。
$ docker exec -it test ps aux PID USER COMMAND 1 root /bin/sh -c top -b cmd cmd2 7 root top -b 8 root ps aux $ /usr/bin/time docker stop test test real 0m 10.19s user 0m 0.04s sys 0m 0.03s理解CMD和ENTRYPOINT如何交互
CMD和ENTRYPOINT指令都定義了當(dāng)啟動(dòng)一個(gè)容器時(shí)執(zhí)行什么命令。描述他們?nèi)绾我黄鸸ぷ鞯囊?guī)則很少。
Dockerfile至少應(yīng)該指定一個(gè)CMD或ENTRYPOINT命令。
當(dāng)容器做一個(gè)可執(zhí)行程序時(shí),ENTRYPOINT應(yīng)該被定義。
CMD應(yīng)該被用作一種給ENTRYPOINT定義默認(rèn)參數(shù)的方式,或在容器中執(zhí)行ad-hoc命令的方式。
當(dāng)運(yùn)行容器時(shí)是用了交互參數(shù)時(shí),CMD將被會(huì)被覆蓋。
下表顯示了對(duì)不同ENTRYPOINT / CMD組合執(zhí)行的命令:
No ENTRYPOINT | ENTRYPOINT exec_entry p1_entry | ENTRYPOINT [“exec_entry”, “p1_entry”] | |
---|---|---|---|
No CMD | error, not allowed | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry |
CMD [“exec_cmd”, “p1_cmd”] | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry exec_cmd p1_cmd |
CMD [“p1_cmd”, “p2_cmd”] | p1_cmd p2_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry p1_cmd p2_cmd |
CMD exec_cmd p1_cmd | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/28083.html
摘要:比如和指令,鏡像中的文件內(nèi)容被檢查并且為每個(gè)文件計(jì)算校驗(yàn)和。這些文件的最終修改和訪問時(shí)間將不被考慮到校驗(yàn)和內(nèi)。在查找緩存期間,校驗(yàn)和將被用于與已存在的鏡像校驗(yàn)和進(jìn)行對(duì)比。 Docker 可以從 Dockerfile 中讀取指令自動(dòng)構(gòu)建鏡像,Dockerfile是一個(gè)包含構(gòu)建指定鏡像所有命令的文本文件。Docker堅(jiān)持使用特定的格式并且使用特定的命令。你可以在 Dockerfile參考 ...
摘要:在前一篇文章學(xué)習(xí)與和應(yīng)用一初步認(rèn)識(shí)中,我們初步介紹了解決了什么問題,容器化技術(shù)與傳統(tǒng)的虛擬化方式的區(qū)別,以及簡要介紹了的幾大核心概念鏡像容器和倉庫。針對(duì)上述問題,提供了的,通過使用指令配置的方式來創(chuàng)建鏡像。 在前一篇文章 Docker學(xué)習(xí)與和應(yīng)用(一)_初步認(rèn)識(shí)中,我們初步介紹了Docker解決了什么問題,Docker容器化技術(shù)與傳統(tǒng)的虛擬化方式的區(qū)別,以及簡要介紹了Docker的幾大...
摘要:更多的內(nèi)容可以參考深入理解一命令參考的用法咧實(shí)例的寫法已經(jīng)講述完畢,這兒有一個(gè)示例的指定系統(tǒng)我抄的他的創(chuàng)建私鑰修復(fù)登錄,否則登陸后的用戶會(huì)被秒退。 本系列教程翻譯自 Flux7 Docker Tutorial Series,系列共有九篇,本文譯自第三篇 Part 3: Automation is the Word Using DockerFile。 該系列所有文章將參考其他學(xué)...
摘要:更多的內(nèi)容可以參考深入理解一命令參考的用法咧實(shí)例的寫法已經(jīng)講述完畢,這兒有一個(gè)示例的指定系統(tǒng)我抄的他的創(chuàng)建私鑰修復(fù)登錄,否則登陸后的用戶會(huì)被秒退。 本系列教程翻譯自 Flux7 Docker Tutorial Series,系列共有九篇,本文譯自第三篇 Part 3: Automation is the Word Using DockerFile。 該系列所有文章將參考其他學(xué)...
閱讀 1158·2023-04-26 00:12
閱讀 3344·2021-11-17 09:33
閱讀 1088·2021-09-04 16:45
閱讀 1233·2021-09-02 15:40
閱讀 2255·2019-08-30 15:56
閱讀 3010·2019-08-30 15:53
閱讀 3584·2019-08-30 11:23
閱讀 1963·2019-08-29 13:54