Docker 基础与实战,看这一篇就够了( 三 )


  • exec 格式:RUN ["可执行文件", "参数1", "参数2"] , 这更像是函数调用中的格式 。
  • CMD此指令就是用于指定默认的容器主进程的启动命令的 。CMD指令格式和RUN相似 , 也是两种格式
    • shell 格式:CMD <命令>
    • exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
    • 参数列表格式:CMD ["参数1", "参数2"...] 。在指定了 ENTRYPOINT 指令后 , 用 CMD 指定具体的参数 。
  • ENTRYPOINTENTRYPOINT 的格式和RUN指令格式一样 , 分为 exec 格式和 shell 格式 。ENTRYPOINT 的目的和 CMD 一样 , 都是在指定容器启动程序及参数 。ENTRYPOINT 在运行时也可以替代 , 不过比 CMD 要略显繁琐 , 需要通过 docker run 的参数 --entrypoint 来指定 。当指定了 ENTRYPOINT 后 , CMD 的含义就发生了改变 , 不再是直接的运行其命令 , 而是将 CMD 的内容作为参数传给 ENTRYPOINT指令 , 换句话说实际执行时 , 将变为:
  • <ENTRYPOINT> "<CMD>"
    • COPY & ADD
      这2个指令都是复制文件 , 它将从构建上下文目录中 <源路径> 的文件/目录 复制到新的一层的镜像内的 <目标路径> 位置 。比如:COPY demo-test.jar app.jar 或ADD demo-test.jar app.jar 。ADD指令比COPY高级点 , 可以指定一个URL地址 , 这样Docker引擎会去下载这个URL的文件 , 如果ADD后面是一个tar文件的话 , Dokcer引擎还会去解压缩 。
      我们在构建镜像时尽可能使用 COPY , 因为 COPY 的语义很明确 , 就是复制文件而已 , 而 ADD 则包含了更复杂的功能 , 其行为也不一定很清晰 。
    • EXPOSE声明容器运行时的端口 , 这只是一个声明 , 在运行时并不会因为这个声明应用就会开启这个端口的服务 。在 Dockerfile 中写入这样的声明有两个好处 , 一个是帮助镜像使用者理解这个镜像服务的守护端口 , 以方便配置映射;另一个用处则是在运行时使用随机端口映射时 , 也就是 docker run -P 时 , 会自动随机映射 EXPOSE 的端口 。要将 EXPOSE 和在运行时使用-p <宿主端口>:<容器端口> 区分开来 。-p , 是映射宿主端口和容器端口 , 换句话说 , 就是将容器的对应端口服务公开给外界访问 , 而 EXPOSE 仅仅是声明容器打算使用什么端口而已 , 并不会自动在宿主进行端口映射 。
    • ENV这个指令很简单 , 就是设置环境变量 , 无论是后面的其它指令 , 如 RUN , 还是运行时的应用 , 都可以直接使用这里定义的环境变量 。它有如下两种格式:
      • ENV <key> <value>
      • ENV <key1>=<value1> <key2>=<value2>...
    • VOLUME该指令使容器中的一个目录具有持久化存储的功能 , 该目录可被容器本身使用 , 也可共享给其他容器 。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令 。如VOLUME /tmp这里的 /tmp 目录就会在运行时自动挂载为匿名卷 , 任何向 /tmp 中写入的信息都不会记录进容器存储层 , 从而保证了容器存储层的无状态化 。当然 , 运行时可以覆盖这个挂载设置 。比如:docker run -d -v mydata:/tmp xxxx
    • LABEL你可以为你的镜像添加labels , 用来组织镜像 , 记录版本描述 , 或者其他原因 , 对应每个label , 增加以LABEL开头的行 , 和一个或者多个键值对 。如下所示:
      LABEL version="1.0"LABEL description="test"
     
    Dockerfile实战我们以一个简单的SpringBoot项目为例构建基于SpringBoot应用的镜像 。功能很简单 , 只是对外提供了一个say接口 , 在进入这个方法的时候打印出一行日志 , 并将日志写入日志文件 。
    @SpringBootApplication@RestController@Log4j2public class DockerApplication {public static voidmain(String[] args) {SpringApplication.run(DockerApplication.class, args);}@GetMapping("/say")public String say{log.info("get say request...");return "Hello,Java日知录";}}


    推荐阅读