dockerfile中CMD和ENTRYPOINT
Dockerfile中CMD和ENTRYPOINT命令详解
CMD 和 ENTRYPOINT 指令都是用来指定容器启动时运行的命令。
当前主机docker版本:
[root@k8s-harbor test]# docker version
Client: Docker Engine - Community
Version: 19.03.9
API version: 1.40
Go version: go1.13.10
Git commit: 9d988398e7
Built: Fri May 15 00:25:27 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.9
API version: 1.40 (minimum version 1.12)
Go version: go1.13.10
Git commit: 9d988398e7
Built: Fri May 15 00:24:05 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.4
GitCommit: 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
runc:
Version: 1.1.1
GitCommit: v1.1.1-0-g52de29d
docker-init:
Version: 0.18.0
GitCommit: fec3683
1.exec模式
使用 exec 模式时,容器中的任务进程就是容器内的进程PID为1的进程。
FROM alpine:3.11
CMD [ "top" ]
# docker build . -t 192.168.10.3:80/tools/alpine-test1:v1
使用上述dockerfile进行构建镜像,然后启动镜像:
docker build . -t 192.168.10.3:80/tools/alpine-test1:v1
docker run -it --rm --name alpine-test1 192.168.10.3:80/tools/alpine-test1:v1
然后查看容器中的进程ID:

exec 模式的特点是不会通过 shell 执行相关的命令,所以像 $HOME 这样的环境变量是取不到的:
FROM alpine:3.11
CMD [ "echo", "$HOME" ]
# docker build . -t 192.168.10.3:80/tools/alpine-test1:v1
# docker run -it --rm --name alpine-test1 192.168.10.3:80/tools/alpine-test1:v1
使用上述dockerfile进行构建镜像,然后启动镜像:

通过 exec 模式执行 shell 可以获得环境变量:
FROM alpine:3.11
CMD [ "sh", "-c", "echo $HOME" ]
# docker build . -t 192.168.10.3:80/tools/alpine-test1:v1
# docker run -it --rm --name alpine-test1 192.168.10.3:80/tools/alpine-test1:v1
使用上述dockerfile进行构建镜像,然后启动镜像:

2.shell模式
使用shell模式时与exec模式一样,容器中的任务进程就是容器内的进程PID为1的进程。
FROM alpine:3.11
CMD top
# docker build . -t 192.168.10.3:80/tools/alpine-test2:v1
# docker run -it --rm --name alpine-test2 192.168.10.3:80/tools/alpine-test2:v1
使用上述dockerfile进行构建镜像,然后启动镜像:

容器中的任务进程就是容器内的进程PID为1的进程,可以通过 docker 的 stop 命令优雅的结束容器。
3.CMD指令
CMD ["executable","param1","param2"] //exec模式写法,注意需要使用双引号。
CMD command param1 param2 //shell模式写法。
FROM alpine:3.11
CMD [ "top" ]
# docker build . -t 192.168.10.3:80/tools/alpine-test1:v1
# docker run -it --rm --name alpine-test1 192.168.10.3:80/tools/alpine-test1:v1 ps aux

从上图可以看到,命令行上指定的ps aux命令覆盖了Dockerfile中的 CMD [ "top" ]。实际上,命令行上的命令同样会覆盖shell模式的CMD指令。
# docker run -it --rm --name alpine-test1 192.168.10.3:80/tools/alpine-test1:v1 sh
# 与这样起一个容器的sh一样,sh覆盖了CMD指令
4.ENTRYPOINT指令
ENTRYPOINT ["executable", "param1", "param2"] //exec模式写法,注意需要使用双引号。
ENTRYPOINT command param1 param2 //shell模式的写法。
ENTRYPOINT指令和CMD指令
FROM alpine:3.11
CMD [ "cat" ]
ENTRYPOINT [ "echo","-e" ]
# docker build . -t 192.168.10.3:80/tools/alpine-test3:v1

总结:CMD指令和ENTRYPOINT指令同时存在时,CMD指令将作为ENTRYPOINT指令的参数,启动容器命令行时输入 '参数' 一样会覆盖CMD指令。
ENTRYPOINT指令被命令行覆盖的方式:需要显式的指定 --entrypoint
# docker run --rm --entrypoint hostname 192.168.10.3:80/tools/alpine-test3:v1
本文来自博客园,作者:kuzane,转载请注明原文链接:https://www.cnblogs.com/kuzane/articles/16115428.html

浙公网安备 33010602011771号