Dockerfile系列:探索ENTRYPOINT与CMD的

在使用 Docker 构建容器镜像时,我们经常会使用 Dockerfile 来定义容器的配置。其中,ENTRYPOINT 和 CMD 是两个重要的指令,用于设置容器运行时的命令。本文将详细介绍 ENTRYPOINT 和 CMD 的主要区别,并探讨它们在 Dockerfile 中的结合使用。

CMD 与 ENTRYPOINT的主要区别

CMD

  • CMD 指令用于设置容器运行时的默认参数。
  • 如果 Dockerfile 中有多个 CMD 指令,只有最后一个会生效。
  • CMD 可以被 docker run 命令行中的参数覆盖。
  • 在 Dockerfile 中,可以用 JSON 数组或字符串数组的形式指定 CMD,如 CMD ["command", "arg1", "arg2"] 或 CMD command arg1 arg2
  • CMD 的参数会作为默认参数传递给 ENTRYPOINT。

ENTRYPOINT

  • ENTRYPOINT 指令用于设置容器启动时的默认可执行命令。
  • ENTRYPOINT 可以是一个具体的命令或者一个可执行脚本。
  • ENTRYPOINT 的值不会被 docker run 命令行中的参数覆盖。
  • 在 Dockerfile 中,可以用 JSON 数组或字符串数组的形式指定 ENTRYPOINT,如 ENTRYPOINT ["command", "arg1", "arg2"] 或 ENTRYPOINT command arg1 arg2

CMD 与 ENTRYPOINT的结合使用

CMD 和 ENTRYPOINT 可以结合使用,以满足不同的需求。当它们同时存在时,CMD 中的参数会作为 ENTRYPOINT 的默认参数。

以下是一个示例的 Dockerfile:

FROM ubuntu:latest

ENTRYPOINT ["echo", "Hello"]
CMD ["World"]

上述 Dockerfile 中,ENTRYPOINT 指定了默认的可执行命令为 echo,并设定了默认参数为 HelloCMD 指定了默认参数为 World。当容器启动时,会执行的命令为 echo Hello World

可以通过以下步骤验证 ENTRYPOINT 和 CMD 的结合使用效果:

  1. 创建一个名为 Dockerfile 的文件,并将上述示例内容复制到文件中。
  2. 执行以下命令构建镜像:docker build -t myimage .
  3. 运行容器并观察输出:docker run myimage

运行以上命令后,会看到容器输出 Hello World,验证了 ENTRYPOINT 和 CMD 的结合运行。

需要注意的是,如果在运行容器时显式传递了命令行参数,则会覆盖 CMD 中指定的默认参数。例如,使用 docker run myimage "Greeting" 命令运行容器时,会执行的命令为 echo Greeting,而不再是 echo Hello World

java

我们有一个 java 程序,它添加了两个数字,我们希望用户在执行 docker run 时传递参数。那么当我们容器化下面给出的程序时,我们如何实现这一点呢?


public static void main(String[] args) {
      
    if (args.length == 2) {
           int a = Integer.parseInt(args[0]);
           int b = Integer.parseInt(args[1]);
           int sum = a + b;
        System.out.println("Sum of "+args[0] +" & "+ args[1]+" is : " + sum);
     } 
}

ENTRYPOINT

FROM openjdk:8-jre-alpine 
COPY out/production/DockerExampleArgsJava/ /tmp 
WORKDIR /tmp 
ENTRYPOINT ["java", "AddTwoNumber"]
  • 上述文件中的ENTRYPOINT用于指定容器启动时要运行的命令,在本例中,它通过发出命令来启动 AddTwoNumber 程序的 mainjava AddTwoNumber方法

  • 当你使用命令运行容器时docker run raje/add2number,它会给出一条消息 – 请输入 2 个整数

  • 您可以通过发出相同的命令并传递参数来传递参数,这些将被传递到入口点示例docker run raje/add2number 10 100

  • 如果您想在启动时将默认值传递给容器,可以通过在 Dockerfile 中提及它来实现,如下所示

FROM openjdk:8-jre-alpine 
COPY out/production/DockerExampleArgsJava/ /tmp 
WORKDIR /tmp 
ENTRYPOINT ["java", "AddTwoNumber","5","15"]

CMD

  • 如果您现在使用命令运行该程序docker run raje/add2number,它将显示总和

  • 然而,如果你尝试传递新的参数,那是行不通的。尝试 docker run raje/add2number 10 100并且参数将不会被考虑

  • 发生这种情况是因为我们在 dockerfile 中提供的 ENTRYPOINT 指令不会被忽略,而是会附加到原始指令中,因此在这种情况下,程序将被调用,如下所示java AddTwoNumber 5 15 10 100

  • CMD 是另一个选项,它提供有关在执行 docker run 时应执行的操作的说明。

  • 如果我们在 Dockerfile 中使用以下指令

FROM openjdk:8-jre-alpine 
COPY out/production/DockerExampleArgsJava/ /tmp 
WORKDIR /tmp 
CMD ["java", "AddTwoNumber","5","15"]
  • 执行后docker run raje/add2number

  • 我们将看到输出:Sum of 10 & 100 is : 110

  • 使用 ENTRYPOINT,当我们传递新参数时,它会附加到命令中,但是使用 CMD 你可以覆盖命令,例如

    • 如果你想传递新的参数,你可以运行:docker run raje/add2number java AddTwoNumber 300 40

    • 您可以将命令完全替换为类似的命令docker run raje/add2number echo This is Test

  • 如果您有一个场景,您希望默认命令是您提到的程序并希望用于覆盖参数,那么您可以使用 ENTRYPOINT 和 CMD 的组合

使用 ENTRYPOINT 和 CMD 的组合

FROM openjdk:8-alpine 
COPY out/production/DockerExampleArgsJava/ /tmp 
WORKDIR /tmp ENTRYPOINT ["java", "AddTwoNumber"] 
CMD ["10","200"]
  • 使用上面的 docker 文件,当您发出命令时,docker run raje/add2number
    它将输出Sum of 10 & 200 is : 210

  • 您可以通过发出类似命令来覆盖默认参数docker run raje/add2number 40 50,它将输出Sum of 40 & 50 is : 90

总结

在 Dockerfile 中,ENTRYPOINT 和 CMD 是两个重要的指令,用于设置容器运行时的命令。ENTRYPOINT 指定了默认的可执行命令,而 CMD 则提供了 ENTRYPOINT 的默认参数。它们的结合使用可以帮助我们定义灵活且可定制的容器镜像。通过实际的例子与操作指引,我们深入理解了它们的功能和使用方法。

全部评论

相关推荐

EEbond:给北邮✌️跪了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务