dockerfile里面可以定义CMD
或ENTRYPOINT
例如:
FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]
这两种命令之间有什么区别呢?下面将以实际操作来解释。
FROM busybox
CMD [ "sh" ]
构建:docker build -t cmd .
运行:docker run -itd --name cmd1 cmd ping -c 10 taobao.com
此时原来的sh
启动命令被覆盖,变为新传入的命令:
FROM busybox
CMD [ "/bin/ping" ]
构建:docker build -t entrypoint .
运行:docker run -itd name entrypoint1 entrypoint -c 10 taobao.com
此时基于原来的命令补上用户传入的命令,合起来变为:/bin/ping -c 10 taobao.com
CMD
可以直接用其他启动命令覆盖。
ENTRYPOINT
不能被覆盖,使用其他命令尝试覆盖时会当做参数传入。
The best use of ENTRYPOINT
is to set the image’s main command.
所以,常见的使用方式是将两者结合使用。
FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]
sleep 5
。sleep
时长,可以传入参数。例如sleep 10
。k8s里对应指令为command
和args
。
如何方便记忆呢?记住口诀: 长对长,短对短
(单词长度)。
ENTRYPOINT => command
CMD => args
例如下面的yaml,最后一行 command: ["sleep", "3600"]
指定了启动容器时运行的命令:
apiVersion: v1
kind: Pod
metadata:
name: command
spec:
containers:
- name: busybox
image: busybox
command: ["sleep", "3600"]
也可以使用下面这种形式,command与args混合使用,args用来传递参数:
apiVersion: v1
kind: Pod
metadata:
name: command2
spec:
containers:
- name: busybox
image: busybox
command: ["sleep"]
args: ["36000"]
也可以仅使用args传入命令:
apiVersion: v1
kind: Pod
metadata:
name: command3
spec:
containers:
- name: busybox
image: busybox
args: ["sleep","3200"]
Docker镜像中指定了CMD与entrypoint命令,k8s中没有声明任何命令。 这种情况执行Docker镜像的命令:
Docker镜像中指定了CMD与entrypoint命令,k8s中声明Command 。这种情况覆盖Docker镜像的命令:
Docker镜像中指定了CMD与entrypoint命令,k8s中声明Argument。 这种情况覆盖Docker镜像的CMD:
Docker镜像中指定了CMD与entrypoint命令,k8s中声明Argument和Command。 这种情况全部覆盖:
只要k8s的yaml文件中声明了args
和Command
,就会覆盖掉Docker镜像中对应的命令。