关于docker:简简单单将Java应用封装成Docker镜像

45次阅读

共计 3519 个字符,预计需要花费 9 分钟才能阅读完成。

想必 Docker 这个词大家都不生疏,是一个十分优良的虚拟化容器。

我的博客

怎么把 Java 利用打包成 Docker 镜像?对相熟 Docker 的同学这应该是一个很简略的问题,把我的项目打包成 JAR 包而后在 Dockerfile 里用 ADD 命令把 JAR 文件放到镜像里,启动命令设置执行这个 JAR 文件即可。

可是对于不懂 Java 的,听起来貌似并不是那么简略。

在这之前,咱们先理解理解什么是:Dockerfile

Dockerfile

Dockerfile 是一个用来构建镜像的文本文件,文本内容蕴含了一条条构建镜像所需的指令和阐明。

比方一个应用 Maven 构建的 Spring 利用就能够用上面这个 Dockerfile 构建镜像。

 FROM openjdk:8-jre
 ADD target/*.jar /application.jar
 ENTRYPOINT ["java", "-jar","/application.jar"]

咦?这是啥语言,也没见过啊?这个其实是 dockerfile 的指令。

下面这个 Dockerfile 的指令很好了解,应用 Maven 构建的 Java 我的项目的目录构造对立是:

 project
 │   pom.xml
 └───src // 源文件目录
 │   │
 │   └───main
 │       │   
 │       └───java
 │       
 └───target // class 和 jar 文件的目录

mvn clean package 打包后会把 JAR 文件生成在 target 目录里,通过 java -jar 命令即可执行编译好的程序。

所以下面的 Dockerfile 里就进行了把 JARtarget目录里增加到 Docker 镜像中以及将jar -jar /application.jar 设置成容器的启动命令这两步操作。

不过除了这种最原始的办法外咱们还能够应用 Maven 的一些插件,或者 Docker 的多阶段打包性能来实现把 Java 利用打包成 Docker 镜像的动作。

Maven 插件构建镜像

Spotify公司的 dockerfile-maven-plugin 和 Google 公司出品的 jib-maven-plugin 是两款比拟有名的插件,上面简略介绍一下 dockerfile-maven-plugin 的配置和应用。

其实应用办法很简略,咱们在 POM 文件里引入这个 plugin,并联合下面那个Dockerfile 就能让插件帮忙咱们实现利用镜像的打包。

 <groupId>com.example</groupId>
     <artifactId>hello-spring</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <name>helloworld</name>
 <plugin>
  <groupId>com.spotify</groupId>
  <artifactId>dockerfile-maven-plugin</artifactId>
  <version>1.4.10</version>
  <executions>
   <execution>
   <id>default</id>
       <goals>
         <goal>build</goal>
         <goal>push</goal>
       </goals>
     </execution>
   </executions>
   <configuration>
     <repository>${docker.registry.url}/${image.prefix}/${artifactId}</repository>
     <tag>${project.version}</tag>
     <buildArgs>
       <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
     </buildArgs>
   </configuration>
 </plugin>

插件里应用的 docker.registry.urlimage.prefix是我独自为 Docker 的镜像仓库设置的属性。

 <properties>
  <java.version>1.8</java.version>
   <image.prefix>kevinyan001</image.prefix>
   <docker.registry.url></private.registry.url>
 </properties>

这里能够随便设置成公有仓库的近程地址和镜像前缀,比方在阿里云的镜像服务上创立一个叫 docker-demo 的空间,下面的属性就须要这样配置:

 <properties>
   <java.version>1.8</java.version>
   <image.prefix>docker-demo</image.prefix>
   <docker.registry.url>registry.cn-beijing.aliyuncs.com</docker.registry.url>
 </properties>

POM 文件里配置好插件后随同着咱们打包利用执行 mvc clean package 操作时 dockerfile-maven-plugin 就会主动依据咱们的配置打包好一个叫做 kevinyan001/hello-spring:0.0.1-SNAPSHOT 的 Docker 镜像。

dockerfile-maven-plugin除了能帮忙咱们打包利用镜像外还能够让它帮忙咱们把镜像 push 到远端仓库,不过我感觉用途不大,感兴趣的同学能够去网上搜搜看这部分性能怎么配置。

Docker 的多阶段构建打包镜像

下面介绍了应用 Maven 插件帮忙咱们打包 Java 利用的镜像,其实咱们还能够把 mvn clean package 这一步也交给 Docker 来实现。当然把 Java 利用的源码放在 Docker 镜像里再编译打包在公布进来必定是有问题的,咱们晓得在 Dockerfile 里每个指令 ADDRUN 这些都是在独自的层上进行,指令越多会造成镜像越大,而且蕴含 Java 我的项目的源码也是一种危险。

不过好在起初 Docker 反对了多阶段构建,容许咱们在一个 Dockerfile 里定义多个构建阶段,先拉起一个容器实现用于的构建,比如说咱们能够在这个阶段里实现 JAR 的打包,而后第二个阶段从新应用一个 jre 镜像把上阶段打包好的 JAR 文件拷贝到新的镜像里。

应用上面的 Dockerfile 能够通过多阶段构建实现 Java 利用的 Docker 镜像打包。

 ​
 # Dockerfile 也能够不放在我的项目目录下,通过 -f 指定 Dockerfile 的地位,比方在我的项目根下执行以下命令 
 docker build -t <some tag> -f <dirPath/Dockerfile> .
 ​
 FROM kevinyan001/aliyun-mvn:0.0.1 AS MAVEN_BUILD
 ​
 COPY pom.xml /build/
 COPY src /build/src
 ​
 WORKDIR /build/
 # mount anonymous host directory as .m2 storage for contianer 
 VOLUME /root/.m2
 ​
 RUN mvn clean package -Dmaven.test.skip=true --quiet
 ​
 FROM openjdk:8-jre
 ​
 ​
 COPY --from=MAVEN_BUILD /build/target/*.jar /app/application.jar
 ​
 ENTRYPOINT ["java", "-jar", "/app/application.jar"]

下面咱们用的这些 Dockerfile 也能够不必放在我的项目的根目录里,当初曾经反对通过 -f 指定 Dockerfile 的地位,比方在我的项目根下执行以下命令实现镜像的打包。

 docker build -t kevinyan001/hello-spring:0.0.1 -f <dirPath/Dockerfile> .

下面第一个镜像是我本人做的,因为 Maven 官网的镜像的近程仓库慢的一批,只能本人包装一下走阿里云的镜像源了。试了试速度也不快,次要是随随便便一个 Spring 我的项目依赖就太多了。大家如果这块有什么放慢Docker 构建速度的办法也能够留言一起探讨探讨。

不可否认用多阶段构建打进去的 Go 镜像基本上是 10M 左右,然而 Spring 的利用随随便便就是上百兆,这个对容器的构建速度、网络传输老本是有影响的,那么 Spring 利用的镜像怎么瘦身呢,这个就留到当前的文章进行探讨了。

正文完
 0