args和command

Docker的CMD和 ENTRYPOINT

dockerfile里面可以定义CMDENTRYPOINT

例如:

FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]

这两种命令之间有什么区别呢?下面将以实际操作来解释。

CMD

FROM busybox
CMD [ "sh" ]

构建:docker build -t cmd .

运行:docker run -itd --name cmd1 cmd ping -c 10 taobao.com

此时原来的sh启动命令被覆盖,变为新传入的命令:

image-20200118171241813

ENTRYPOINT

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

image-20200118171648513

总结:

  • CMD可以直接用其他启动命令覆盖。

  • ENTRYPOINT不能被覆盖,使用其他命令尝试覆盖时会当做参数传入。

  • The best use of ENTRYPOINT is to set the image’s main command.

所以,常见的使用方式是将两者结合使用。

FROM ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]
  • CMD作为默认参数存在。如果用户不进行任何操作,则上面构建的镜像会sleep 5
  • 如果用户想要覆盖掉默认sleep时长,可以传入参数。例如sleep 10

K8S的command和args

k8s里对应指令为commandargs

如何方便记忆呢?记住口诀: 长对长,短对短(单词长度)。

ENTRYPOINT => command  
CMD => args

image-20190629155854914

测试

例如下面的yaml,最后一行 command: ["sleep", "3600"]指定了启动容器时运行的命令:

apiVersion: v1
kind: Pod
metadata:
  name: command
spec:
  containers:
    - name: busybox
      image: busybox
      command: ["sleep", "3600"]

image-20200118192046586

也可以使用下面这种形式,command与args混合使用,args用来传递参数:

apiVersion: v1
kind: Pod
metadata:
  name: command2
spec:
  containers:
    - name: busybox
      image: busybox
      command: ["sleep"]
      args: ["36000"]

image-20200118192231341

也可以仅使用args传入命令:

apiVersion: v1
kind: Pod
metadata:
  name: command3
spec:
  containers:
    - name: busybox
      image: busybox
      args: ["sleep","3200"]

docker与k8s command混合使用

场景一:

Docker镜像中指定了CMD与entrypoint命令,k8s中没有声明任何命令。 这种情况执行Docker镜像的命令:

image-20200118192808245

场景二:

Docker镜像中指定了CMD与entrypoint命令,k8s中声明Command 。这种情况覆盖Docker镜像的命令:

image-20200118192920262

场景三:

Docker镜像中指定了CMD与entrypoint命令,k8s中声明Argument。 这种情况覆盖Docker镜像的CMD:

image-20200118193017368

场景四:

Docker镜像中指定了CMD与entrypoint命令,k8s中声明Argument和Command。 这种情况全部覆盖:

image-20200118193039011

总结:

只要k8s的yaml文件中声明了argsCommand,就会覆盖掉Docker镜像中对应的命令。