Docker CMD评估与ENTRYPOINT
我有一个Dockerfile属于理解CMD和ENTRYPOINT如何交互的matrix中的exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
类别。 行为不是我所期待的。 我期待/bin/sh -c exec_cmd p1_cmd
先评估,然后传递到exec_entry p1_entry
。 我正在观察的是/bin/sh -c exec_cmd p1_cmd
从字面上被传递到exec_entry p1_entry
,我认为这很有趣。
为了提供更多的上下文,我特别从现有的Dockerfile中派生出一个新的Dockerfile,其中父代有:
ENTRYPOINT ["/bin/registrator"]
我想从我的Dockerfile传递特定的命令行参数:
FROM gliderlabs/registrator:v7 CMD echo "-ip=$EXTERNAL_IP consul://$CONSUL_HOST"
当我在一个容器中运行我的Docker镜像时:
$ docker run --rm --name=test-registrator --volume=/var/run/docker.sock:/tmp/docker.sock -e "EXTERNAL_IP=<some-ip>" -e "CONSUL_HOST=<some-consul-hostname>:8500" my/registrator
我得到以下错误:
2016/12/28 19:20:46 Starting registrator v7 ... Extra unparsed arguments: -c echo "-ip=$EXTERNAL_IP consul://$CONSUL_HOST" Options should come before the registry URI argument. Usage of /bin/registrator: /bin/registrator [options] <registry URI> -cleanup=false: Remove dangling services -deregister="always": Deregister exited services "always" or "on-success" -internal=false: Use internal ports instead of published ones -ip="": IP for ports mapped to the host -resync=0: Frequency with which services are resynchronized -retry-attempts=0: Max retry attempts to establish a connection with the backend. Use -1 for infinite retries -retry-interval=2000: Interval (in millisecond) between retry-attempts. -tags="": Append tags for all registered services -ttl=0: TTL for services (default is no expiry) -ttl-refresh=0: Frequency with which service TTLs are refreshed
这意味着-c echo "-ip=$EXTERNAL_IP consul://$CONSUL_HOST"
实际上是作为参数传入/bin/registrator
。
我做错了什么,或者这是/bin/sh -c exec_cmd p1_cmd
在进入入口点之前没有被首先/bin/sh -c exec_cmd p1_cmd
的用例限制? 如果后者是真的,那么你也可以解释这个用例的用处吗?
是。 这正是它应该如何工作。
CMD的值只是作为parameter passing给入口点。
CMD和ENTRYPOINT之间的主要区别在于,CMD只是为ENTRYPOINT程序提供了默认的命令参数,并且它通常被运行命令的参数所覆盖。 另一方面,如果要执行不同的命令,则必须使用–entrypoint选项明确地重新定义ENTRYPOINT。
另外请注意,根据在Dockerfile中定义ENTRYPOINT和CMD的方式,事情是如何执行的。 当它们以['arg1','arg2']的forms被定义为数组时,该数组被原样传递给ENTRYPOINT命令,并且ENTRYPOINT的第一个元素是被执行的程序。 在另一种情况下,当它们被定义为像arg1 arg2这样的简单string时,首先传递的string被前缀“/ bin / sh -c”注意,Docker不执行/ bin / sh并返回评估结果,string本身被传递给ENTRYPOINT程序。
所以在你的情况下,你必须使用传递参数的数组方法:
CMD [-ip, $EXTERNAL_IP, consul://$CONSUL_HOST]