一、序言
近几年,微服务已经成为Java主流的技术方向,随着微服务化的流行,应用容器化部署也是必不可少的。应用容器化用抽象的话来说就是:将应用程序部署到容器当中作为独立的应用程序部署单元运行,并作为实现高级别资源隔离的机制。常见的容器化技术就是docker,所以简单来说就是将微服务程序打包成镜像,在容器中运行,但这样做有一个关键问题,就是docker镜像越大,部署的效率越低,希望通过本文为你容器化部署提供效率。
二、 使用原始的方式构建一个docker镜像
我们先用原始的方式制作一个Spring boot应用程序镜像,体会一下目前流行的容器化部署方式。
1. 创建spring boot应用
我们编写一个简单的应用程序,只有一个hello的controller即可
如果你不想创建该项目,可以从这里看到源码
打开浏览器简单测试一下:
2. 打包
root@ubuntu:docker-image-demo$ mvn package
3.编写Dockerfile
#Dockerfile 这里我们选用 jre环境 减少镜像的体积
FROM openjdk:8-jre-alpine
#镜像内部创建一个app目录 用来存放jar包
RUN mkdir /app
#复制jar包 到app目录下
COPY target/docker-image-demo-0.0.1-SNAPSHOT.jar /app/app.jar
#暴露端口
EXPOSE 8080/tcp
#默认启动程序
ENTRYPOINT java -jar /app/app.jar
4. 创建镜像
#创建镜像
root@ubuntu:docker-image-demo$ docker build -t docker-image-demo:0.0.1 .
#查询镜像
root@ubuntu:docker-image-demo$ docker images
5. 推送镜像到registry仓库
#将镜像推送到镜像仓库 这里我们选择阿里云的镜像仓库
#登录的步骤 请自行查阅阿里云镜像仓库
root@ubuntu:docker-image-demo$ docker tag docker-image-demo:0.0.1 registry.cn-hangzhou.aliyuncs.com/jk1123/docker-jib-test:0.0.1
#推送
root@ubuntu:docker-image-demo$ docker push registry.cn-hangzhou.aliyuncs.com/jk1123/docker-jib-test:0.0.1
在阿里云仓库查看镜像
三、原始方式的不足
1. 需要编写Dockerfile
镜像的打包部署本身属于运维工作,但是需要开发人员的介入,解放应用开发人员的双手,不要将运维的工作引入到开发人员的工作流中
2. 制作镜像耗时
使用springboot的项目打包而成的jar包是一个fat jar(就是该jar中包含该应用程序需要一切依赖).导致docker镜像制作过程当中需要复制该jar到容器中
稍微大一点应用程序打成fat jar 高达一两百MB,其实最主要还是依赖的sprring全家桶的jar太多
3. 推送镜像到仓库和拉取镜像耗时
微服务的使用便于快速迭代服务,所以发版的频率十分频繁.每次推送镜像/拉取镜像十分耗时,因为每次发版我们的fat jar都会发生细微的改变.导致docker无法利用其缓存机制,每次都要拉取镜像中的fat jar 那层.导致推送和拉取十分消耗网络资源和时间
四、 使用Google jib工具
1. 简介
Jib 是谷歌公司推出的开源 Java 镜像构建工具,它可以将一个 Java 应用构建成 OCI 镜像或者是 Docker 镜像,目前最新的 Relaese 版本为 3.2.1
JIB 具有以下特点:
-
Jib 使用 Java 开发,并作为 Maven 或 Gradle 的一部分运行.你不需要编写 Dockerfile 或 安装Docker 环境,甚至无需创建包含所有依赖的大 JAR 包,就可以构建出镜像,并将镜像推送到镜像仓库。因为 Jib 与 Java 构建过程紧密集成,所以它可以访问到打包应用程序所需的所有信息。在后续的容器构建期间,它将自动选择 Java 构建过的任何变体。
-
JIB 构建出的应用镜像,具有分层结构, 利用镜像分层和注册表缓存来实现快速、增量的构建,提高构建镜像、推送镜像的性能,减少镜像存储空间。
-
幂等性,Jib 支持根据 Maven 和 Gradle 的构建元数据进行声明式的容器镜像构建,只要输入保持不变,就可以通过配置重复创建相同的镜像。
下图是官方给出的性能测试
2.使用
如此强大的工具使用起来相当的简单
2.1 导入插件依赖
<!--