文章目录
前言一、ENTRYPOINT 命令格式介绍二、示例总结
前言
Entrypoint的作用是,把整个container变成了一个可执行的文件,这样不能够通过替换CMD的方法来改变创建container的方式。但是可以通过参数传递的方法影响到container内部。
一、ENTRYPOINT 命令格式介绍
ENTRYPOINT 有两种格式:
ENTRYPOINT [“executable”, “param1”, “param2”] (exec 格式,首选)ENTRYPOINT command param1 param2 (shell 格式)exec 格式
docker run image 后面跟的命令行参数将会添加到 ENTRYPOINT 所有参数的最后,且会覆盖掉所有 CMD 命令中的参数。这将允许运行时传递参数给 ENTRYPOINT 命令,例如 docker run image -d 会将 -d 参数传给 ENTRYPOINT 命令 。ENTRYPOINT 命令可以通过 docker run --entrypoint 参数来覆盖 。
shell 格式
会忽略所有 CMD 命令的参数和 docker run 的命令行参数,ENTRYPOINT 要运行的命令会作为 /bin/sh -c 的子命令运行,而且 /bin/sh 不会传递信号,也就是说 ENTRYPOINT 要运行的命令不是 PID 为 1 的进程,且不会收到 Unix 信号,所以你要执行的命令不会收到 docker stop 发出的 SIGTERM 信号。
二、示例
Exec格式
用使用CMD的参数,run [image] 会替代CMD参数,会使用run中的多个参数
示例一ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"] //表示默认参数,没提供参数,则使用此参数
docker run -it [image] 输出:Hello world docker run -it [image] "hanke" 输出 Hello hanke ,不使用默认参数docker run -it [image] "hanke" "hujing" 输出 Hello hankd hujing ,使用多个提供参数
示例二
可以使用 exec 格式的 ENTRYPOINT 来设置稳定的默认命令和参数,再通过CMD 命令设置容易变动的默认值。
FROM ubuntuENTRYPOINT["top","-b"]CMD["-c"]
运行这个容器,可以看到只有 top 一个进程:
$ docker run -it --rm --name testtop -Htop - 08:25:00 up 7:27, 0users, load average: 0.00, 0.01, 0.05Threads: 1total, 1running, 0sleeping, 0stopped, 0zombie%Cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 stKiB Mem: 2056668total, 1616832used, 439836free, 99352buffersKiB Swap: 1441840total, 0used, 1441840free. 1324440cached MemPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1root 2001974423362080R 0.0 0.1 0:00.04 top可以通过 docker exec 进一步确认:$ docker exec-it testps auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 12.6 0.1 197522352? Ss+ 08:24 0:00 top -b -Hroot 70.0 0.1 155722164? R+ 08:25 0:00 ps aux
Shell格式
可以给 ENTRYPOINT 命令指定一个纯字符串,它将通过 /bin/sh -c 执行。这种格式会处理 shell 环境变量,忽略所有的 CMD 命令和 docker run 命令行参数。为了确保 docker stop 能正确的停止运行的 ENTRYPOINT 命令,容器需要通过 exec 来启动。
FROM ubuntuENTRYPOINT exec top -b
运行这个镜像,将会看到 PID 为 1 的进程:
$ docker run -it --rm --name test topMem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cachedCPU: 5% usr 0% sys 0% nic 94% idle 0% io 0% irq 0% sirqLoad average: 0.08 0.03 0.05 2/98 6 PID PPID USER STAT VSZ %VSZ %CPU COMMAND 1 0 root R 3164 0% 0% top -b
如果忘了在 ENTRYPOINT 命令中添加 exec:
FROM ubuntuENTRYPOINT top -bCMD --ignored-param1
运行
$ docker run -it --name test top --ignored-param2Mem: 1704184K used, 352484K free, 0K shrd, 0K buff, 140621524238337K cachedCPU: 9% usr 2% sys 0% nic 88% idle 0% io 0% irq 0% sirqLoad average: 0.01 0.02 0.05 2/101 7 PID PPID USER STAT VSZ %VSZ %CPU COMMAND 1 0 root S 3168 0% 0% /bin/sh -c top -b cmd cmd2 7 1 root R 3164 0% 0% top -b从 top 的输出中可以看到 PID 为 1 的进程不是 ENTRYPOINT 中设置的命令这时运行 docker stop test,容器不能优雅的退出(docker stop 命令在一个超时时间后会强制发送 SIGKILL[9] 信号):$ docker exec -it test ps auxPID USER COMMAND 1 root /bin/sh -c top -b cmd cmd2 7 root top -b 8 root ps aux$ /usr/bin/time docker stop testtestreal0m 10.19suser0m 0.04ssys0m 0.03s
总结
CMD 和 ENTRYPOINT 命令都定义了容器运行时运行命令。下面有几条规则:
Dockerfile 必须有一条 CMD 或 ENTRYPOINT 命令如果容器作为可执行程序运行,需要指定 ENTRYPOINT 命令,CMD 命令应该用来定义 ENTRYPOINT 命令的默认参数下表展示了 ENTRYPOINT / CMD 组合: