目录
2、Library工作模式
3、Library代码结构
二、提前准备工作
1、jenkins添加harbor登录凭证
2、jenkins配置library
3、jenkins独立配置robot流水线
4、jenkins配置gitlab
三、涉及功能点实现
1、library整体环境准备
1、jenkinsfile全局配置
2、异常捕获
3、计时器与循环
4、library解析yaml文件
2、library集成镜像构建及推送
1、jenkinsfile调用片段
2、docker login实现
3、build or push完成推送消息
3、library集成k8s服务部署
四、源码
1、原出处
2、简化版
一、sharedLibrary介绍 1、什么是sharedLibrary
由于公司内部项目众多,大量的项目使用同一套流程做CICD
-
那么势必会存在大量的重复代码
-
一旦某个公共的地方需要做调整,每个项目都需要修改
主要通过使用groovy实现Jenkins的sharedLibrary的开发,以提取项目在CICD实践过程中的公共逻辑,提供一系列的流程的接口供公司内各项目调用。
开发完成后,对项目进行Jenkinsfile的改造,最后仅需通过简单的Jenkinsfile的配置,即可优雅的完成CICD流程的整个过程,此方式已在大型企业内部落地应用。
2、Library工作模式由于流水线被组织中越来越多的项目所采用,常见的模式很可能会出现。 在多个项目之间共享流水线有助于减少冗余并保持代码 "DRY"。
流水线支持引用 "共享库" ,可以在外部源代码控制仓库中定义并加载到现有的流水线中。
@Library('my-shared-library') _
在实际运行过程中,会把library中定义的groovy功能添加到构建目录中:
3、Library代码结构/var/jenkins_home/jobs/test-maven-build/branches/feature-CDN-2904.cm507o/builds/2/libs/my-shared-library/vars/devops.groovy
共享库的目录结构如下:
(root) +- src # Groovy source files | +- org | +- foo | +- Bar.groovy # for org.foo.Bar class +- vars | +- foo.groovy # for global 'foo' variable | +- foo.txt # help for 'foo' variable
src 目录应该看起来像标准的 Java 源目录结构。当执行流水线时,该目录被添加到类路径下。
vars 目录定义可从流水线访问的全局变量的脚本。 每个 *.groovy 文件的基名应该是一个 Groovy (~ Java) 标识符, 通常是 camelCased。
二、提前准备工作 1、jenkins添加harbor登录凭证无论是传统流水线还是library构建,登陆或者钉钉token等私密数据都建议采用全局凭证方式调用,类似k8s中的secret资源对象。
2、jenkins配置library[系统管理] -> [系统设置] -> [ **Global Pipeline Libraries** ],配置jenkins调用library,library可以看作是gitlab上面的一套独立代码类。
3、jenkins独立配置robot流水线robot集成测试一般用于测试流水线,不适合放在项目中,我们将测试用户单独创建一个流水线,library直接调用即可
4、jenkins配置gitlab 三、涉及功能点实现 1、library整体环境准备 1、jenkinsfile全局配置@Library('rui-devops') _ #jenkins调用library pipeline { agent { label 'jnlp-slave'} #k8s动态生成jenkins-slave options { timeout(time: 20, unit: 'MINUTES') #循环检测超时 gitLabConnection('gitlab') #调用gitlab } environment { IMAGE_REPO = "192.168.0.121:5000/myblog/myblog" #镜像地址 IMAGE_CREDENTIAL = "credential-registry" #用户密码模式全局变量,harbor登录 DINGTALK_CREDS = credentials('dingTalk') #token模式全局变量,钉钉通知token PROJECT = "myblog" }2、异常捕获
def exceptionDemo(){ try { def val = 10 / 0 println(val) }catch(Exception e) { println(e.toString()) throw e } } exceptionDemo()3、计时器与循环
主要用于集群更新容器版本后,循环检测pog启动状态是否为running
import groovy.time.TimeCategory use( TimeCategory ) { def endTime = TimeCategory.plus(new Date(), TimeCategory.getSeconds(15)) def counter = 0 while(true) { println(counter++) sleep(1000) if (new Date() >= endTime) { println("done") break } } }4、library解析yaml文件
library代码中需要获取容器yaml文件中的变量,例如获取namespace、label、副本数等,可以导入三方类org.yaml.snakeyaml.Yaml实现
import org.yaml.snakeyaml.Yaml def readYaml(){ def content = new File('myblog.yaml').text Yaml parser = new Yaml() def data = parser.load(content) def kind = data["kind"] def name = data["metadata"]["name"] println(kind) println(name) } readYaml()2、library集成镜像构建及推送 1、jenkinsfile调用片段
stage('docker-image') { steps { container('tools') { script{ devops.docker( "${IMAGE_REPO}", "${GIT_COMMIT}", IMAGE_CREDENTIAL ).build().push() } } }2、docker login实现
//groovy获取jenkins全局凭证ID,并将对应的账号密码赋值给自定义变量 withCredentials([usernamePassword(credentialsId: this.credentialsId, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) sh "docker login ${regs} -u $USERNAME -p $PASSWORD"3、build or push完成推送消息
sh "docker push ${this.fullAddress}" //把当前推送的镜像地址记录在环境变量中 env.CURRENT_IMAGE = this.fullAddress isSuccess = true // check if build success def stage = env.STAGE_NAME + '-push' if(isSuccess){ updateGitlabCommitStatus(name: "${stage}", state: 'success') this.msg.updateBuildMessage(env.BUILD_TASKS, "${stage} OK... √")3、library集成k8s服务部署
检查myblog应用的pod是否部署正常,人工检查的大致步骤:
kubectl -n luffy get pod,查看pod列表
找到列表中带有myblog关键字的running的pod
查看上述running pod数,是否和myblog的deployment中定义的replicas副本数一致
若一致,则检查结束,若不一致,可能稍等几秒钟,再次执行相同的检查 *** 作
如果5分钟了还没有检查通过,则大概率是pod有问题,通过查看日志进一步排查
如何通过library代码实现上述过程:
-
library如何获取myblog的pod列表?
-
首先要知道本次部署的是哪个workload,因此需要调用者传递workload的yaml文件路径
-
library解析workload.yaml文件,找到如下值:
-
pod所在的namespace
-
pod中使用的labels标签
-
-
使用如下命令查找该workload关联的pod
$ kubectl -n
get po -l -l # 如查找myblog的pod $ kubectl -n luffy get po -l app=myblog
-
-
如何确定步骤1中的pod的状态?
# 或者可以直接进行提取状态 $ kubectl -n luffy get po -l app=myblog -ojsonpath='{.items[0].status.phase}' # 以json数组的形式存储 $ kubectl -n luffy get po -l app=myblog -o json
-
如何检测所有的副本数都是正常的?
# 以json数组的形式存储 $ kubectl -n luffy get po -l app=myblog -o json # 遍历数组,检测每一个pod查看是否均正常(terminating和evicted除外)
-
如何实现在5分钟的时间内,若pod状态符合预期,则退出检测循环,若不符合预期则继续检测
use( TimeCategory ) { def endTime = TimeCategory.plus(new Date(), TimeCategory.getMinutes(timeoutMinutes,5)) while (true) { if (new Date() >= endTime) { //超时了,则宣告pod状态不对 updateGitlabCommitStatus(name: 'deploy', state: 'failed') throw new Exception("deployment timed out...") } //循环检测当前deployment下的pod的状态 try { if (this.isDeploymentReady()) { readyCount++ if(readyCount > 5){ updateGitlabCommitStatus(name: 'deploy', state: 'success') break; } }else { readyCount = 0 }catch (Exception exc){ echo exc.toString() } //每次检测若不满足所有pod均正常,则sleep 5秒钟后继续检测 sleep(5) } }
原作者源码,有能力者可以直接git clone学习
YongxinLi/jenkins-shared-library
2、简化版自己练习时简化的代码,基本功能实现,主要去除了多项目逻辑判断,sonarqube代码扫描、通知方式判断等,添加了一些注释。
配套源码:
CSDNhttps://mp.csdn.net/mp_download/manage/download/UpDetailed
配套镜像:
docker pull registry.cn-hangzhou.aliyuncs.com/devlop01/myblog:v1 docker pull registry.cn-hangzhou.aliyuncs.com/devlop01/mysql:v1 docker pull registry.cn-hangzhou.aliyuncs.com/devlop01/tools:v1
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)