赵安家
2019年02月11日阅读 1518

关注

加速和简化构建Docker(基于Google jib)

介绍

其实jib刚发布时就有关注,但是一直没有用于生产,原因有二

先简单介绍一下: google jib 是Google于18年7月发布的一个针对Java应用的构建镜像的工具(支持MavenGradle) ,好处是能够复用构建缓存,能够加快构建,减小传输体积(后文会详细讲解),并且让Java工程师不需要理解Docker相关知识就可以简单构建镜像并且发布到指定registry里(不需要docker build , tag, push)

本文会依次讲解三种java构建镜像的方法,分别是 正统的Dockerfile ,spotify/dockerfile-maven ,Google jib 

附赠 alibaba/arthas 的集成和使用方法

准备

  • Maven3.5
  • Git
  • Jdk 1.8
  • Docker
$ git clone https://github.com/anjia0532/jib-demo.git
$ cd jib-demo
$ mvn clean package -DskipTests
$ mkdir docker
$ cp ./target/*.jar ./docker
复制代码

Dockerfile

创建 ./docker/Dockerfile ,内容如下,需要注意此处为了方便理解,没有进行改进(比如限制用户,安装必要软件等)

FROM openjdk:8-jdk-alpine

ADD *.jar /app.jar



EXPOSE 8080 CMD java ${JAVA_OPTS} /app.jar

复制代码

详情参见 官方文档 Dockerfile reference

$ cd ./docker
$ sudo docker build . -t jib-demo
$ docker images --查看本地images
$ docker tag jib-demo anjia0532/jib-demo --不写registry,则默认为docker hub registry,可以在build时,直接写
$ docker push anjia0532/jib-demo -- 推送到registry
复制代码

小结

优点: 不需要改造pom,灵活,配合CI工具,可以不侵入项目,运维可以针对性的进行安全加固,并且可以做到标准化

缺点: 命令复杂,Java程序员需要学习Dockerfile命令,或者运维和java沟通不畅时,时区,软件,甚至目录等都可能有出问题

spotify/dockerfile-maven

需要注意,spotify/dockerfile-maven 是需要pom+Dockerfile一块用的,而docker-maven-plugin是可选的

在项目根目录创建Dockerfile,如下所示

FROM openjdk:8-jdk-alpine

EXPOSE 8080

ARG JAR_FILE

ADD target/${JAR_FILE} /usr/share/myservice/myservice.jar



ENTRYPOINT ["/usr/bin/java", "-jar", "/usr/share/myservice/myservice.jar"]

复制代码

在pom里增加dockerfile-maven-plugin到build标签里

<build>
<plugins>
...
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile-maven-version}</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>anjia0532/dockerfile-maven-demo</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
...
<plugins>
<build>
复制代码

运行如下命令进行构建

$ mvn package -DskipTests
复制代码

详情参见 官方文档 spotify/dockerfile-maven

小结

优点: 减少了docker build & tag & push 的操作,Java程序员能够控制镜像名

**缺点: **其实就是省了docker build & tag & push的操作,别的缺点一点没落不说,还得改动pom,还得要求写Dockerfile,tag只支持一个等等

Google jib

修改默认settings.xml,增加registry认证,参见Authentication Methods

<settings>
...
<servers>
...
<server>
<id>docker_hub</id>
<username>MY_USERNAME</username>
<password>{MY_SECRET}</password>
</server>
</servers>
</settings>
复制代码

改动pom.xml 增加 jib插件

<project>
...
<build>
<plugins>
...
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>1.0.0</version>
<configuration>
<from>
<!-- 如果不需要arthas可以改为 registry.hub.docker.com/openjdk:8-jdk-alpine -->
<image>registry.hub.docker.com/hengyunabc/arthas:latest</image>
<credHelper>docker_hub</credHelper>
</from>
<to>
<image>${project.artifactId}</image>
<tags>
<tag>latest</tag>
<tag>${project.version}</tag>
</tags>
</to>
<container>
<mainClass>${start-class}</mainClass>
<ports>
<port>8080</port>
<port>5701/udp</port>
<port>8563</port>
</ports>
<entrypoint>
<shell>sh</shell>
<option>-c</option>
<arg>java -cp /app/resources/:/app/classes/:/app/libs/* com.example.demo.DemoApplication</arg>
</entrypoint>
<appRoot>/app</appRoot>
<useCurrentTimestamp>true</useCurrentTimestamp>
</container>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
复制代码

执行mvn clean compile jib:dockerBuild 构建docker镜像

注意: 

pom中用的是 registry.hub.docker.com/hengyunabc/arthas:latest 是 alibaba/arthas (阿里开源的一个Java诊断工具,便于线上调试)封装的docker镜像,如果不需要可以改成 registry.hub.docker.com/openjdk:8-jdk-alpine

$ docker run -d --init -p8563:8563 --name demo demo:latest
## 下面是启动arthas,如果使用的是openjdk镜像请勿执行
$ docker exec -it demo /bin/sh
$ jid=$(jps | grep App | awk '{print $1}')
$ java -jar /opt/arthas/arthas-boot.jar --target-ip 0.0.0.0 ${jid}
复制代码

如果使用了arthas镜像,可以访问 http://ip:8563 ,在页面上填上宿主ip,点击Connect, 然后参考Arthas/命令列表 了解Arthas命令用法


小结

优点: 充分利用缓存,加快构建,不强制依赖docker daemon,依赖简单(在maven或gradle增加插件即可)

缺点: 不支持Docker RUN 命令(jib官方建议将run封装到base镜像),对entrypoint和cmd支持不太好(alpine默认不支持多任务,跑java应用默认是pid 1 ,运行jmap等命令会报错,参考 jmap not happy on alpine )

jib 缓存策略

项目每次发布实际上变更的代码量不大,尤其依赖的jar变动的可能性较小,如果按照前两种方案构建镜像,会导致每次都全量构建,会导致存储和带宽资源浪费。

Jib 如何让开发变得更美好

Jib 利用了 Docker 镜像的分层机制,将其与构建系统集成,并通过以下方式优化 Java 容器镜像的构建:

  1. 简单——Jib 使用 Java 开发,并作为 Maven 或 Gradle 的一部分运行。你不需要编写 Dockerfile 或运行 Docker 守护进程,甚至无需创建包含所有依赖的大 JAR 包。因为 Jib 与 Java 构建过程紧密集成,所以它可以访问到打包应用程序所需的所有信息。在后续的容器构建期间,它将自动选择 Java 构建过的任何变体。
  2. 快速——Jib 利用镜像分层和注册表缓存来实现快速、增量的构建。它读取你的构建配置,将你的应用程序组织到不同的层(依赖项、资源、类)中,并只重新构建和推送发生变更的层。在项目进行快速迭代时,Jib 只讲发生变更的层(而不是整个应用程序)推送到注册表来节省宝贵的构建时间。
  3. 可重现——Jib 支持根据 Maven 和 Gradle 的构建元数据进行声明式的容器镜像构建,因此,只要输入保持不变,就可以通过配置重复创建相同的镜像。

可以可以通过 mvn clean compile jib:buildTar 生成 target/jib-image.tar 然后用解压缩工具解压后进行分析,实际上jib会将lib中非快照部分放到一个层,将快照部分放到一个层,将源码编译后放到一个层。。。


参考资料

招聘小广告

山东济南的小伙伴欢迎投简历啊 加入我们 , 一起搞事情。

长期招聘,Java程序员,大数据工程师,运维工程师。

原文地址:https://juejin.im/post/5c60c021f265da2dd37bf85b

加速和简化构建Docker(基于Google jib)的更多相关文章

  1. 基于url-to-pdf-api构建docker镜像,制作一个网页另存服务

    基于url-to-pdf-api构建docker镜像,制作一个网页另存服务 业务背景: 需要根据一个url路径打印这个网页的内容 解决方案: 1.使用wkhtml2pdf 2.使用puppeteer ...

  2. 使用Makefile构建Docker

    使用Makefile构建Docker 刚开始学习docker命令的时候,很喜欢一个字一个字敲,因为这样会记住命令.后来熟悉了之后,每次想要做一些操作的时候就不得不 重复的输入以前的命令.当切换一个项目 ...

  3. Maven插件构建Docker镜像

    背景 微服务架构下,微服务在带来良好的设计和架构理念的同时,也带来了运维上的额外复杂性,尤其是在服务部署和服务监控上.单体应用是集中式的,就一个单体跑在一起,部署和管理的时候非常简单,而微服务是一个网 ...

  4. SpringBoot 构建 Docker 镜像的 3 种方式

    本文将介绍3种技术,通过 Maven 把 SpringBoot 应用构建成 Docker 镜像. (1)使用 spring-boot-maven-plugin 内置的 build-image. (2) ...

  5. SpringBoot 构建 Docker 镜像的最佳 3 种方式

    本文将介绍3种技术,通过 Maven 把 SpringBoot 应用构建成 Docker 镜像. (1)使用 spring-boot-maven-plugin 内置的 build-image. (2) ...

  6. Jenkins + Github持续集成构建Docker容器,维基百科&人工自能(AI)模块

    本文分两部分,第一部分是手动计划任务的方式构建Github上的Docker程序,第二部分是用Github webhook Trigger一个自动构建任务. Jenkins采用2.5版本Docker采用 ...

  7. Pinpoint是一个开源的 APM (Application Performance Management/应用性能管理)工具,用于基于java的大规模分布式系统,基于Google Dapper论文

    Pinpoint是一个开源的 APM (Application Performance Management/应用性能管理)工具,用于基于java的大规模分布式系统,基于Google Dapper论文 ...

  8. 利用Dockerfile构建一个基于CentOS 7镜像

    利用Dockerfile构建一个基于CentOS 7,包括java 8, tomcat 7,php ,mysql+mycat的镜像. Dockerfile内容如下: FROM centosMAINTA ...

  9. 构建Docker镜像两种方式的比较-Dockerfile方式和S2I方式

    前言 写Dockerfile是构建Docker镜像最通常的方式,接触过Docker的童鞋多少了解一些.前段时间研究OpenShift(paas的一种),发现了另外一种构建Docker镜像的方式:S2I ...

随机推荐

  1. OO作业第三单元总结

    目录 一.JML语言理论基础及应用工具链 二.部署JMLUnitNG,自动生成测试用例 三.架构设计 第一次作业 第二次作业 第三次作业 四.Bug分析 五.心得体会 一.JML语言理论基础及应用工具 ...

  2. C++容器类-vector

    vecto之简单应用: #include<vector> #include<iostream> using namespace std; int main() { vector ...

  3. 如何使用动画库animate.css

    animate.css是一个CSS3动画库,里面预设了抖动(shake).闪烁(flash).弹跳(bounce).翻转(flip).旋转(rotateIn/rotateOut).淡入淡出(fadeI ...

  4. npm上发布包和删除已发布的npm包(https://www.npmjs.com/)

    1.npm上发布自己写的包 2.删除已经发布的包 npm unpublish --force //强制删除,这个是撤销24小时发布的包,有些包发布久了,这个方法不会再管用了. npx force-un ...

  5. 【0624作业】使用Scanner类输入并显示会员卡号

    package com.work0624; /** * 练习题 * 使用Scanner类输入并显示会员卡号 * @author L */ import java.util.Scanner; publi ...

  6. npm 安装插件失败

    由于npm的很多安装包的下载源来自国外网站,所以比较缓慢甚至访问失败. 再此可以用淘宝的镜像文件来安装插件.方法其实很简单:

  7. java基础——快速排序

    今天又把以前学的快速排序拿出来回忆一下 高快省的排序算法 有没有既不浪费空间又可以快一点的排序算法呢?那就是“快速排序”啦!光听这个名字是不是就觉得很高端呢. 假设我们现在对“6 1 2 7 9 3 ...

  8. Find the Longest Word in a String-freecodecamp算法题目

    Find the Longest Word in a String(找出最长单词) 要求 在句子中找出最长的单词,并返回它的长度 函数的返回值应该是一个数字. 思路 用.split(' ')将句子分隔 ...

  9. python 项目中包中__init__.py文件的作用

    开发python项目时,我遇到了一个这样的现象,当我新建一个pythonpackage时,总会自动地生成一个空的__init__.py文件,因为是python新手,所以很不了解这个空文件的作用是什么, ...

  10. NXP低功耗蓝牙集成芯片QN9080C的时钟配置

    /*************************************************************************************************** ...