Dockerfile 用於自動化構建一個docker鏡像。Dockerfile裏有 CMD 與 ENTRYPOINT 兩個功能咋看起來很類似的指令,開始的時候以爲兩個互用沒什麼所謂,但其實並不是如此:linux
CMD指令:docker
The main purpose of a CMD is to provide defaults for an executing container.shell
CMD在容器運行的時候提供一些命令及參數,用法以下:ubuntu
如你指定:bash
build後運行(假設鏡像名爲ec):ide
就會輸出: this is a echo testoop
是否是感受很像開機啓動項,你能夠暫時這樣理解。ui
注意點:this
docker run命令若是指定了參數會把CMD裏的參數覆蓋: (這裏說明一下,如:docker run -it ubuntu /bin/bash 命令的參數是指/bin/bash 而非 -it ,-it只是docker 的參數,而不是容器的參數,如下所說參數均如此。)spa
一樣是上面的ec鏡像啓動:
docker run ec /bin/bash
就不會輸出:this is a echo test,由於CMD命令被」/bin/bash」覆蓋了。
ENTRYPOINT
字面意思是進入點,而它的功能也恰如其意。
An ENTRYPOINT allows you to configure a container that will run as an executable.它可讓你的容器功能表現得像一個可執行程序同樣。
容器功能表現得像一個可執行程序同樣,這是什麼意思呢?
直接給個例子好說話:
例子一:
使用下面的ENTRYPOINT構造鏡像:
那麼docker build出來的鏡像之後的容器功能就像一個/bin/echo程序:
好比我build出來的鏡像名稱叫imageecho,那麼我能夠這樣用它:
這裏就會輸出」this is a test」這串字符,而這個imageecho鏡像對應的容器表現出來的功能就像一個echo程序同樣。 你添加的參數「this is a test」會添加到ENTRYPOINT後面,就成了這樣 /bin/echo 「this is a test」 。如今你應該明白進入點的意思了吧。
例子二:
ENTRYPOINT ["/bin/cat"]
構造出來的鏡像你能夠這樣運行(假設名爲st):
這樣至關: /bin/cat /etc/fstab 這個命令的做用。運行以後就輸出/etc/fstab裏的內容。
ENTRYPOINT有兩種寫法:
寫法一:
寫法二:
你也能夠在docker run 命令時使用–entrypoint指定(可是隻能用寫法一)。
下面是我把ENTRYPOINT設爲[「/bin/sh -c」]時候運行的狀況:
能夠看到PID爲1的進程運行的是sh,而bash只是sh的一個子進程,/bin/bash只是做爲 /bin/sh -c後面的參數。
CMD能夠爲ENTRYPOINT提供參數,ENTRYPOINT自己也能夠包含參數,可是你能夠把那些可能須要變更的參數寫到CMD裏而把那些不須要變更的參數寫到ENTRYPOINT裏面例如:
把可能須要變更的參數寫到CMD裏面。而後你能夠在docker run裏指定參數,這樣CMD裏的參數(這裏是-c)就會被覆蓋掉而ENTRYPOINT裏的不被覆蓋。
注意點1:
ENTRYPOINT有兩種寫法,第二種(shell form)會屏蔽掉docker run時後面加的命令和CMD裏的參數。
注意點2:
網上有資料說ENTRYPOINT的默認值是[」/bin/sh -c」],可是筆者在試驗的時候獲得的結果並非這樣的。
筆者使用ENTRYPOINT [「/bin/sh -c」] 指令構造一個以/bin/sh -c爲進入點的鏡像,命名爲sh,而後我能夠這樣運行:
運行結果就是無限輸出loop。但若是直接運行一個ubuntu:14.10鏡像,狀況不是這樣的:
獲得這樣的錯誤:
能夠猜測默認狀況下ENTRYPOINT並非[「/bin/sh -c」]。
並且直接運行ubuntu:14.10列出程序也能夠看到PID爲1的程序並非sh。因此更否認了網友的說法,ENTRYPOINT並不默認爲[「/bin/sh -c」] 。