带脚本的 CMD 和 ENTRYPOINT,相同的 Dockerfile

Ren*_*mas 1 containers docker kubernetes dockerfile kubernetes-pod

尝试使用以下命令运行基于图像的 Pod Dockerfile

...

ENTRYPOINT [ "./mybashscript", ";", "flask" ]
CMD [ "run" ]
Run Code Online (Sandbox Code Playgroud)

我期望完整的命令是./mybashscript; flask run. 然而,在此示例中,pod/container执行./mybashscript,但 不执行flask

我还尝试了一些变体,例如:

...

ENTRYPOINT [ "/bin/bash", "-c", "./mybashscript && flask" ]
CMD [ "run" ]
Run Code Online (Sandbox Code Playgroud)

现在,flask被执行但run被忽略。

PS:我试图理解为什么这不起作用,并且我知道我可以将所有内容放入脚本中entrypoint或将所有内容放入bash脚本中,但这不是重点。

Dav*_*aze 6

在此处显示的两种情况下,您都使用 JSON 数组执行形式来执行ENTRYPOINTCMD。这意味着不会运行 shell,除非在第二种情况下显式运行它。这两部分只是组合在一起成为一个命令

第一个构造运行脚本./mybashscript,该脚本必须是可执行的并且具有有效的“shebang”行(可能#!/bin/bash)。该脚本传递了三个参数,您可以在 shell 变量$1$2和中看到它们$3:分号;flaskrun

第二个构造运行/bin/sh -c './mybashscript && flask' runsh -c采用单个参数,即mybashscript && flask; 剩余的参数run被解释为位置参数,并且sh -c命令将其视为$0


ENTRYPOINT和you show的任意分割CMD实际上没有意义。两者之间唯一真正重要的区别是,CMD运行容器时更容易更改,例如将其放在docker run命令中的映像名称后面。将所有命令放在命令部分中是有意义的,或者都不放在命令部分中,但实际上将一半命令放在一个部分中,一半放在另一部分中是不合理的。

我在这里的第一遍是写:

# no ENTRYPOINT
CMD ./mybashscript && flask run
Run Code Online (Sandbox Code Playgroud)

Docker 将以sh -c裸字符串shell 形式为您插入一个包装器,因此&&具有其通常的 Bourne-shell 含义。


此设置看起来像是您尝试在主容器命令之前运行初始化脚本。ENTRYPOINT为此有一个相当标准的使用模式。由于它传递了CMD作为参数,因此脚本可以以exec "$@"运行结束CMD(可能在命令中被覆盖docker run)。入口点脚本可能看起来像

#!/bin/sh
# entrypoint.sh
./mybashscript
exec "$@"
Run Code Online (Sandbox Code Playgroud)

(如果您编写了mybashscript,您也可以以该行结束它exec "$@",并使用该脚本作为入口点。)

在 Dockerfile 中,将此包装器脚本设置为ENTRYPOINT,然后将主命令设置为CMD.

ENTRYPOINT ["./entrypoint.sh"] # must be a JSON array
CMD ["flask", "run"]           # can be either form
Run Code Online (Sandbox Code Playgroud)

如果您提供备用命令,它会替换CMD,因此该exec "$@"行将运行该命令而不是 Dockerfile 中的命令,但ENTRYPOINT包装器仍然运行。

# See the environment the wrapper sets up
docker run --rm your-image env
# Double-check the data directory setup
docker run --rm -v $PWD/data:/data your-image ls -l /data
Run Code Online (Sandbox Code Playgroud)

如果您确实想使用sh -cform 和 split ENTRYPOINT,则内部命令sh -c必须读取$@以查找其位置参数( )CMD,另外您需要知道第一个参数是$0不是$1。如果你写的话,你显示的表格将会起作用

# not really recommended but it would work
ENTRYPOINT ["/bin/sh", "-c", "./mybashscript && flask \"$@\"", "flask"]
CMD ["run"]
Run Code Online (Sandbox Code Playgroud)