概念
Google Jib 容器化构建工具
Jib是google开源的Java容器化工具,可以直接构建 Java 应用的 Docker 和 OCI 镜像的类库,以 Maven 和 Gradle 插件形式提供。
通过 Jib,Java 开发者可以使用他们熟悉的 Java 工具来构建容器。Jib 是一个快速而简单的容器镜像构建工具,它负责处理将应用程序打包到容器镜像中所需的所有步骤。它不需要你编写 Dockerfile 或安装 Docker,而且可以直接集成到 Maven 和 Gradle中—— 只需要将插件添加到构建中,就可以立即将 Java 应用程序容器化。
Docker 构建流程

讯享网
Jib 构建流程

简单——Jib使用Java开发,并作为Maven或Gradle的一部分运行。你不需要编写Dockerfile或运行Docker守护进程,甚至无需创建包含所有依赖的大JAR包。因为Jib与Java构建过程紧密集成,所以它可以访问到打包应用程序所需的所有信息。在后续的容器构建期间,它将自动选择Java构建过的任何变体。
快速——Jib利用镜像分层和注册表缓存来实现快速、增量的构建。它读取你的构建配置,将你的应用程序组织到不同的层(依赖项、资源、类)中,并只重新构建和推送发生变更的层。在项目进行快速迭代时,Jib只将发生变更的层(而不是整个应用程序)推送到注册表来节省宝贵的构建时间。
可重现——Jib支持根据Maven和Gradle的构建元数据进行声明式的容器镜像构建,因此,只要输入保持不变,就可以通过配置重复创建相同的镜像。
简化
快速 — 快速部署您的更改。Jib 将你的应用程序分成多个层,从类中分离依赖项。你不必等待 Docker 重建整个 Java 应用程序 —— 只需部署更改的层即可 可重现 — 使用相同内容重建容器镜像 Daemonless — 减少 CLI 依赖性。从 Maven 或 Gradle 中构建 Docker 镜像,然后推送到你选择的任何注册表,无需编写 Dockerfiles 并调用 docker build/push
讯享网
下图为某微服务开启 Jib 构建后在 Jenkins 中的构建过程,可以看出构建速度的提升主要在 package 和 push 阶段。

原理
假设我们有一个项目,其组织结构如下:
讯享网parentPro |-- moduleA |-- moduleB |-- rest [rest 模块为 spring boot 启动入口,并依赖 moduleA、moduleB]
对于 SpringBoot 项目,Maven 的默认构建工具是 Spring-boot-maven-plugin,构建出产物为 Fat Jar。Fat jar 中包含有 rest 模块中的 classes,及 rest 所依赖的 moduleA、moduleB 及其他第三方 jar 库。最终,通过 Jenkins 的 Dockerfile 文件将 Fat jar 基于 JDK 基础镜像层构建,产生一个新的应用镜像。
每次应用构建新版本镜像时,因为 Maven 构建产出物是 Fat jar,当 rest、moduleA、moduleB 模块中任意一处发生变化时,都会产出一个新的 Fat jar。构建镜像时都要将整个 Fat jar 重新写入到镜像层,并将整个镜像层推送到镜像仓库中,大大降低了镜像构建和推送的性能,并导致同一个应用镜像的多个 Tag 占用大量的存储空间。
Jib 在编译 Java 应用时,会将 Java 项目内的资源及所依赖的资源,基于变化频率不同分成多个部分,并将每个部分都单独作为一个镜像层存在,这样其中一部分资源发生变化时,只需要重新构建该部分所属镜像层即可。
以第二节的应用为例,rest 应用镜像将被分为以下镜像层:
Classes: rest 模块中的class信息,这部分信息变化频率最高,处于最上层镜像层;
Resources: rest 模块中的配置文件,这部分信息变化频率较低,处于第二层镜像层;
Project Dependencies: rest 模块的项目依赖信息,在当前示例中为 moduleA、moduleB,这部分内容比依赖第三方 Jar 库更容易变化,所以也单独做为一个镜像层存在;

Snapshot Dependencies:rest 模块所依赖的 SnapShot Jar 库;
All other Dependencies: rest 模块所依赖的其他类型 Jar 库;
Each extra directory:其他所依赖额外资源目录;
基于Jib 插件构建出的镜像,与使用以下 Dockerfile 所构建出的镜像相同:

使用
关键几步
配置 parent 的 pom
<properties> <!-- 要想本地可以上传到阿里云,请使用公网地址 registry.cn-shenzhen.aliyuncs.com --> <docker.repostory>registry-vpc.cn-shenzhen.aliyuncs.com</docker.repostory> <docker.repostory.namespace>syp-app</docker.repostory.namespace> <docker.project.version>1.0</docker.project.version> </properties> <build> <pluginManagement> <plugins> <!-- spring-boot-maven-plugin --> <plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <version>1.7.0</version> <configuration> <!-- 拉取所需的基础镜像 - 即构建本镜像所基于的根镜像 --> <from> <image>${docker.repostory}/syp-common/openjdk:8-jdk-alpine</image> <auth> <username>在阿里云上的账号</username> <password>阿里云注册的密码</password> </auth> </from> <!-- 最后生成的镜像配置 --> <!-- 表示本镜像构建完成后,要发布到哪里去 --> <to> <!-- push到阿里云镜像仓库,如果是其它镜像仓库,将下面地址替换掉即可,ex: `Docker Hub` 的 `docker.io/zhengqing/xxx` --> <!-- 镜像名,命名格式为:Registry 仓库地址/属组/镜像名:Tag名 --> <image> ${docker.repostory}/${docker.repostory.namespace}/${project.artifactId} </image> <tags> <tag>${docker.project.version}</tag> <tag>latest</tag> </tags> <!-- 阿里云的用户名和密码也可以配置在 maven settings.xml文件中(推荐) --> <!--插件配置中的用户密码及镜像库地址在ci的环境变量中配置 --> <auth> <username>在阿里云上的账号</username> <password>阿里云注册的密码</password> </auth> </to> <container> <jvmFlags> <jvmFlag>-Xms512m</jvmFlag> <jvmFlag>-Xmn256m</jvmFlag> </jvmFlags> <environment> <TZ>Asia/Shanghai</TZ> </environment> <useCurrentTimestamp>true</useCurrentTimestamp> </container> <!--允许使用 HTTP 协议连接 Registry 仓库--> <allowInsecureRegistries>true</allowInsecureRegistries> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> </executions> </plugin> </plugins> </pluginManagement> </build>
配置 module 的 pom
讯享网 <parent> <groupId>com.missyou</groupId> <artifactId>missyou</artifactId> <version>1.0-SNAPSHOT</version> </parent> <groupId>com.missyou</groupId> <artifactId>missyou_user_service</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <build> <finalName>missyou_user_service</finalName> <plugins> <!-- spring-boot-maven-plugin --> <!-- maven-compiler-plugin --> <plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> </plugin> </plugins> </build>
配置maven settings.xml文件(推荐)
<pluginGroups> <pluginGroup>com.google.cloud.tools</pluginGroup> </pluginGroups> <!--对应容器仓库权限的账号密码--> <servers> <server> <id>registry-vpc.cn-shenzhen.aliyuncs.com</id> <username>xxx</username> <password>xxx</password> </server> </servers>
配置 .gitlab-ci.yml
讯享网image: xxx.com/xxx-tools/cibase:0.5.0 variables: MAVEN_OPTS: -Dmaven.repo.local=.m2/repository BUILD_CI_NAME: $CI_COMMIT_REF_NAME-$CI_PIPELINE_ID stages: - build - dev-release cache: key: one-key-for-all paths: - .m2/repository/ build: stage: build script: "mvn -U clean compile" dev-release: stage: dev-release only: - tags - development-uat - /^release-.*$/ when: manual script: - "mvn compile jib:build -Dregistry_url=$REGISTRY_URL -Dregistry_username=$REGISTRY_USERNAME -Dregistry_password=$REGISTRY_PASSWORD -Dci_pipeline_id=$BUILD_CI_NAME"
配置完毕后,使用如下命令编译,并自动 push 到仓库中:
mvn clean package -DskipTests jib:build 核心就是 jib:build,更多命令见文档: https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#build-your-image
鉴权
根据错误日志可知连接 Registry 仓库时需要鉴权

maven 报错
解决-命令行
最粗暴的,在执行 maven 命令时传递 Registry 仓库的用户名密码
讯享网mvn clean package -DskipTests jib:build \ -Djib.from.auth.username=admin \ -Djib.from.auth.password=admin \ -Djib.to.auth.username=admin \ -Djib.to.auth.password=admin
由于 <from> 和 <to> 中的镜像 可能不是来自于同一个 Registry 仓库,因此既要配置 from 的用户名密码,也要配置 to 的用户名密码。
执行完毕后,通过命令行,或者可视化工具,查看是否被 push 上去(此处我使用的工具是 Harbor)

解决-配置文件
使用命令行方式每次执行都要输入那么长一串命令,这样实在是不方便。另一种方法是在 pom.xml 文件直接将用户名密码配置进去
<plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <version>1.8.0</version> <configuration> <from> <image>harbor.jitwxs-inc.com/base/java:8-jdk-alpine</image> <auth> <username>my_username</username> <password>my_password</password> </auth> </from> <to> <image>harbor.jitwxs-inc.com/sample/${artifactId}:v1</image> <auth> <username>my_username</username> <password>my_password</password> </auth> </to> <allowInsecureRegistries>true</allowInsecureRegistries> </configuration> </plugin>
即给 from 和 to 标签都加上 <auth> 标签,但是这种方式实在是不够优雅,因为将用户名密码硬编码在代码中会带来安全性问题
合适的方法
合适的方法是配置在 Maven 的 settings.xml 配置文件中,在 <servers> 标签中新增一个 <server> 节点,配置 Registry 仓库的用户名密码。
讯享网<servers> ... <server> <id>harbor.jitwxs-inc.com</id> <username>admin</username> <password>admin</password> <configuration> <email></email> </configuration> </server> </servers>
配置完毕后,再执行次命令验证下:
mvn clean package -DskipTests jib:build
不想单独输入 jib:build
如果你不想单独输入 jib:build,你可以把 jib 绑定到 Maven 命令中,在maven插件中添加如下的<executions>标签即可。
讯享网<plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> ... <executions> <execution> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> </executions> </plugin>
mvn package 命令就会自动构建镜像
工作中
maven 中 pom 中标签含义
查看百度网盘

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/63320.html