使用ENTRYPOINT和CMD参数传递的行为不清楚

时间:2017-11-13 22:15:15

标签: dockerfile alpine

从11月14日14:25更新: 这个问题可以在面临多个问题时关闭,不应相互混淆。 稍后我将回来并添加对更具体问题的引用。

https://stackoverflow.com/a/39408777的启发,我列出了可能的案例表,并找到了2个孤立的案例:

+------------------+-------------------------------------------+------------------------+---------------------------------------------------+
|                  | No Entrypoint                             | Entrypoint (JSON-form) | Entrypoint (shell-form)                           |
+------------------+-------------------------------------------+------------------------+---------------------------------------------------+
| No CMD           | HostConfig.Config.cmd=/bin/bash is called | breaks                 | ok                                                |
|                  | (assumption as of docker inspect)         | (See Case 1)           |                                                   |
+------------------+-------------------------------------------+------------------------+---------------------------------------------------+
| CMD (JSON-form)  | breaks(See Case 1)                        | breaks                 | breaks                                            |
|                  |                                           | (See Case 1)           | (See Case 2)                                      |
+------------------+-------------------------------------------+------------------------+---------------------------------------------------+
| CMD (shell-form) | ok                                        | ok                     | Breaks [seems to work as designed]                |
|                  |                                           |                        | (both are called with a shell concatinated)       |
|                  |                                           |                        | Example: /bin/sh -c <ENTRYPOINT> /bin/sh -c <CMD> |
+------------------+-------------------------------------------+------------------------+---------------------------------------------------+

案例1 - 逃避exec表单的双引号问题。 可能的解决方法: 创建一个单独的shell脚本并处理此脚本中的所有逻辑。

案例2 - 如果与Entrypoint

一起使用,exec形式的CMD参数会丢失

( 用过的措辞:

  • 使用json数组的exec表单 - &gt; CMD [“coommand”,“参数”]
  • shell form - &gt; CMD命令参数

见:https://docs.docker.com/engine/reference/builder/#cmd

从11月14日12:16更新: 我试图用ubuntu:latest重现这种行为,并且使用bash和dash遇到了不同的行为。经过一些试验和错误,我可以说它在shellform中同时适用于ENTRYPOINT和CMD。 我将进一步研究当我使用jsonform时会发生什么。转义指令没有改变行为)

我的问题不是关注何时使用ENTRYPOINT或CMD的决策,而是关注将参数传递给容器时的行为方式。但是t.b.h.我不确定这是一个码头工人还是高山环境/壳相关的问题 - &gt;标记了两者。

预期行为

使用ENTRYPOINT设置稳定的默认命令和参数,并使用CMD设置可覆盖参数。 然后将这些参数正确传递给容器。

实际行为

被调用的可执行文件在三种不同的场景中表现不同。下面将描述每三种情况。

案例1: 参数按预期传递。但我无法用ENTRYPOINT来实现它。只有CMD。

案例2: ENTRYPOINT和CMD的结合。出现两个具有未知来源的字符“/ \”。

案例3: ENTRYPOINT(贝壳形式)和CMD的组合。 CMD的参数似乎消失了。

使用交互式shell(docker exec -it --entrypoint =“/ bin / ash”)修复案例3的异常情况: 使用

中的单引号转义所有参数
/bin/sh -c /usr/bin/run.sh server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"

/bin/sh -c '/usr/bin/run.sh server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"'

但为什么它仅适用于仅使用CMD的案例1?并且SHLVL设置为值'2'。

到目前为止我尝试了什么

  • 差异对接器检查相关容器的输出 - &gt;没有什么可疑的(如果需要可以发布)
  • 写了一个简单的包装器脚本来打印环境变量,ps faux和传递的参数。 (下面的输出)
  • 阅读在线文章(例如Dockerfile参考和https://stackoverflow.com/a/39408777(ENTRYPOINT和CMD的可能组合))

引用的run.sh来源 - &gt; link

用于构建运行容器的命令:

"sudo docker build -t docker-hugo . && sudo docker run --rm docker-hugo"

Dockerfile CASE 1 - 工作但没有ENTRYPOINT(我想要实现的目标):

FROM alpine:latest
RUN apk --no-cache add hugo
CMD hugo server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"

相关产出:

Error: Unable to locate Config file. Perhaps you need to create a new site.
       Run `hugo help new` for details. (Config File "config" Not Found in "[/src]") <-- "/src" as provieded via CMD

Container内的命令(通过“ps faux”和docker exec -it --entrypoint =“/ bin / ash”获得)

PID   USER     TIME   COMMAND
    1 root       0:00 /bin/sh -c hugo server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"
    7 root       0:00 hugo server --watch=true --bind=0.0.0.0 --source=/src --destination=/output
   28 root       0:00 ash
   34 root       0:00 ps faux

Dockerfile案例2 - 不明白stdout中的“/ \”来自哪里

FROM alpine:latest
RUN apk --no-cache add hugo
#ENTRYPOINT ["/usr/bin/run.sh"]
ENTRYPOINT ["hugo"]
CMD ["server", "--watch=true", "--bind=0.0.0.0", "--source=\"/src\"", "--destination=\"/output\""]

相关产出:

Error: Unable to locate Config file. Perhaps you need to create a new site.
       Run `hugo help new` for details. (Config File "config" Not Found in "[/\"/src\"]")   <-- where is the "/\" comming from?)

来自容器的命令和环境(来自run.sh的stdout)

HOME='/root'
HOSTNAME='805e3dd6110a'
IFS='   
'
OPTIND='1'
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
PPID='0'
PS1='\w \$ '
PS2='> '
PS4='+ '
PWD='/'
SHLVL='1'

PID   USER     TIME   COMMAND
    1 root       0:00 ash /usr/bin/run.sh server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"
    7 root       0:00 ps faux

server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"

Dockerfile案例3 - 不行 - CMD参数似乎“消失”

FROM alpine:latest
RUN apk --no-cache add hugo
#ENTRYPOINT ["/usr/bin/run.sh"]
ENTRYPOINT /usr/bin/run.sh
CMD ["server", "--watch=true", "--bind=0.0.0.0", "--source=\"/src\"", "--destination=\"/output\""]

相关产出:

Error: Unable to locate Config file. Perhaps you need to create a new site.
       Run `hugo help new` for details. (Config File "config" Not Found in "[/]")  <-- Parameter had no effect

来自容器的命令和环境(来自run.sh的stdout)

HOME='/root'
HOSTNAME='cd6df15c5028'
IFS='   
'
OPTIND='1'
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
PPID='1'
PS1='\w \$ '
PS2='> '
PS4='+ '
PWD='/'
SHLVL='2'

PID   USER     TIME   COMMAND
    1 root       0:00 /bin/sh -c /usr/bin/run.sh server --watch=true --bind=0.0.0.0 --source="/src" --destination="/output"
    7 root       0:00 ash /usr/bin/run.sh
    8 root       0:00 ps faux

0 个答案:

没有答案