devops学习(十) Jenkins 流水线
在之前的环境中我们实现了基本的持续集成和持续部署(CI/CD) 但整个实现的过程是非常繁琐的,经常容易忘记怎么操作,而且当报错的时候排查很艰难 在jenkins中提供了一套流水线作业pipeline 来简化这些流程
一、认识pipeline流水线
1、新建项目
项目名称: pipeline项目风格: 流水线
2、体验流水线简单案例
我们在流水线项目中点击右侧的hello World会自动生成流水线代码片段
当我们手动构建后可以在屏幕中间的任务列表中看到我们项目构建所消耗的时间、是否成功、日志信息等
二、pipeline 流水线语法结构
我们上面生成的hello world的语句片段我们拿过来用一下
1、语法说明
pipeline { // 所有的脚本信息都是放在pipeline中的agent any //构建时任务交给具体那个jenkins节点,(集群模式下可选node)environment { //演示代码里没有,这里加一下key = 'value' //全局变量配置,自定义}stages { //任务组,所有要跑的任务都放在这个组下stage('Hello') { //第一个任务,任务构建的顺序是从上到下的,可以定义任务名称steps { //第一个任务的具体操作echo 'Hello World' //具体的shell命令}}}
}
也就是说,我们要添加一个子任务就需要在stages下添加一组stage的配置
2、添加多组配置
我们在这里先将大致框架定出来,设置每一步大概要做什么,具体内容先用输出代替
pipeline {agent any environment {key = 'value'}stages {stage('1、 拉取gitlab上的代码到jenkins主机 ') {steps() {echo '拉取git仓库代码 - SUCCESS'}}stage('2、通过jenkins本机的maven+jdk来实现编译打包') {steps() {echo '通过maven构建项目 - SUCCESS'}}stage('3、通过SonarQube做代码质量检测') {steps() {echo '通过SonarQube做代码质量检测 - SUCCESS'}}stage('4、通过jenkins主机构建docker镜像') {steps() {echo '通过jenkins主机构建docker镜像 - SUCCESS'}}stage('5、发送Chart包到K8master主机') {steps() {echo '发送Chart包到K8master主机 - SUCCESS'}}stage('6、通过Publish Over SSH通知master 部署/更新helm - SUCCESS') {steps() {echo '通过Publish Over SSH通知master 部署/更新helm - SUCCESS'}}}
}
把上面的流水线配置贴到 pipeline中测试一下,我们能看到就有了很多任务
三、基于前面的项目完善流水线配置
1、通过流水线拉取gitlab项目
这里我们没有像之前那种图形化配置,不过pipeline提供了生成流水线的配置
//点击流水线案例,找到如下配置
checkout Check out from version control //git地址
http://101.43.4.210:30001/root/mytest.git
生成的语句
checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[url: 'http://101.43.4.210:30001/root/mytest.git']]])
添加到我们的语法中
pipeline {agent any environment {key = 'value'}stages {stage('1、 拉取gitlab上的代码到jenkins主机 ') {steps() {echo '拉取git仓库代码 - SUCCESS'checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[url: 'http://101.43.4.210:30001/root/mytest.git']]])}}stage('2、通过jenkins本机的maven+jdk来实现编译打包') {steps() {echo '通过maven构建项目 - SUCCESS'}}stage('3、通过SonarQube做代码质量检测') {steps() {echo '通过SonarQube做代码质量检测 - SUCCESS'}}stage('4、通过jenkins主机构建docker镜像') {steps() {echo '通过jenkins主机构建docker镜像 - SUCCESS'}}stage('5、发送Chart包到K8master主机') {steps() {echo '发送Chart包到K8master主机 - SUCCESS'}}stage('6、通过Publish Over SSH通知master 部署/更新helm - SUCCESS') {steps() {echo '通过Publish Over SSH通知master 部署/更新helm - SUCCESS'}}}
}
测试构建
//这里我们新建的流水线项目pipeline的目录位置,构建完就可以看到拉取的代码了
cd /apps/devops_setup/data/jenkins/data/workspace/pipeline/
2.1、流水线配置导入jenkinsfile
我们每次都去项目中配置修改很麻烦,流水线提供了一种文件形式的定义方式
我们在gitlab代码中定义一个jenkinsfile的文件,在构建的时候他会去拉取这个文件运行,打开idea
2.2 项目配置拉取jenkinsfile位置
我这里当时搞的时候整错了,idea添加时写的jenkinsfile首字母是小写,这里在配置拉取jenkinsfile的时候最下面的关键字也要改成小写
如上,可知这个jenkinsfile文件名称不固定,根据自己的使用定义
构建完的操作和之前在项目中定义的是完全一样的
3、根据tag构建指定版本
在我们的pipeline项目中定义一个全局字符tag ,让我们项目可以通过tag去构建,下图中我们设置的默认值意思是,当我们不选择构建的tag版本时直接点构建会去拉取master分支的代码
我们在上面构建默认是走的master分支,但这使得我们发布特定版本的时候很不方便
这里我们稍作修改,将master分支改成我们在构建时gitlab传过来的分支信息
steps() {echo '拉取git仓库代码 - SUCCESS'checkout([$class: 'GitSCM', branches: [[name: '$tag']], extensions: [], userRemoteConfigs: [[url: 'http://101.43.4.210:30001/root/mytest.git']]])
}//这里将*/master 修改为$tag 表示以gitlab传过来的标签作为分支切换
注意,使用jenkinsfile内部调用全局变量是${xxx},而在jenkins项目中调用jenkinsfile的变量是$xxx
此时jenkinsfile是去拿master分支的配置,克隆的应该是V4版本
构建测试
根据上图显示我们也可以指定不同的版本来跑构建了,接下来继续完善这个流程
4、添加maven编译打包
直接在流水线语法那里指定为shell语法后,将编译的语法转换为流水线语法即可
//脚本语法
sh: shell script //编译的命令,绝对路径
/var/jenkins_home/maven/bin/mvn clean package -DskipTests
返回流水线语法
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
这里加一段就全量跑一下太麻烦了,我们把剩下的几段都找出来再添加
5、添加代码质量扫描
这个和上面的操作方法一致,这里就不放图了
//脚本语法
sh: shell script //代码质检命令
/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsoanr.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target -Dsonar.login=squ_3005d10215abc1ac559457cc90ba804c6c477c0c//这里是直接shell跑的需要带上token值,最后一段那个
//如果不记得你自己的token了,去sonarQube上 (我的账户--安全--生成token-用户令牌)获取
返回
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsoanr.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target -Dsonar.login=squ_3005d10215abc1ac559457cc90ba804c6c477c0c'
6、jenkins容器构建镜像
我们在设置镜像的时候,不希望写死镜像仓库地址,根据测试或功能环境不同需要重新指定仓库,这里做全局变量
通过jenkinsfile添加
//添加全局变量
environment { harborUser = 'admin'harborPasswd = 'Harbor12345'harborAddress = '101.43.4.210:30007'harborRepo = 'repo'}
指定镜像构建和上传到镜像仓库的部分
通过流水线语法添加
//脚本语法
sh: shell script //镜像上传命令
mv ./target/*.jar docker/
docker build -t "${JOB_NAME}:${tag}" ./docker/
docker login ${harborAddress} -u${harborUser} -p${harborPasswd}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
返回值
sh '''mv ./target/*.jar docker/
docker build -t "${JOB_NAME}:${tag}" ./docker/
docker login ${harborAddress} -u${harborUser} -p${harborPasswd}
docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''
7、通知K8S--Heml部署
//生成方法
sshPublisher: Send build artifacts over SSH//要拷贝的源文件
helm/mytest/* helm/mytest/templates/* //要执行的命令
helm upgrade -i ${JOB_NAME} --set containers.image=$harborAddress/$harborRepo/${JOB_NAME}:${tag} --set name=${JOB_NAME} /usr/local/test/helm/mytest/
返回
sshPublisher(publishers: [sshPublisherDesc(configName: 'test', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'helm upgrade -i ${JOB_NAME} --set containers.image=$harborAddress/$harborRepo/${JOB_NAME}:${tag} /usr/local/test/helm/mytest/', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'helm/mytest/* helm/mytest/templates/* ')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
这里要注意一个问题
execCommand: 'helm upgrade -i ${JOB_NAME} --set containers.image=$harborAddress/$harborRepo/${JOB_NAME}:${tag} /usr/local/test/helm/mytest/'//命令中execCommand: 后面的命令是 单引号 ''
//这样会使得我们的$harborAddress/$harborRepo 这两个变量不生效
//但是这个变量是取自jenkinsfile的我们无法通过${}的方式获取
//所以这里的单引号要改成双引号
修改后的代码如下
sshPublisher(publishers: [sshPublisherDesc(configName: 'test', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "helm upgrade -i ${JOB_NAME} --set containers.image=$harborAddress/$harborRepo/${JOB_NAME}:${tag} /usr/local/test/helm/mytest/", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'helm/mytest/* helm/mytest/templates/* ')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
这样一来我们就把之前的项目中所有步骤的流水线代码都拿到了,下面开始整理一下
8、流水线脚本全量整理(jenkinsfile)
pipeline {agent anyenvironment {harborUser = 'admin'harborPasswd = 'Harbor12345'harborAddress = '101.43.4.210:30007'harborRepo = 'repo'}stages {stage('1、 拉取gitlab上的代码到jenkins主机 ') {steps() {echo '拉取git仓库代码 - SUCCESS'checkout([$class: 'GitSCM', branches: [[name: '$tag']], extensions: [], userRemoteConfigs: [[url: 'http://101.43.4.210:30001/root/mytest.git']]])}}stage('2、通过jenkins本机的maven+jdk来实现编译打包') {steps() {echo '通过maven构建项目 - SUCCESS'sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'}}stage('3、通过SonarQube做代码质量检测') {steps() {echo '通过SonarQube做代码质量检测 - SUCCESS'sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsoanr.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target -Dsonar.login=squ_3005d10215abc1ac559457cc90ba804c6c477c0c' }}stage('4、通过jenkins主机构建docker镜像') {steps() {echo '通过jenkins主机构建docker镜像 - SUCCESS'sh '''mv ./target/*.jar docker/docker build -t "${JOB_NAME}:${tag}" ./docker/docker login ${harborAddress} -u${harborUser} -p${harborPasswd}docker tag ${JOB_NAME}:${tag} ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${tag}'''}}stage('5、发送Chart包到K8master主机 通过helm部署, 这里多写了个第6步已经删了') {steps() {echo '发送Chart包到K8master主机 - SUCCESS'sshPublisher(publishers: [sshPublisherDesc(configName: 'test', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "helm upgrade -i ${JOB_NAME} --set containers.image=$harborAddress/$harborRepo/${JOB_NAME}:${tag} --set name=${JOB_NAME} /usr/local/test/helm/mytest/", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'helm/mytest/* helm/mytest/templates/* ')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])}}}
}
9、更新代码指定新版本
这里我们修改一下idea上代码输出的信息为5.0.0版本,然后上传到gitlab上,打一个tag为V5.0.0的版本
修改输出代码并上传
gitlab添加V5.0.0版本标签
10、构建前准备
这里因为我们之前已经部署了mytest的服务,这里先清理一下,因为job名称不同,他不会替换掉,但是因为30008端口已经被占用,这里会冲突(或者在helm的地方更新下nodePort端口)
helm delete mytest
11、多版本快速滚动部署
通过以上步骤实现了通过流水线去完成我们ci/cd的持续集成和部署,现在我们可以选择版本去发布了(≧∇≦)ノ
devops学习(十) Jenkins 流水线相关推荐
- 【云原生】DevOps(六):Jenkins流水线
本文目录: 一.Jenkins流水线任务介绍 二. Jenkins流水线任务 1. 构建Jenkins流水线任务 2. Groovy脚本 3.Jenkinsfile实现 三.Jenkins流水线任务实 ...
- 38.DevOps之基于Jenkins实现的CI与CD
文章目录 一 DevOps 简介 1.1 什么是 DevOps 1.2 为什么要推广 DevOps? 1.3 传统技术团队 1.4 DevOps 技术团队 1.5 什么是持续集成(CI-Continu ...
- jenkins流水线(jenkinsfile)详解,保姆式教程
jenkins流水线(jenkinsfile)详解 在学习本篇文章的时候,可以去看看jenkins官网的文档,jenkins官网支持中文,观看十分便捷 此教程使用的是gitee+docker+jenk ...
- Jenkins 流水线 获取git 分支列表_使用Jenkins Git参数实现分支标签动态选择
1.1 为什么要使用GIT参数? 我们为什么要使用 git参数呢? 每个项目代码库都会有不同的分支,(如果你没有用多分支流水线的情况下)对于普通的流水线项目我们可以 让一条流水线来支持多个分支的发布, ...
- jenkins pipeline_DevOps编程操练:用Jenkins流水线建立代码质量预警机制
解决痛点 代码上线故障多 不知如何用docker搭建Jenkins操练环境 不知如何开始为Java代码编写自动化单元测试 不知如何将单元测试运行在Jenkins流水线上 不知如何将繁琐的手工Jenki ...
- DevOps学习总结
DevOps学习总结 2017-4-28 DevOps(英文Development和Operations的组合)是一组过程.方法与系统的统称,用于促进开发(应用程序/软件工程).技术运营和质量保障( ...
- 2017年深度学习十大趋势预测
2017年深度学习十大趋势预测 本文作者曾经多次预测了技术发展的趋势,最近的一次预测是"2011年软件发展的趋势与预测".10项预言中,准确地命中了6项,比如JavaScript ...
- 强化学习(十九) AlphaGo Zero强化学习原理
在强化学习(十八) 基于模拟的搜索与蒙特卡罗树搜索(MCTS)中,我们讨论了MCTS的原理和在棋类中的基本应用.这里我们在前一节MCTS的基础上,讨论下DeepMind的AlphaGo Zero强化学 ...
- 强化学习(十六) 深度确定性策略梯度(DDPG)
在强化学习(十五) A3C中,我们讨论了使用多线程的方法来解决Actor-Critic难收敛的问题,今天我们不使用多线程,而是使用和DDQN类似的方法:即经验回放和双网络的方法来改进Actor-Cri ...
最新文章
- Opengl-基本概念-对象(很关键啊兄弟这章)
- C#设计模式之:抽象工厂模式与反射
- 常用设计模式之抽象工厂模式
- 第13届年度Webby奖采用Silverlight / 13th Annual Webby Awards powered by Silverlight
- 论文浅尝 | 基于正交普鲁克分析的高效知识图嵌入学习
- 一个带关闭按钮的Div窗口,很漂亮
- 前端笔记-thymeleaf获取及回显input标签type=date
- Java多线程学习十六:读写锁 ReadWriteLock 获取锁有哪些规则
- python获取当前线程_Python爬虫(线程,进程)
- 《常微分方程教程》习题2.3.6
- DataRowView 笔记
- OFFICE技术讲座:设置调整字间距(kern)后,标点就不压缩
- SMART PLC PID仿真 (SMART PID仿真库使用说明)
- [鸿篇巨制]蚂蚁金融级分布式架构SOFAStack编年史
- 计算机和网络之间有个感叹号,网络有个感叹号!电脑无线网络连接不上的几种常见问题...
- QString汉字个数检测
- 贯入用计算机怎样换算,标准贯入试验的应用及其杆径换算的研究.doc
- java中UPD的一个简单的例子
- 服务器 ftp查询文件是否存在,ftp查看远程服务器文件是否存在
- 停止线程 暂停线程