gpt4 book ai didi

docker - CMD 和 ENTRYPOINT 括号与非括号版本

转载 作者:行者123 更新时间:2023-12-02 18:45:45 24 4
gpt4 key购买 nike

我见过许多具有各种语法的 Dockerfile。他们中的一些人使用CMD没有括号,其中一些使用括号。根据我的实验,这两个是等价的:

CMD ["/bin/ping", "localhost"] 
CMD /bin/ping localhost

但对于 ENTRYPOINT 而言,情况并非如此。根据我的实验,这些不一样,只有带括号的版本有效。
ENTRYPOINT ["/docker-entrypoint.sh"]
ENTRYPOINT /docker-entrypoint.sh

我正在试验这些文件:

Dockerfile:
FROM debian:wheezy
COPY docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh

# WORKS AS EXPECTED - FIRST PASS EXECUTION TO /docker-entrypoint.sh THEN TO CMD
ENTRYPOINT ["/docker-entrypoint.sh"]

# PRINTS "PASSED ARGUMENTS" AND EXITS (CMD IS NOT EXECUTED)
# ENTRYPOINT /docker-entrypoint.sh

# WORKS
CMD ["/bin/ping", "localhost"]

# WORKS
# CMD /bin/ping localhost

# ERROR
# CMD "/bin/ping localhost"

docker 入口点.sh
#!/bin/bash
echo "PASSED ARGUMENTS"
echo "$@"
exec "$@"

配置:
wakatana@ubuntu:~/df$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.3 LTS
Release: 18.04
Codename: bionic


wakatana@ubuntu:~/df$ docker info
Client:
Debug Mode: false

Server:
Containers: 44
Running: 8
Paused: 0
Stopped: 36
Images: 98
Server Version: 19.03.5
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: systemd
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339
runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
init version: fec3683
Security Options:
apparmor
seccomp
Profile: default
Kernel Version: 4.15.0-99-generic
Operating System: Ubuntu 18.04.3 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.83GiB
Name: ubuntu
ID: GIQ3:BYEM:O3GZ:OWNP:VROK:V3IV:SVMI:MRZ7:CLHG:GDBR:PG3S:6NQU
Docker Root Dir: /var/lib/docker
Debug Mode: false
Username: xclbr
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false

WARNING: No swap limit support


wakatana@ubuntu:~/df$ docker --version
Docker version 19.03.5, build 633a0ea838

我认为括号版本是首选方式,但我想知道为什么甚至允许构建非括号版本?它有什么好处吗?为什么 CMDENTRYPOINT 时适用于两个版本仅适用于支架版本?

最佳答案

有两个规则:

  • 如果您使用 JSON 数组(“括号”)版本,则它是构成命令的“单词”的显式列表;如果你使用裸字符串,它会被包裹在 /bin/sh -c '...' 中。 .
  • 应用第一条规则后,ENTRYPOINTCMDcombined into a single command .

  • 还有一个细节:如果您调用 /bin/sh -c 'command' ,任何剩余的参数成为位置参数 $0 , $1等用于扩展 command字符串;它们不会作为参数进一步传递给 command .

    所以如果你的 Dockerfile 说
    ENTRYPOINT ["/entrypoint.sh"]
    CMD ["/command.sh"]

    然后当 Docker 启动容器时,它们将组合成一个命令行
    /entrypoint.sh /command.sh

    但如果你用字符串形式
    ENTRYPOINT /entrypoint.sh
    CMD /command.sh

    你会得到
    /bin/sh -c '/entrypoint.sh' /bin/sh -c '/command.sh'

    它评估字符串 /entrypoint.sh并按原样执行它,不带任何参数;命令丢失。

    通常,您希望命令部分成为标准的 shell 命令( docker run --rm -it some-image /bin/sh 对于调试非常有用)。为了支持这一点, ENTRYPOINT必须是 JSON 数组形式,并且它需要确保运行在其参数中传递的命令(在 shell 脚本中,以 exec "$@" 结尾)。

    关于docker - CMD 和 ENTRYPOINT 括号与非括号版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62206384/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com