云原生

20230319--深入理解Docker CMD与ENTRYPO

2023-03-18  本文已影响0人  負笈在线

在写Dockerfile中需要指定容器启动时运行的命令,CMD和ENTRYPOINT都可以实现,但其实是有区别的。CMD是指定容器启动时默认运行命令,那么在没有ENTRYPOINT运行命令,就会执行CMD的运行命令,可能会被忽略。ENTRYPOINT指定容器启动时运行的命令,一定会执行。

1.CMD指定容器启动时默认运行命令

CMD格式
1)exec格式:CMD ["executable","param1","param1"] ;CMD的推荐格式
2)shell格式:CMD command param1 param2

如果docker run指定了其他命令,CMD指定的默认命令将会被忽略掉。

# cat Dockerfile
FROM almalinux
MAINTAINER luorf
CMD ["/bin/echo","CMD>>Hello World1","CMD>>Hello World2"]
# docker build -f ./Dockerfile -t cmdtest:V1 .
# docker image ls|grep cmdtest
cmdtest                                 V1        30160a00abdb   16 months ago   198MB

说明:CMD的param1、param2连续执行
# docker run -it cmdtest:V1 
CMD>>Hello World1 CMD>>Hello World2
[root@docker docker]# 
说明:CMD的param1、param2都被/bin/bash覆盖忽略
# docker run -it cmdtest:V1 /bin/bash
[root@e0314b2b5af1 /]# 

如果Dockerfile存在多个CMD指令,则只有最后一个CMD有效。

# cat Dockerfile
FROM almalinux
MAINTAINER luorf
CMD ["/bin/echo","CMD>>Hello World1"]
CMD ["/bin/echo","CMD>>Hello World2"]
# docker build -f ./Dockerfile -t cmdtest:V2 .
# docker image ls|grep cmdtest|grep V2
cmdtest
V2        28c7ebd0fc82   16 months ago   198MB
说明:多条CMD,仅执行最后一条CMD.
# docker run -it cmdtest:V2
CMD>>Hello World2

CMD命令解析变量

# cat Dockerfile
FROM almalinux
MAINTAINER luorf
CMD ["/bin/sh","-c","echo hello,$HOSTNAME"]    # -c参数表示解析变量
# docker build -f ./Dockerfile -t cmdtest:V3 .
# docker image ls|grep cmdtest|grep V3
cmdtest                                 V3        b98bc6808584   16 months ago   198MB
# docker run -it cmdtest:V3
hello,b667060b8c6a

2.ENTRYPOINT指定容器启动时运行的命令

ENTRYPOINT格式
1)exec格式:ENTRYPOINT ["executable","param1","param1"] ;ENTRYPOINT 推荐格式
2)shell格式:ENTRYPOINT command param1 param2

如果docker run指定了其他命令,ENTRYPOINT指定的命令不会被忽略。

# cat Dockerfile_ENTRYPOINT 
FROM almalinux
MAINTAINER luorf
ENTRYPOINT ["/bin/echo","CMD>>Hello World1"]
# docker build -f ./Dockerfile_ENTRYPOINT -t entrypointtest:V1 .
# docker image ls|grep entrypointtest|grep V1
entrypointtest                          V1        f2812d2994ab   16 months ago   198MB
# docker run -it entrypointtest:V1
CMD>>Hello World1
说明:entrypoint的param1没有被/bin/bash覆盖忽略
# docker run -it entrypointtest:V1 /bin/bash
CMD>>Hello World1 /bin/bash

如果Dockerfile存在多个ENTRYPOINT 指令,则只有最后一个ENTRYPOINT 有效;

# cat Dockerfile_ENTRYPOINT 
FROM almalinux
MAINTAINER luorf
ENTRYPOINT ["/bin/echo","CMD>>Hello World1"]
ENTRYPOINT ["/bin/echo","CMD>>Hello World2"]
# docker build -f ./Dockerfile_ENTRYPOINT -t entrypointtest:V2 .
# docker image ls|grep entrypointtest|grep V2
entrypointtest                          V2        2a46f5a1fde6   16 months ago   198MB
说明:多行ENTRYPOINT,仅最后一行有效
# docker run -it entrypointtest:V2
CMD>>Hello World2

ENTRYPOINT的exec格式用于设置要执行的命令和参数,同时可通过CMD提供额外的参数

# cat Dockerfile_ENTRYPOINT 
FROM almalinux
MAINTAINER luorf
CMD ["/bin/echo","World"]
ENTRYPOINT ["/bin/echo","CMD>>Hello "]
# docker build -f ./Dockerfile_ENTRYPOINT -t entrypointtest:V3 .
# docker image ls|grep entrypointtest|grep V3
entrypointtest                          V3        f56e2b8394f4   16 months ago   198MB
说明:通过CMD提供了额外的参数
# docker run -it entrypointtest:V3
CMD>>Hello  /bin/echo World
说明:CMD的参数还是被/bin/bash覆盖忽略
# docker run -it entrypointtest:V3 /bin/bash
CMD>>Hello  /bin/bash

ENTRYPOINT的shell格式会忽略任何CMD或docker run提供的参数

# cat Dockerfile_ENTRYPOINT 
FROM almalinux
MAINTAINER luorf
CMD ["World"]
ENTRYPOINT "/bin/echo" "CMD>>Hello"
# docker build -f ./Dockerfile_ENTRYPOINT -t entrypointtest:V4 .
# docker image ls|grep entrypointtest|grep V4
entrypointtest                          V4        d04c8b81e661   16 months ago   198MB
说明:shell格式忽略任何CMD参数
# docker run -it entrypointtest:V4
CMD>>Hello
说明:shell格式忽略docker run提供的参数
# docker run -it entrypointtest:V4 /bin/bash
CMD>>Hello

ENTRYPOINT 命令解析变量

# cat Dockerfile_ENTRYPOINT 
FROM almalinux
MAINTAINER luorf
ENTRYPOINT ["/bin/sh","-c","echo hello,$HOSTNAME"]
# docker build -f ./Dockerfile_ENTRYPOINT -t entrypointtest:V5 .
# docker image ls|grep entrypointtest|grep V5
entrypointtest                          V5        04b662e86ab2   16 months ago   198MB
# docker run -it entrypointtest:V5
hello,333f4af8f872
说明:ENTRYPOINT 命令解析变量,覆盖docker run提供的参数
# docker run -it entrypointtest:V5 /bin/bash
hello,da284a108c72

如果想要Docker run 覆盖ENTRYPOINT

# docker run -it --rm --entrypoint /bin/bash entrypointtest:V5
[root@60860fbf496f /]# 

3.总结

1)Dockerfile应该至少指定一个 CMD 或ENTRYPOINT;
2)ENTRYPOINT 与CMD很类似,但是ENTRYPOINT 一定不会被忽略,一定会执行;
3)将 Docker 当作可执行程序时, 应该使用 ENTRYPOINT 进行配置; CMD ["param1","param1"] 可以用作 ENTRYPOINT 默认参数(此时ENTRYPOINT 必须使用exec格式);或者用作 Docker 的默认命令;
4)ENTRYPOINT 中的参数始终会被使用,而CMD中的额外参数可以在容器启动(docker run)时动态替换掉;
5)使用了 exec 格式时,docker run 传入的参数会附加到 ENTRYPOINT 之后;
6)建议一般情况下CMD与ENTRYPOINT都使用exec格式.

参考URL

https://blog.csdn.net/MssGuo/article/details/126348571

上一篇 下一篇

猜你喜欢

热点阅读