在 CICD 的流程中,需要保存的产物主要有两类,构建产物和缓存。构建产物是最终的执行结果,缓存是为了优化下一次的构建速度。本篇主要描述的是在 Jenkins 中如何对构建产物和缓存进行归档,并结合对象存储进行实践。有部分示例使用的是 在 Kubernetes 上动态创建 Jenkins Slave 进行构建,配置过程可以参考超链接文档。
1. 部署 Minio 及 S3cmd 使用
1.1 部署 Minio
这里使用 docker-compose 编排 Minio 进行部署。
- 安装 Docker-compose
|
|
- 部署 Minio
|
|
- 查看 Minio 页面
选择 9001-9004 任意端口,可以看到 Minio 的页面,使用 minioadmin:minioadmin 账户登陆。
1.2 安装使用 S3cmd
- 安装
|
|
- 配置
编辑 ~/.s3cfg
文件,增加如下内容:
host_base = 1.1.1.1:9001
host_bucket = 1.1.1.1:9001
use_https = False
access_key = minioadmin
secret_key = minioadmin
signature_v2 = False
这里仅用于测试,host_bucket
直接指向部署的服务器。在生产环境中, Bucket 有两种风格:DNS-style 和 Path-style ,可以支持超大规模的分布式存储。
- 日常操作
列出全部 Bucket
|
|
创建 Bucket
|
|
上传文件
|
|
上传文件夹
|
|
列出 Bucket 中的数据
|
|
下载 Bucket 中的文件
|
|
删除 Bucket 中的文件
|
|
删除 Bucket
|
|
2. Jenkins 构建归档
2.1 本地归档
新建流水线,内容如下:
pipeline {
agent {
kubernetes {
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.6.3-jdk-8-openj9
command:
- cat
tty: true
"""
}}
stages {
stage('Hello') {
steps {
container('maven') {
sh "echo `date` >> newfile.txt"
}
}
}
}
post {
success {
archiveArtifacts 'newfile.txt'
}
}
}
查看构建日志,可以看到构建产物成功归档。
在当次构建的 UI 中,也可以直接查看到归档文件。
在服务器上,可以查找到归档文件, /var/jenkins_home/jobs/test/builds/43/archive/newfile.txt
。这里 Jenkins 直接将归档的文件保存在 /var/jenkins_home/jobs
文件夹中。
2.2 对象存储归档
在 Jenkins 中大部分对象存储插件面向的是 AWS ,而不是 S3 协议。当然,也有云厂商,如 Qiniu ,提供了 Jenkins 存储插件。这里主要使用的是一款开源的对象存储组件 - Minio 。
- 在插件市场搜索并安装插件 minio
- 在 Jenkins 配置中,设置 Minio 相关的配置
- 新建一条自由风格的流水线
编辑需要执行的 Step ,然后设置构建后需要归档的文件
- 在构建日志中,可以看到已经归档成功
与 Jenkins 本地归档不同的是,此时的归档在当次构建页面上,不会展示。
- 在 Minio 中,查看构建归档的结果
3. 缓存
Jenkins 中的缓存主要有两种实践方式,全部流水线共用缓存,每条流水线单独缓存。
由于采用的是 Kubernetes 动态提供的 Agent ,可以将主机上的 Docker Volume 挂载到 Pod ,提供 Node 级别的缓存,这样全部 Pod 就会共用一个缓存目录。这样处理比较简单,但同时共用一个依赖库文件夹会带来潜在的并发问题。下图是相关的配置:
另外一种方式是每条流水线一个缓存,这样够精细,但也增加了存储和执行时间的开销。下面主要介绍如何使用 jobcacher 进行缓存。
- 搜索并安装插件 jobcacher
- 查看 jobcacher 插件配置
在 Jenkins 配置中,可以看到 jobcacher 默认使用的是内置的存储,也就是 /var/jenkins_home
下的文件存储。
如下图,下拉框中,还有另外一个 AWS 的 S3 存储可选。这里仅查看,不做设置和测试。
- 新建流水线
新建流水线,内容如下:
pipeline {
agent {
kubernetes {
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: nodejs
image: node:10-alpine
command:
- cat
tty: true
"""
}}
stages {
stage('checkout') {
steps {
git branch: 'master', url: "https://github.com/vuejs/vue"
}
}
stage('install') {
steps {
container('nodejs') {
cache(caches: [[$class: 'ArbitraryFileCache', excludes: '', includes: '**/*', path: 'node_modules']], maxCacheSize: 512) {
sh "npm install"
}
}
}
}
}
}
- 首次构建
可以看到 Jenkins 将设置的目录进行了缓存。在 Jenkins 目录 /var/jenkins_home/jobs/test/cache/3ec03583f8eaec275cb2183db769ff47
中,可以看到相关文件。
|
|
- 带缓存构建
缓存归档之后,再次构建时,下载依赖包的耗时会明显减少。从 31 秒 减少到 7 秒,但增加了拉取缓存、解压等操作的时间。
- 使用对象存储进行缓存
由于大部分插件支持的是 AWS ,如果能直接使用 AWS 也是一个不错的选择。使用其他存储,需要厂商插件的支持,或者 fork AWS 的 Jenkins 插件进行二次开发。
另外一个方向是,提供 s3cmd 命令行,通过 credential 注入秘钥,使用命令行进行上传和下载的管理。下面是简单的流程:
|
|