其实jib刚发布时就有关注,可是一直没有用于生产,缘由有二php
先简单介绍一下: google jib 是Google于18年7月发布的一个针对Java应用的构建镜像的工具(支持Maven和Gradle) ,好处是可以复用构建缓存,可以加快构建,减少传输体积(后文会详细讲解),而且让Java工程师不须要理解Docker相关知识就能够简单构建镜像而且发布到指定registry里(不须要docker build , tag, push)html
本文会依次讲解三种java构建镜像的方法,分别是 正统的Dockerfile ,spotify/dockerfile-maven ,Google jib
附赠 alibaba/arthas 的集成和使用方法java
google jib 和 Dragonfly 系列文章git
$ git clone https://github.com/anjia0532/jib-demo.git
$ cd jib-demo
$ mvn clean package -DskipTests
$ mkdir docker
$ cp ./target/*.jar ./docker
复制代码
建立 ./docker/Dockerfile
,内容以下,须要注意此处为了方便理解,没有进行改进(好比限制用户,安装必要软件等)程序员
FROM openjdk:8-jdk-alpine
ADD *.jar /app.jar
EXPOSE 8080
CMD java ${JAVA_OPTS} /app.jar 复制代码
详情参见 官方文档 Dockerfile referencegithub
$ 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沟通不顺畅时,时区,软件,甚至目录等均可能有出问题docker
须要注意,spotify/dockerfile-maven 是须要pom+Dockerfile一块用的,而docker-maven-plugin是可选的shell
在项目根目录建立Dockerfile,以下所示segmentfault
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只支持一个等等
修改默认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 )
项目每次发布实际上变动的代码量不大,尤为依赖的jar变更的可能性较小,若是按照前两种方案构建镜像,会致使每次都全量构建,会致使存储和带宽资源浪费。
Jib 如何让开发变得更美好
Jib 利用了 Docker 镜像的分层机制,将其与构建系统集成,并经过如下方式优化 Java 容器镜像的构建:
- 简单——Jib 使用 Java 开发,并做为 Maven 或 Gradle 的一部分运行。你不须要编写 Dockerfile 或运行 Docker 守护进程,甚至无需建立包含全部依赖的大 JAR 包。由于 Jib 与 Java 构建过程紧密集成,因此它能够访问到打包应用程序所需的全部信息。在后续的容器构建期间,它将自动选择 Java 构建过的任何变体。
- 快速——Jib 利用镜像分层和注册表缓存来实现快速、增量的构建。它读取你的构建配置,将你的应用程序组织到不一样的层(依赖项、资源、类)中,并只从新构建和推送发生变动的层。在项目进行快速迭代时,Jib 只讲发生变动的层(而不是整个应用程序)推送到注册表来节省宝贵的构建时间。
- 可重现——Jib 支持根据 Maven 和 Gradle 的构建元数据进行声明式的容器镜像构建,所以,只要输入保持不变,就能够经过配置重复建立相同的镜像。
能够能够经过 mvn clean compile jib:buildTar
生成 target/jib-image.tar
而后用解压缩工具解压后进行分析,实际上jib会将lib中非快照部分放到一个层,将快照部分放到一个层,将源码编译后放到一个层。。。
山东济南的小伙伴欢迎投简历啊 加入咱们 , 一块儿搞事情。
长期招聘,Java程序员,大数据工程师,运维工程师。