社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

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

赵安家 • 5 年前 • 627 次点击  
阅读 334

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

加速和简化构建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命令用法

snipaste20190208_201332.png

小结

优点: 充分利用缓存,加快构建,不强制依赖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 构建过的任何变体。
  1. 快速——Jib 利用镜像分层和注册表缓存来实现快速、增量的构建。它读取你的构建配置,将你的应用程序组织到不同的层(依赖项、资源、类)中,并只重新构建和推送发生变更的层。在项目进行快速迭代时,Jib 只讲发生变更的层(而不是整个应用程序)推送到注册表来节省宝贵的构建时间。
  2. 可重现——Jib 支持根据 Maven 和 Gradle 的构建元数据进行声明式的容器镜像构建,因此,只要输入保持不变,就可以通过配置重复创建相同的镜像。

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

snipaste20190208_211839.png

参考资料


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/Ee6xhpWal2
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/28872
 
627 次点击