什么是Dockerfile
Dockerfile简介
简而言之,dockerfile是镜像生产说明书,其作用是用来构建镜像的。
使用者通过Dockerfile就能知晓镜像每一层是如何构建的;
Dockerfile的组成结构
Dockerfile编排包含基础镜像信息、维护者信息、镜像操作指令和容器启动指令四个结构。
编写规范Dockerfile
编写规范的目的
Dockerfile编写规范的目的:旨在构建最小、最快,最少层的镜像。
基础镜像挑选
微服务推荐选用openjdk:8u151-jre-alpine3.7基础镜像,具有基础的java环境,大小仅57M。
更小的镜像意味着更少依赖,更少变化,更少问题,更快拉取,更快加载,更省资源。
Dockerfile编排第一行使用:FROM openjdk:8u151-jre-alpine3.7
谨记容器都是暂态的
无论容器中产生了什么数据,都会在关停和重启时删除,容器一定是无状态的。因此一定不要在容器中存储持久化数据,容器的状态需要外置。
不能出现软件包安装和更新操作
不要在Dockerfile出现软件的安装,比如RUN yum install mysql 或 RUN yum update mysql。如果需要依赖其他软件,可以选择直接使用dockerhub相关镜像或者重新构建一个合适的基础镜像。
不发生变化的layer放在前面
为了保证layer缓存可以复用从而增加构建速度,尽量把稳定的、不变的layer放在前面。
把联系紧密并且相对独立的几个RUN指令合并成一条
如果有几个镜像RUN指令联系紧密,需要把几个RUN指令通过 && 符号连接到一块,减少layer层数。
例如: RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime&& echo $TZ > /etc/timezone
这条指令即是把联系紧密的两条命令用&& 连成一条,只会构建一个layer;
避免安装不必要的包
一定要在Dockerfile 里编写与自己容器启动相关的环境,所有编写指令信息都是围绕容器指令启动和稳定运行而执行的。比如启动jar包的Dockerfile编写不要添加C++的依赖环境。这样做是为了减少容器的复杂度、依赖关系、尺寸以及构建时间;
一个容器只有一个微服务
尽量保证一个容器只有一个运行程序,保证容器镜像的清洁,独立和可规模化(多实例部署、横向扩展)。
容器中启动的Java程序需要使用命令行参数
增加JVM启动参数:
-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
Java8 以前,JVM无法识别出自己在容器中,也不能识别cgroups所设置的内存限制。在申请的内存超过cgroups限制时,程序就会崩溃。Java8 通过开启这两个参数,使JVM识别出cgroups限制。