背景说明
CMD和ENTRYPOINT都是用来指定容器启动时要运行的命令。
解决方案
特点对比
CMD
- 指定这个容器启动的时候要运行的命令,不可以追加命令,对命令可以覆盖
- CMD指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有其他传入值会覆盖根命令
-
ENTRYPOINT
指定这个容器启动的时候要运行的命令,可以追加命令,对命令不能覆盖
- ENTRYPOINT 指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有其他传入值作为该命令的参数
- 该指令可以存在多个,存在多个时只有最后一个生效
CMD
默认命令
假设针对如下Dockerfile
执行镜像构建并运行,执行默认命令FROM busybox
WORKDIR /home/data
RUN touch test.txt
CMD ls /home/data
[root@vm1 cmd]# docker build . -t cmd:v1 [root@vm1 cmd]# docker run cmd:v1 test.txt [root@vm1 cmd]#
覆盖命令
可以在容器创建时对命令进行覆盖,可以看到这里覆盖了根命令执行了自定义命令[root@vm1 cmd]# docker run cmd:v1 ls / bin dev etc home proc root sys tmp usr var [root@vm1 cmd]# docker run cmd:v1 free -g total used free shared buff/cache available Mem: 4 2 1 0 1 2 Swap: 0 0 0 [root@vm1 cmd]#
ENTRYPOINT
默认命令
假设针对如下Dockerfile
FROM busybox
WORKDIR /home/data
RUN touch test.txt
ENTRYPOINT ls /home/data
执行镜像构建并运行,执行默认命令
[root@vm1 entrypoint]# docker build . -t entrypoint:v1
[root@vm1 entrypoint]# docker run entrypoint:v1
test.txt
[root@vm1 entrypoint]#
追加命令
可以在容器创建时对命令无法进行覆盖,是对命令进行追加
[root@vm1 entrypoint]# docker run entrypoint:v1 ls / #
test.txt
[root@vm1 entrypoint]#
[root@vm1 entrypoint]# docker run entrypoint:v1 && ls /
test.txt
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@vm1 entrypoint]#
[root@vm1 entrypoint]# docker run entrypoint:v1 && free -g
test.txt
total used free shared buff/cache available
Mem: 3 1 0 0 1 1
Swap: 0 0 0
[root@vm1 entrypoint]#
覆盖命令
如果想对命令进行覆盖可以使用如下方式
[root@vm1 entrypoint]# docker run --entrypoint=ls entrypoint:v1 /home
data
[root@vm1 entrypoint]#
[root@vm1 entrypoint]# docker run --entrypoint=free entrypoint:v1 -g
total used free shared buff/cache available
Mem: 4 2 1 0 1 2
Swap: 0 0 0
[root@vm1 entrypoint]#
—entrypoint指定目标命令,命令最后指定参数
命令对比
最佳实践
ENTRYPOINT用来写一个容器固定的指令,CMD用来写默认参数。
当指定了 ENTRYPOINT 后,CMD 的含义就发生了改变,不再是直接的运行其命令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令
换句话说实际执行时,会变成
FROM busybox
WORKDIR /home/data
RUN touch test.txt
ENTRYPOINT ls
CMD -l
构建并运行,步骤如下
[root@vm1 xx]# docker run xx:v1
test.txt
[root@vm1 xx]# docker build . -t xx:v1
[root@vm1 xx]# docker run xx:v1 -al
test.txt
[root@vm1 xx]#
固定指令ENTRYPOINT使用—entrypoint也是可以替换的。