天天看点

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