天天看點

Dockerfile中CMD指令和ENTRYPOINT 指令的說明

首先說明下RUN、CMD、ENTRYPOINT 等指令都可以用來執行指令,但是各有不同的特點

RUN 在Build Image的時候執行。

CMD ENTRYPOINT 在運作Image時執行。

CMD 可以和ENTRYPOINT 搭配使用,也可以單個指令使用。當CMD 和ENTRYPOINT都出現在一個DockerFile中時,CMD中設定的資訊(EXEC格式的)都以參數的形式提供給ENTRYPOINT指令。EntryPoint 指令沒有設定時,預設是/bin/bash

ENTRYPOINT的指令不可以簡單被覆寫,但可以使用run 中的--entrypoint被覆寫,如果docker run時提供參數,這些參數附加在ENTRYPOINT 裡面設定的内容後面。

CMD 單獨使用時,如果run 指令後面中提供參數,那麼參數會完全覆寫CMD

來看一個例子可以很好的說明以上情況,我們的大概步驟是建立一個簡單的Docker Image ,使用Echo指令來看CMD指令和ENTRYPOINT指令在單獨使用、組合使用等情況下的差別。

第一次我們的Dockerfile 如下,我隻使用CMD指令

FROM centos MAINTAINER [email protected] CMD ["/bin/dir","/bin"] chef@chef:~/dockerfiles/cmd_entrypoint$ docker build -t echotest:cmd -f Dockerfile_cmd . Sending build context to Docker daemon 4.096 kB Step 1 : FROM centos ---&gt; 87e5b6b3ccc1 Step 2 : MAINTAINER [email protected] ---&gt; Using cache ---&gt; a9bea6e7d663 Step 3 : CMD /bin/dir /bin ---&gt; Running in abc9360528ee ---&gt; 07103bc09e6f Removing intermediate container abc9360528ee Successfully built 07103bc09e6f 然後我們執行run ,不提供任何參數 <a href="http://s3.51cto.com/wyfs02/M00/87/3E/wKioL1fY55_BHp4gAAAhDzkZ0tA562.png"></a> 然後我們提供參數的情況下: chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it echotest:cmd /bin/echo # 以上指令沒有任何輸出,正常情況下應該是下面輸出(因為我們CMD指令中提供的是/bin/dir指令: chef@chef:~/dockerfiles/cmd_entrypoint$ dir /bin/echo /bin/echo # 我接着執行下面指令,發現我們提供的參數完全替換了CMD中的所有指令(/bin/dir /bin 被/bin/echo test 完全替換了,驗證了前面總結的第5點) chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it echotest:cmd /bin/echo test test

第二個測試,我們的Dockerfile内容如下,我們測試僅使用Entrypoint的情況。

chef@chef:~/dockerfiles/cmd_entrypoint$ cat Dockerfile_entrypoint ENTRYPOINT ["/bin/echo","defaultParam"] #CMD ["/bin/dir","/bin"] # 然後我們Build 另外一個image echotest:entrypoint chef@chef:~/dockerfiles/cmd_entrypoint$ docker build -t echotest:entrypoint -f Dockerfile_entrypoint . Step 3 : ENTRYPOINT /bin/echo defaultParam ---&gt; Running in f17009dd0dc1 ---&gt; 9f7dab52dc3a Removing intermediate container f17009dd0dc1 Successfully built 9f7dab52dc3a # 以預設參數執行 chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it echotest:entrypoint defaultParam # 提供參數情況下,我們發現param1 并不像CMD一樣,CMD是拿docker run 提供的參數完全覆寫CMD内容,而ENTRYPOINT是把參數附加到ENTRYPOINT内容後面。 chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it echotest:entrypoint param1 defaultParam param1 # 如果想替換 ENTRYPONT 的内容,可以使用docker run --entrypointdocker chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it --entrypoint /bin/ping echotest:entrypoint param1 ping: unknown host param1 chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it --entrypoint /bin/ping echotest:entrypoint localhost PING localhost (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.051 ms 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.128 ms 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.058 ms 64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.068 ms ^C --- localhost ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 2997ms rtt min/avg/max/mdev = 0.051/0.076/0.128/0.031 ms PING cn.a-0001.a-msedge.net (202.89.233.103) 56(84) bytes of data. 64 bytes from 202.89.233.103: icmp_seq=1 ttl=115 time=37.1 ms 64 bytes from 202.89.233.103: icmp_seq=2 ttl=115 time=37.2 ms 64 bytes from 202.89.233.103: icmp_seq=3 ttl=115 time=36.9 ms 64 bytes from 202.89.233.103: icmp_seq=4 ttl=115 time=36.7 ms

第三個測試,我們的Dockerfile内容如下,我們測試同時使用Entrypoint和CMD的情況。

先看Dockerfile内容,我這裡故意把CMD和ENTRYPOINT中執行的指令設定成不同的 chef@chef:~/dockerfiles/cmd_entrypoint$ cat Dockerfile_cmd_and_entrypoint chef@chef:~/dockerfiles/cmd_entrypoint$ docker build -t echotest:entrypointAndCmd -f Dockerfile_cmd_and_entrypoint . Step 4 : CMD /bin/dir /bin ---&gt; Running in 0bb1e042a2a0 ---&gt; 91eb9487a88a Removing intermediate container 0bb1e042a2a0 Successfully built 91eb9487a88a # 我這裡發現當同時存在ENTRYPOINT和CMD指令時,使用預設參數執行時,會把CMD 中的内容以參數的形式提供給ENTRYPOINT 指令。等下我們看看在Dockerfile 中把ENTRYPOINT指令和CMD指令出現的順序對調,看是否有影響。 chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it echotest:entrypointAndCmd defaultParam /bin/dir /bin # 執行有參數的情況,CMD中的内容完全被我們在docker run 提供的參數替代了,然後以參數提供給ENTRYPOINT指令。 chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it echotest:entrypointAndCmd paramCus defaultParam paramCus # 使用docker run --entrypoint 覆寫ENTRYPOINT内容。 chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it --entrypoint /bin/ls echotest:entrypointAndCmd paramCus /bin/ls: cannot access paramCus: No such file or directory chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it --entrypoint /bin/ls echotest:entrypointAndCmd /sbin addgnupghome build-locale-archive cracklib-packer fsck.cramfs grpck # 這裡測試下Dockerfile中如果CMD和ENTRYPOINT指令的順序如果和上面的颠倒,是否對結果有影響,結果是發現沒有影響。 chef@chef:~/dockerfiles/cmd_entrypoint$ cat Dockerfile chef@chef:~/dockerfiles/cmd_entrypoint$ docker build -t echotest . Sending build context to Docker daemon 5.12 kB Step 4 : ENTRYPOINT /bin/echo defaultParam ---&gt; Running in 091b72e36f4f ---&gt; b01150245beb Removing intermediate container 091b72e36f4f Successfully built b01150245beb chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it echotest chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it echotest paramCus chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it --entrypoint /bin/ls echotest paramCus chef@chef:~/dockerfiles/cmd_entrypoint$ docker run --rm -it --entrypoint /bin/ls echotest /sbin

清理現場:

chef@chef:~/dockerfiles/cmd_entrypoint$ docker images echotest* REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE echotest latest b01150245beb 4 minutes ago 224 MB echotest entrypointAndCmd 91eb9487a88a 17 minutes ago 224 MB echotest entrypoint 9f7dab52dc3a 26 minutes ago 224 MB echotest cmd 07103bc09e6f 38 minutes ago 224 MB chef@chef:~/dockerfiles/cmd_entrypoint$ docker rmi $(docker images -q echotest*) Untagged: echotest:latest Deleted: b01150245bebc9ff2c44ed259861a5466fbaf1f9bc8339a4ed965e38299e3380 Untagged: echotest:entrypointAndCmd Deleted: 91eb9487a88a70af6e91568018b11ca52574d47ffaed8b2600f24897027252d8 Untagged: echotest:entrypoint Deleted: 9f7dab52dc3a33693743ffc34b463f820b3e954291927d73ca09e29c43fde80a Untagged: echotest:cmd Deleted: 07103bc09e6f918199f4a9f34dd13f4bf1eaab8bf415d5b70e360dc6885b5f9b 本文轉自 yoke88 51CTO部落格,原文連結: http://blog.51cto.com/yoke88/1852696