容器化部署 Jib

2023-11-15

概念

Google Jib 容器化构建工具

Jibgoogle开源的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 依赖性。从 MavenGradle 中构建 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 JarFat 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>admin@jitwxs-inc.com</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 中标签含义

查看百度网盘
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

容器化部署 Jib 的相关文章

  • 使用 Java 在 WebDriver 中按 Ctrl+F5 刷新浏览器

    我已经使用 java 刷新了 WebDriver 中的浏览器 代码如下 driver navigate refresh 如何使用 Java 在 WebDriver 中按 Ctrl F5 来做到这一点 我认为您可以使用 WebDriver 和
  • 无法使用 json 架构验证器根据预定义的 yaml 文件验证查询参数

    我需要根据预定义的 yaml 文件架构验证查询参数的架构 因此我使用 json 架构验证器 验证如何失败 我正在执行以下步骤 填充参数和相应的架构 final List
  • 哪个 Swing 布局管理器可以获得我想要的布局?

    我正在尝试按照这个模型制作一个基本的登录菜单 我决定将整个菜单放入 JPanel 中 以便在连接成功后我可以切换到另一个面板 所以我决定使用 Borderlayout 将标题放在北区 将连接按钮放在南区 我将边框布局的中心本身设置为面板 我
  • 将过滤器添加到 Eclipse 中的 Project Explorer

    我想向 Project Explorer 添加一个新的过滤器 以向用户隐藏一些在 Eclipse RCP 应用程序中自动创建的项目 到目前为止我已经找到了两个扩展点 org eclipse ui ide resourceFilters 允许
  • 如何拦截 REST 端点以接收所有标头?

    我当前的代码是 Path login RequestScoped public class LoginResource GET SecurityChecked public Response getUser HeaderParam AUTH
  • Java Microsoft Excel API [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 所有平台上的java

    如果您想用 java 为 Windows Mac 和 Linux 编写桌面应用程序 那么所有这些代码都相同吗 您只需更改 GUI 即可使 Windows 应用程序更像 Windows 等等 如果不深入细节 它是如何工作的 Java 的卖点之
  • 线程“main”中的异常 java.lang.StackOverflowError

    我有一段代码 但我无法弄清楚为什么它在线程 main java lang StackOverflowError 中给出异常 这是问题 Given a positive integer n prints out the sum of the
  • Intellij 中的 Google OR-Tools:UnsatisfiedLinkError

    我正在建立一个应该使用 Google OR Tools 的 java 框架 下面的代码编译成功 但在运行时抛出异常 Exception in thread main java lang UnsatisfiedLinkError com go
  • Jenkins 的代码覆盖率 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 当您在数组列表上调用remove(object o)时,它如何比较对象?

    当您在 java 中的数组列表上调用remove object o 时 它如何比较对象以找到要删除的正确对象 它使用指针吗 或者它使用 Comparable 接口来比较对象吗 ArrayList remove 依赖于对象的实现Equal方法
  • Java:java.util.ConcurrentModificationException

    我正在制作 2D 目前正在研究用子弹射击 子弹是一个单独的类 所有项目符号都存储在称为项目符号的数组列表中 当它超出屏幕一侧 Exception in thread main java util ConcurrentModification
  • 创建正则表达式匹配数组

    在Java中 我试图将所有正则表达式匹配返回到一个数组 但似乎您只能检查模式是否匹配某些内容 布尔值 如何使用正则表达式匹配来形成与给定字符串中的正则表达式匹配的所有字符串的数组 4城堡的回答 https stackoverflow com
  • Hibernate HQL:将对值作为 IN 子句中的参数传递

    我面临一个问题 如何使用 IN 子句将查询中的成对值的参数传递给 HQL 例如 select id name from ABC where id reg date in x y 并且参数是不同的数据类型string id 和reg date
  • 了解 Spark 中的 DAG

    问题是我有以下 DAG 我认为当需要洗牌时 火花将工作划分为不同的阶段 考虑阶段 0 和阶段 1 有些操作不需要洗牌 那么为什么 Spark 将它们分成不同的阶段呢 我认为跨分区的实际数据移动应该发生在第 2 阶段 因为这里我们需要cogr
  • 如何初始化静态地图?

    你会如何初始化静态Map在Java中 方法一 静态初始化方法二 实例初始化 匿名子类 或者 还有其他方法吗 各自的优点和缺点是什么 这是说明这两种方法的示例 import java util HashMap import java util
  • Java:由 HTTP 连接创建的等待连接线程存活时间很长

    我有一个服务器端代码 用于检查 SOAP 服务是否已启动 代码如下 String response while response length 0 try final URL url new URL DummySoapServiceURL
  • 失败时石英重试

    假设我有一个这样配置的触发器
  • 防止Java实例化的正确方法[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 每次我们调用浏览器时,在 selenium 中使用 driver.manage().window().maximize() 是否好?

    We use driver manage window maximize 最大化浏览器 我在网上看到一些使用的例子driver manage window maximize 尽管不需要最大化浏览器 例如 gmail 登录 我还看到使用 se

随机推荐

  • SqlServe--从字符串中提取数字

    1 基础使用 声明一个nvarchar类型的变量并赋值 declare Name nvarchar 50 set Name 我正在123学 习22 SQL中11 的一些函数 patindex函数返回所查内容在字符串中第一次出现的内容 pri
  • STM32 (十五)ESP8266WIFI

    简介 1 ESP8266wifi 模块 低功耗串口WiFi模块ESP8266内置一个Tensilica 泰思立达 Xtensa架构的32位处理器L106 具有5级流水线 ARM CortexM3是3级流水线 最大时钟速度为160MHz 可以
  • JMM简单理解

    JMM java内存模型 代码理解 public class test private static boolean f false public static void main String args throws Interrupte
  • Python日志记录基础教程:logging模块详解与示例代码

    Python日志记录基础教程 logging模块详解与示例代码 在Python应用程序的开发过程中 日志记录是一个重要的组成部分 它能够帮助开发人员追踪和调试代码 并记录应用程序的运行情况 Python标准库中的logging模块提供了一个
  • 【计算机视觉

    文章目录 一 CBC Complete Blood Count 二 CURE TSD CURE Traffic Sign Detection 三 DUO Detecting Underwater Objects 四 Duke Breast
  • 方法的重写-overrideoverwrite

    方法的重写 override overwrite 1 定义 定义 子类继承父类以后 可以对父类中同名同参数的方法 进行覆盖操作 应用 重写以后 当创建子类对象以后 通过子类对象调用子父类中的同名同参数的方法时 实际执行的是子类重写的方法 使
  • 2D和3D人体姿态数据集

    转自链接 https www jianshu com p c046db584a21 2D数据集 LSP 地址 http sam johnson io research lsp html 样本数 2k 关节点数 14 全身 单人 FLIC 地
  • 用go实现一个telnet带上账号密码的协议请求

    实现一个telnet协议请求 需要用到网络编程的知识 下面是一份简单的代码示例 package main import bufio fmt net strings func main ln err net Listen tcp 8080 i
  • 数据结构之直接插入排序(算法思想,复杂度分析)以及冒泡排序和直接插入排序的比较

    一般来说 插入排序都采用in place在数组上实现 具体算法描述如下 从第一个元素开始 该元素可以认为已经被排序 取出下一个元素 在已经排序的元素序列中从后向前扫描 如果该元素 已排序 大于新元素 将该元素移到下一位置 重复步骤3 直到找
  • 【算法入门12】链表合并

    核心考点 链表合并 思维缜密程度 输入两个递增的链表 合并这两个链表并使新链表中的结点仍然是递增排序的 解析一 常规 合并两个链表最常规的做法就是 依次比较两个链表的第一个结点 取较小的结点 此处为递增排序 尾插到一个新链表后 直到其中一个
  • C语言 缓存区溢出 3221225725

    目录 问题描述 解决办法 问题描述 DEV C报错 Process exited after 4 03 seconds with return value 3221225725 原因 数组定义的容量太大 五十万起步的样子 而且每次循环都会再
  • Laravel定时任务的每秒执行

    我的个人博客 逐步前行STEP laravel中的任务调度可以不将每条命令都写入crontab 便于管理维护 而且可以基于laravel框架环境运行 而不需写独立的脚本执行 非常方便 但是最小的执行间隔也是一分钟 要想达到每秒执行的效果 就
  • 2018.7.18 something you want to replace

    Something I want to replace is iphone6 which looks like a small box When I come to university my parents brought me this
  • 【C++ Core Guidelines解析】C++学习之路的一盏明灯

    前言 C 语言的功能非常丰富 表达能力非常强 因为一种成功的通用编程语言拥有的功能必须比任何开发人员所需要的更多 任何一种有生命力且不断发展的语言都会不断积累用于表达程序员思想的替代用法 这会导致选择过载 那么 开发人员应该如何根据编程风格
  • 旧手机改服务器,并配合花生壳实现外网访问的方法

    旧手机改服务器 并配合花生壳实现外网访问的方法 前提准备 开始手机端操作 开始电脑端操作 至此所有操作结束 前提准备 1 手机必须root 2 busybox 3 linux deploy 4 花生壳安卓内网穿透版 下载时注意 有个管理版
  • 测试开发学习路线

    测试开发学习路线 HI 大家好 我是Lee 通过某些圈子了解大家对于测试开发这个岗位了解的很模糊 对于技术栈不知道应该学习什么 接下来就通过各方面来说一下测试开发具体是做什么以及需要掌握哪些技术 1 了解测试开发 什么是测试开发 大家应该都
  • 【学习笔记】mybatis-generator自动生成工具的使用教程 2021最新版

    一 什么是mybatis generator mybatis geneator是一款mybatis自动代码生成工具 可以通过配置 快速生成DAO POJO和xml等文件 二 如何在IDEA上使用mybatis generator 1 导入依
  • Redis Stream 数据结构实现原理真的很强

    1 是什么 Stream 是 Redis 5 0 版本专门为消息队列设计的数据类型 借鉴了 Kafka 的 Consume Group 设计思路 提供了消费组概念 同时提供了消息的持久化和主从复制机制 客户端可以访问任何时刻的数据 并且能记
  • dft转换与反转

    这次介绍下opencv中DFT的使用 对应的例程是 EXAMPLE dft 在图像处理领域 通过DFT可以将图像转换到频域 实现高通和低通滤波 还可以利用矩阵的卷积运算等同于其在频域的乘法运算从而优化算法降低运算量 即先将图像转换到频域 然
  • 容器化部署 Jib

    概念 Google Jib 容器化构建工具 Jib是google开源的Java容器化工具 可以直接构建 Java 应用的 Docker 和 OCI 镜像的类库 以 Maven 和 Gradle 插件形式提供 通过 Jib Java 开发者可