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:

image

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进行构建镜像,然后启动镜像:

image

通过 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进行构建镜像,然后启动镜像:

image

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进行构建镜像,然后启动镜像:

image

容器中的任务进程就是容器内的进程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

image

从上图可以看到,命令行上指定的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

image

总结:CMD指令和ENTRYPOINT指令同时存在时,CMD指令将作为ENTRYPOINT指令的参数,启动容器命令行时输入 '参数' 一样会覆盖CMD指令。

ENTRYPOINT指令被命令行覆盖的方式:需要显式的指定 --entrypoint

# docker run --rm --entrypoint hostname 192.168.10.3:80/tools/alpine-test3:v1
posted @ 2022-04-08 09:42  kuzane  阅读(181)  评论(0)    收藏  举报