引言
为了提升研发中心整体效能,农业银行于2019年启动了DevOps首批试点项目的评估工作,并于2020年5月顺利通过由中国信息通信研究院开展的《研发运营一体化(DevOps)能力成熟度模型》持续交付部分三级评估,标志着农业银行相关项目持续交付能力达到国内领先水平。在逐步完善持续交付能力的过程中涌现了许多最佳实践,制品与自动化测试报告双向追溯便是其中之一。
制品库在 DevOps 流程中承担着存储各个阶段制品,并保留制品各阶段属性的工作,制品库的管理工作对于DevOps有着非常重要的意义。本文主要介绍农业银行是如何利用Artifactory工具实现制品自动化清理。
一、制品仓库清理的必要性
制品就是构建过程的输出物,包括软件包,测试报告,应用配置文件等可在服务器上直接运行或可查看二进制形式的文件,通常称之为二进制软件制品。制品管理是对软件研发过程中生成的产物的管理,一般作为最终交付物完成发布和交付。随着 DevOps 推广的进行,农行越来越多的制品包纳入了制品库中统一管理,随着制品数量的增加制品库的存储成为了制品管理的一个瓶颈,开发人员希望尽可能多的保留制品,而制品库管理人员基于管理成本的考虑希望减少制品的存储,需求与管理产生了必然矛盾,因此制定合理的制品清理策略,既满足开发人员的开发、测试、投产需求又不会过多的占用大量空间,成为了 DevOps 推广过程中必不可少的一部分。
图1 制品库存储空间分布图(单位G)
二、制品清理策略的制定
目前由于镜像制品和普通制品(非镜像制品)的存储方式、大小、规则都不相同,我们把制品分为镜像制品和普通制品两种类型进行存储和管理。同时,按照制品成熟度的不同,分为开发阶段制品、测试阶段制品、预投产阶段制品和投产阶段制品。与制品的成熟度相对应,分别建立了四个制品仓库,即开发仓库、测试仓库、预投产仓库、投产仓库。
根据制品的以上属性,我们制定了不同的清理策略。
普通制品:
开发仓库存储项目组开发过程中的制品包,开发制品包变更频率非常快,几乎一天就上传0-10个,最终投产使用的只有0-1个,所以根据投产周期,制品库存储了两个投产周期的制品。
测试仓库存储项目组测试过程中的制品包,测试制品包变更频率比较快,平均每天上传0-10个,最终投产使用的只有0-1个,所以根据投产周期,存储了两个投产周期的制品。
预投产仓库存储通过各种质量门禁的制品包,预投产制品包变更频率比较慢,一个投产周期只有0-5个,最终使用的只有0-1个,考虑到制品数量较少而且可能会跨周期投产,同时普通制品占用空间较少的情况,我们按时间存储了最近一年内的制品。
投产仓库存储将要进行生产部署的制品包,制品数量较少,基于项目组有恢复生产版本的需求,我们按时间存储了最近一年内的制品。
镜像制品:
镜像制品占用空间非常大,一个普通镜像大小在200M到600M之间,所以我们对制定合理的清理镜像制品策略的需求更加迫切。Artifactory提供的插件可以从两种维度对镜像制品进行清理,一个维度为镜像制品保留时间,另一个维度是镜像数量。
开发仓库存储项目组开发过程中的制品包,开发制品包变更频率非常快,一天一个服务下会上传0-10个,最终投产使用的只有0-1个,因此我们保留时间维度设置为两个周期,同时为了避免镜像制品冗余存储,我们还设置了另一个维度镜像保留数量为10,即一个服务下可以保留10个最新的镜像。
测试仓库存储项目组测试过程中的制品包,测试制品包变更频率比较快,因此我们保留时间维度设置为两个周期,同时为了避免镜像制品冗余存储,我们设置了镜像保留数量为10,即一个服务下可以保留10个最新的镜像。
预投产仓库存储通过各种质量门禁的制品包,预投产制品包变更频率比较慢,考虑到项目组可能会跨周期投产,我们保留时间维度设置为一年,同时为了避免镜像制品冗余存储,设置了镜像保留数量为5,即一个服务下可以保留5个最新的镜像。
投产仓库存储将要进行生产部署的制品包,基于项目组有恢复生产版本的需求,我们保留时间维度设置为一年,同时为了避免镜像制品冗余存储,设置了镜像保留数量为5,即一个服务下可以保留5个最新的镜像。
三、制品清理的技术实现
Artifactory 为我们提供了清理普通制品的插件和镜像制品的插件。
清理普通制品插件artifactCleanup
清理普通制品主要使用了以下两个脚本,artifactCleanup.json和artifactCleanup.groovy。artifactCleanup.json 为配置文件,可以根据自己的需求对配置文件中的参数进行配置;artifactCleanup.groovy 为清理制品逻辑文件,默认逻辑为根据时间进行制品的删除,如果默认逻辑不能完全满足需求,则需要对 artifactCleanup.groovy 内容进行适应性修改。
artifactCleanup.json参数说明:
- months:Deprecated. Instead of timeUnit and timeInterval the month parameter is supported for backwards compatibility reasons. It defined the months to look back before deleting an artifact. Default 1.
- timeUnit: The unit of the time interval. year, month, day, hour or minute are allowed values. Default month.
- timeInterval: The time interval to look back before deleting an artifact. Default 1.
- repos: A list of repositories to clean. This parameter is required.
- dryRun: If this parameter is passed, artifacts will not actually be deleted. Default false.
- paceTimeMS: The number of milliseconds to delay between delete operations. Default 0.
- disablePropertiesSupport: Disable the support of Artifactory Properties (see below Artifactory Properties support section). Default false.
artifactCleanup.json实例:
3.2 清理镜像制品插件 cleanDockerImages
清理普通制品主要使用了以下两个脚本,cleanDockerImages.properties 和 cleanDockerImages.groovy。
cleanDockerImages.properties 为配置文件,可以根据自己的需求对配置文件中的参数进行配置;cleanDockerImages.groovy 为清理镜像制品逻辑文件,默认逻辑为先判断时间参数进行删除,然后再根据制品数量参数进行镜像制品的删除,如果默认逻辑不能完全满足需求,则需要对 cleanDockerImages.groovy 内容进行适应性修改。
cleanDockerImages.properties 参数说明:
- maxDays: The maximum number of days a Docker image can exist in an Artifactory repository. Any images older than this will be deleted.
- maxCount: The maximum number of versions of a particular image which should exist. For example, if there are 10 versions of a Docker image and maxCount is set to 6, the oldest 4 versions of the image will be deleted.
cleanDockerImages.properties 实例:
3.3 删除空文件夹插件deleteEmptyDirs
清理普通制品主要使用了以下两个脚本,deleteEmptyDirs.properties 和 deleteEmptyDirs.groovy。
deleteEmptyDirs.properties 为配置文件,可以根据自己的需求对配置文件中的参数进行配置;deleteEmptyDirs.groovy 为文件夹逻辑文件,如果默认逻辑不能完全满足需求,则需要对 deleteEmptyDirs.groovy 内容进行适应性修改。
deleteEmptyDirs.properties 参数说明:This plugin takes one parameter, called paths, which consists of a comma-separated list of paths to search for empty directories in. Each path is in the form repository-name/path/to/dir.deleteEmptyDirs.properties实例:
四、制品清理的总结和建议
根据之前制定的策略,目前清理脚本每日可以清理600G空间,减轻了制品库存储的一些压力,但是由于 DevOps 是按系统进行推广,每个系统都有各自的特点,早期制定的制品清理策略并不一定适合所有后期纳入的制品,所以制品清理策略应该根据制品库的存储情况和项目组的需求进行调整,而不应该是一成不变的。一次制品清理策略的改变可能会影响所有已经使用制品库的项目组,清理策略修改之前需要与所有项目组进行沟通确定新的清理策略的可行性,一次清理策略的修改必然会占用很多成本,所以首次制定清理策略时应尽量保留少量的镜像制品避免后期大量系统的纳入给制品库的存储带来极大的压力。