流水线缓存

云效流水线提供了构建缓存的能力帮助提升构建的速度。本文主要介绍流水线缓存相关原理和使用场景。

1. 缓存原理概述

云效流水线构建缓存分为两种类型:

  • 文件缓存:比如构建过程中下载到/root/.m2的jar包。

  • 镜像构建缓存:可以缓存镜像构建过程中的中间层,以提升下次镜像构建的速度。

文件缓存默认会存储在云端,并每次构建时从云端下载缓存文件并恢复到构建环境中,构建环境和云端存储通过内网进行数据传输,速度很快。

当使用私有构建集群时,可以选择让任务运行在VM上,或者运行在容器里(仅支持linux/amd64的机器)。

image

如上图所示,如果选择了默认环境,则云效会在构建机上启动容器,在容器中执行任务。如果选择了默认VM环境,则缓存设置不生效,构建过程中产生的文件会直接持久化的存储在构建机上。

如果你选择让任务运行在容器里,则流水线仍然会将构建缓存存储到云端。由于构建主机和云端缓存之间只能通过公网连接,缓存的上传和下载速度会变慢。如果主机的出网带宽比较小的话,问题会更加突出。针对这种情况,云效支持使用本地缓存,即把文件缓存存储在构建机器的特定目中,并在下次执行任务时,重新挂载这个目录。

以上提到的文件缓存都是任务级别的,也就是说同一个流水线的同一个位置的任务的不同历史执行,会共享这份缓存。如果你希望在使用私有构建机时,让多个流水线的任务都使用相同的一份缓存,则可以用私有构建集群本地挂载配置来把宿主机的一个目录同时挂载到多个流水线中定义的任务的执行环境中。

2. 文件缓存

2.1 任务级别的云端缓存

在流水线编辑的页面中,点击 变量与缓存 进入到缓存的设置页面。image.png

流水线默认开启了常用技术栈的目录缓存,比如maven构建所使用的/root/.m2。流水线在运行时会把指定的这些目录统一打成一个tgz文件,上传到云效流水线托管的 OSS 上,并在下一次构建时下载,解压到同样的目录。该配置对该流水线的所有任务生效。

image.png

image.png

  • 可以通过每个缓存目录配置后边的操作按钮删除不需要的目录,或者临时关闭某个目录。某个目录被关闭或者删除后,后续的构建将不会再打包上传改目录的文件。

  • 添加缓存目录:可以增加更多的目录的文件缓存。

  • 清理缓存:可以清除当前流水线所关联的所有云端缓存,下次任务构建时,将没有缓存文件被下载和解压,但运行结束之后仍然会将指定目录的文件打包上传。

2.2 任务级别的本地缓存

当使用私有构建机器,选择在容器中执行任务,并选择了使用本地缓存时,文件缓存会保留在构建机上。配置方式与云端缓存类似,唯一的差异是需要选中本地缓存,如下图所示。

image.png

想要知道某个任务的本地缓所在的目录,需要从构建环境分配日志(需要runner版本在v0.1.1及以上版本)中获取以下信息:

image.png

对于 Linux 主机或者 macOS 主机,本次任务构建的缓存可以在这台构建机器的以下目录中查看:

${Workspace}/__flow_work/__flow_builds/${ParentID}/cache

对于 Windows 主机,本次任务构建的缓存可以在这台构建机器的以下目录中查看:

%Workspace%\w\b\%ParentId的前8位%\cache

注意:如果流水线配置了本地缓存,但任务配置的是公共构建集群,则这个配置不生效,仍然会使用云端缓存。

2.3 文件缓存的生效范围

流水线可以包含多个任务定义,不同流水线的不同任务的缓存是隔离的,只能在这个任务的不同的执行实例中共享。如下图所示,这条流水线的 任务1 在这三次运行中都会按照缓存配置来保存文件缓存,并在下次运行到这个任务时候恢复缓存。而 任务2 任务3 各自有不同缓存。

image

2.4 云端文件缓存的限制

云端缓存存在大小的限制,缓存压缩成为tgz包之后的总大小如果超过2G,则不会被上传。

2.5 云端文件缓存的清理

除了可以手动在流水线配置页面主动清除该流水线相关的缓存外,超过3个月未更新的缓存也会被自动清理。

2.6 本地文件缓存的清理

当私有构建集群配置本地缓存时,运行一段时间后,会在构建机上产生较多的日志和文件缓存等,占用越来越多的磁盘空间。云效提供缓存清理工具,针对私有构建机的以下内容进行清理:

  • 针对容器化构建方式,清理已停止容器

  • 清理悬空无tag镜像

  • 清理自定义环境构建产生的中间镜像

  • 3天前的构建任务运行日志

  • 3天前的构建任务步骤日志

  • 15天未更新的构建任务缓存目录

清理工具执行命令如下:

docker run -v /var/run/docker.sock:/var/run/docker.sock -v /root/yunxiao:/root/yunxiao registry.cn-beijing.aliyuncs.com/build-steps/cache-cleaner:0.0.3-20230914183240

如果需要定期进行缓存,建议将以上命令配置到cronjob中。

2.7 私有构建集群本地挂载配置

除了针对每个任务隔离的缓存能力外,云效流水线还支持将构建机上的某个目录挂载到多个流水线的任务中。比如当你使用容器化构建的方式进行Java构建时,希望所有构建任务都共享宿主机上/root/.m2/目录,从而可以共享这份缓存,避免每个任务的重复下载。为了达到这个效果,需要进行如下配置:

image.png

则该流水线下的运行在私有构建机上的容器化构建任务都会将宿主机的/root/.m2目录挂载到容器的/root/.m2中。

注意:任务级别的缓存和本地挂载缓存可以同时配置,该流水线中的每个任务根据自己的构建集群的配置,来自动选择对应的缓存方式。

  • 如果任务使用的是私有构建集群,虽然在任务级别的配置中也有/root/.m2的条目,但由于 私有构建集群本地挂载配置 也配置了相同的目录,所以实际生效的是下面的 私有构建集群本地挂载 。且其余的目录的仍然会以任务级别的本地缓存的方式缓存到本地目录。

  • 如果任务使用的是公共构建集群,则会忽略 私有构建集群缓存配置 私有构建集群本地挂载配置,仍然使用任务级别的云端缓存。

3. 镜像构建缓存

3.1 镜像构建任务缓存

云效流水线镜像构建任务提供了构建缓存能力:

  • 当使用公共构建集群时:云效流水线会在构建环境中临时拉起一个 buildkitd 的 sidecar 容器,然后在镜像构建的容器中通过 http 连接到这个 buildkitd,使用 buildkit 进行镜像构建。当构建结束时,buildkitd 的 sidecar 容器会将整个 buildkit 的上下文打包上传到云端,并在下次构建时在 buildkitd 的 sidecar 容器中下载该缓存文件,恢复 buildkitd 的上下文,从而达到提供镜像缓存的能力。

    • 同样,镜像构建缓存的生效范围也是任务级的,不同的流水线的或者同一个流水线的不同任务的缓存都是互相隔离的。

  • 当使用私有构建集群时:镜像构建的任务会直接挂载宿主机上的 dockerd 来进行镜像构建,这时的镜像构建缓存则存在于构建机本地。

镜像构建默认会开启缓存能力,如果不需要,则可以勾选 不使用缓存 关闭任务的缓存功能,下次构建时就不会从云端拉取缓存来恢复上下文。

image

3.2 镜像构建缓存的限制

镜像构建任务的缓存如果超过 5G,则不会上传。