优秀的编程知识分享平台

网站首页 > 技术文章 正文

JAVA项目中实现优雅地构建和管理容器镜像和版本

nanyue 2024-08-09 07:00:42 技术文章 6 ℃

一、背景

Docker镜像采用了分层结构,如果所有的应用程序都使用了相同的基础镜像,就可以节省 Docker 注册表的存储空间,上传和下载镜像的速度也更快了,因为只需要传输更少的文件量(Docker 只会将新的层传输到注册表中)。一般公司由于网络条件限制,导致应用发布时传输速度较慢,因此需要考虑优化Docker镜像构建。

以下是系统中典型的镜像分层结构(通过docker history查看),其中每一行代表一个镜像层,上半部分红色框内的是应用程序构建的镜像层,下半部分是源镜像层。源镜像层很少改动,每次构建都会复用,本文中所作的优化是针对上半部分的应用程序镜像层。


二、优化方案

采用JIB工具对Spring Boot应用程序进一步分层,将其中的依赖项、资源文件和应用代码构建为独立的镜像层,由于依赖项通常体积较大且改动较少,因此能充分利用镜像分层复用的机制。


三、实施步骤

1.修改项目的父POM

<properties>中加入以下自定义property:

<image.tag>default</image.tag>

<registry.username>default</registry.username>

<registry.password>default</registry.password>

<pluginManagement>中加入JIB插件及相关配置,此处配置包含了Dockerfile中的内容(Dockerfile不再起作用,建议删除)

为方便起见,将镜像构建过程绑定到Maven的install生命周期中;

configuration.from.image中配置源镜像地址,configuration.to.image中配置目标镜像推送地址,下图中的xxxx对应于镜像仓库中各项目的namespace;

container.creationTime须配置符合DateTimeFormatter.ISO_DATE_TIME格式的时间,例如2019-07-15T10:15:30+08:00。如果设置为当前时间(USE_CURRENT_TIMESTAMP),则每次生成的镜像就不相同,从而无法复用,因此,仅当依赖项改动时再去更新该时间。

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>1.8.0</version>
    <executions>
        <execution>
            <phase>install</phase>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <allowInsecureRegistries>true</allowInsecureRegistries>
        <from>
            <image>registry.cn-hangzhou.aliyuncs.com/kancy/openjdk:8-jre-alpine</image>
            <auth>
                <username>${registry.username}</username>
                <password>${registry.password}</password>
            </auth>
        </from>
        <to>
            <image>registry.cn-hangzhou.aliyuncs.com/kancy/${project.artifactId}-jib:${image.tag}</image>
            <auth>
                <username>${registry.username}</username>
                <password>${registry.password}</password>
            </auth>
        </to>
        <container>
            <creationTime>2020-05-01T10:00:00+08:00</creationTime>
            <volumes>/tmp</volumes>
            <workingDirectory>/home</workingDirectory>
            <environment>
                <TZ>Asia/Shanghai</TZ>
            </environment>
        </container>
    </configuration>
</plugin>

注意:

以上配置项仅包含了目前一般Springboot项目中典型的Dockerfile内容(如下所示),如果在原Dockerfile中有额外命令,需要在POM文件中添加相应的配置,或考虑包含到源镜像中,详情可参考官方文档。

docker registry 认证信息也可以配置在settings.xml

其中server.id为 docker registry仓库地址

<servers>
  
	<server>
  
	  <id>registry.cn-hangzhou.aliyuncs.com</id>

	  <username>vlovev_cn</username>

	  <password>********</password>

	</server>

</servers>

修改各应用的POM文件

在build.plugins内加入以下项即可,注意非应用类型的module不要添加。

<plugin>
  
    <groupId>com.google.cloud.tools</groupId>

    <artifactId>jib-maven-plugin</artifactId>

</plugin>

在Rancher管理界面中修改应用配置中的环境变量名称

更新以下环境变量名称:

JAVA_OPS替换为: JAVA_TOOL_OPTIONS

PROFILE 替换为: spring.profiles.active

注:原Dockerfile启动命令中如果定义了其他环境变量,也需要在此添加。


四、查看效果

以下是JIB构建的镜像,可以看到应用程序中的依赖项、资源文件和应用代码被构建为独立的镜像层。应用重新构建时如果没有改动依赖项,则只有极少的文件量需要传输。


五、参考

【1】不要把大型JAR包放进Docker镜像_文化 & 方法_Philipp Hauer_InfoQ精选文章

最近发表
标签列表