Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 带入口点的Docker CMD评估_Shell_Docker_Dockerfile_Consul_Registrator - Fatal编程技术网

Shell 带入口点的Docker CMD评估

Shell 带入口点的Docker CMD评估,shell,docker,dockerfile,consul,registrator,Shell,Docker,Dockerfile,Consul,Registrator,我有一个Dockerfile,它属于中的矩阵中的exec\u entry p1\u entry/bin/sh-c exec\u cmd p1\u cmd类别。这种行为不是我所期望的。我希望/bin/sh-c exec\u cmd p1\u cmd首先进行评估,然后传递到exec\u entry p1\u entry。我观察到的是,/bin/sh-c exec_cmd p1_cmd实际上被传递到exec_entry p1_entry,我认为这很有趣 为了提供更多的上下文,我特别从一个新的Docke

我有一个Dockerfile,它属于中的矩阵中的
exec\u entry p1\u entry/bin/sh-c exec\u cmd p1\u cmd
类别。这种行为不是我所期望的。我希望
/bin/sh-c exec\u cmd p1\u cmd
首先进行评估,然后传递到
exec\u entry p1\u 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
$docker run--rm--name=测试注册器--volume=/var/run/docker.sock:/tmp/docker.sock-e“EXTERNAL\u IP=“-e”consu\u HOST=: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
2016/12/28 19:20:46开始注册v7。。。
额外的未分析参数:
-c echo“-ip=$EXTERNAL\u ip consur://$consur\u HOST”
选项应位于注册表URI参数之前。
使用/bin/注册器:
/银行标识代码/登记人[选项]
-cleanup=false:删除悬挂服务
-注销=“始终”:注销退出的服务“始终”或“成功时”
-internal=false:使用内部端口而不是已发布的端口
-ip=“”:映射到主机的端口的ip
-重新同步=0:服务重新同步的频率
-重试次数=0:与后端建立连接的最大重试次数。使用-1进行无限次重试
-重试间隔=2000:重试尝试之间的间隔(毫秒)。
-tags=“”:为所有注册的服务附加标签
-ttl=0:ttl用于服务(默认为无到期)
-ttl refresh=0:刷新服务ttl的频率
这意味着
-c echo“-ip=$EXTERNAL\u ip concur://$concur\u HOST”
实际上是作为参数传递到
/bin/registrator


我是否做错了什么,或者这是一个用例的限制,在该用例中,
/bin/sh-c exec_cmd p1_cmd
在进入
入口点之前没有首先得到评估?如果后者是正确的,那么您是否也可以解释此用例的有用性?

是。这正是它应该如何工作的

CMD的值只是作为参数传递给ENTRYPOINT

CMD和ENTRYPOINT之间的主要区别在于,CMD只为ENTRYPOINT程序提供默认的命令参数,它通常被运行命令的参数覆盖。另一方面,如果希望执行不同的命令,则必须使用--ENTRYPOINT选项显式地重新定义ENTRYPOINT

另外,请注意,根据在Dockerfile中定义ENTRYPOINT和CMD的方式,执行方式也有所不同。当它们被定义为['arg1','arg2']形式的数组时,该数组将按原样传递给ENTRYPOINT命令,ENTRYPOINT的第一个元素是正在执行的程序。在另一种情况下,当它们被定义为一个简单的字符串,如arg1 arg2时,首先传递的字符串前面是“/bin/sh-c”。请注意,Docker不执行/bin/sh并返回计算结果,该字符串本身被传递给入口点程序

因此,在您的情况下,必须使用传递参数的数组方法:

CMD  [-ip, $EXTERNAL_IP,  consul://$CONSUL_HOST]

然后我不明白这个用例的意义是什么
exec\u entry p1\u entry/bin/sh-c exec\u cmd p1\u cmd
。这将需要
exec\u entry
应用程序来处理我认为很奇怪的命令。啊,错过了这一部分。当CMD是以字符串形式定义的,但您的入口点不是shell时,这实际上是一种退化情况。我认为它没有任何用处。这种语法的唯一用途是当您的入口点是一个shell(bash、sh、csh)并且您有类似于“ls.c”的命令行时,globs将以这种方式工作。否则ls将只获取“.c”作为参数,并将查找名为“*.c”的文件,而不是以“.c”结尾的文件集。谢谢您的输入!我想指出(尽管这很好)
CMD[-ip,$EXTERNAL\u ip,concur://$concur\u HOST]
不起作用,因为环境变量无法解析。请参阅Shell表单和Exec表单。是的,您是对的。解析全局变量和环境变量是shell的工作。在您的情况下,我只需在您自己的图像中重新定义ENTRYPOINT以指向/bin/sh,并使用/bin/registrator-ip=$EXTERNAL\u ip consur://$consur\u HOST添加一个小shell脚本,这样您就可以得到您想要的。