赞
踩
最近不知道写点什么,想着补充一下自己的以前的文档,有时间就补充一下jenkins,nginx。。。
以前个人总结的jenkins文档:https://blog.csdn.net/gx_1_11_real/category_9186060.html
Jenkins官方文档:
https://www.jenkins.io/zh/doc/book/pipeline/
下面介绍一下Jenkins Pipeline的基本用法
由于内容较多,为了讲解编辑了大量的补充性的内容,建议首次看的可以不看补充内容
Pipeline是Jenkins 2.x的核心的特性,帮助Jenkins实现从CI到CD与DevOps的转变。其中文翻译为管道,也可以叫做流水线
它是一套运行于Jenkins上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程编排与可视化
简单的来说就是将一套上线或者发布变得流程化和可视化
和传统的扔代码到线上以及使用jenkins简单的调用脚本的上线方式的区别:
更加的流程化和安全。可以清楚的显示在哪个流程中有问题,并自动停止执行。如果是之前文档演示的几种方式,如果出问题了,需要翻整篇的日志,去查询哪个地方有问题。并且最后页面上的显示,只有2种结果,要么最后成功要么最后失败,比较浪费时间
更加的直观显示流程的状态,可视化的界面更加的令人舒适
将一个上线的过程进行分解和流程化,分成多个环节。例如:清理空间,拉取代码,发布到环境,备份,重启服务,验证,通知等环节,然后我们需要将这些步骤套用pipeline的语法
按照以前的方式也许一个脚本里就蕴含了这些流程,但是这实际上并不算是配合jenkins实现了流程化,仅仅只算是使用jenkins进行了简单的发布。虽然完成了发布,但是看起来并不”高级“和舒适
直白的说,使用这个的目的不仅是为了方便自己和规范流程,对于部分领导并不喜欢你看上去很闲,简单的认为越复杂越专业。配置时越复杂越看不懂,图形界面越好看才是”他的需求“,效率并不会让他舒服,只会认为你工作不饱和,
实际上Pipeline的语法较多,有很大部分并不一定能用到
因此这里只演示几种常见的配置和创建方式,更多的需要研究官方文档
Stage 阶段,一个Pipeline可以划分为若干个Stage,每个Stage代表一组操作
你可以把你在此阶段后要配置的过程进行一个总结,将这个阶段叫做 构建 测试 发布 或者其他
Stage是一个逻辑分组的概念,可以跨多个Node
Node 节点,一个Node就是一个Jenkins节点,或者是Master,或者是slave,是执行Step的具体运行期环境
Step 步骤,Step是最基本的操作单元,小到创建一个目录,大到构建一个Docker镜像,由各类Jenkins Plugin提供
Pipeline支持两种语法:声明式语法(Declarative Pipeline) 和脚本化语法(Scripted Pipeline)
两者都能够使用pipeline内置的插件或者插件提供的steps,两者都可以利用共享库扩展
从官网上来说,声明式流水线相比脚本化的流水线语法,它提供更丰富的语法特性,是为了使编写和读取流水线代码更容易而设计的。其语法更严格,有固定的组织结构,更容易生成代码段,可以Blue Ocean插件进行简单的编排(实际上部分工作者还是喜欢类似于脚本化语法的方法,在声明式流水线中去调用脚本)
但是对于一些使用较老版本jenkins的用户,更习惯使用脚本化的语法。实际上脚本化的语法要更加灵活方便,用户可以根据自己的业务进行灵活的实现和扩展实现其他需求,例如 配合编写的python或其他脚本,完成一些复杂的任务
声明式语法由于语法严格,有固定的,严格的格式 声明式由块,章节,指令,步骤,节点组成;必须包含在固定格式pipeline{}块内;每个声明必须独立一行,行尾无需使用分号 块(blocks{}) 由大括号括起来的语句,如pipeline{},Section{},parameters{},script{} 章节(Sections) 通常包含一个或多个指令或步骤。如 agent 、post、stages、steps 指令(Directives) environment、options、parameters、triggers(触发)、stage、tools、when 步骤(Steps) agent 必须存在,agent必须在pipeline块内的顶层定义,但stage内是否使用使可选的
预计在这里演示一下Pipeline的创建方法,然后再演示几个常用的配置
实际上还有Blue Ocean的创建pipeline的方法,但是我这边更常用一些老的方法
<1>新建一个item 项目
<2>根据你的项目的需求选择要创建的格式
由于要演示Pipeline,可以选择流水线 或者自由风格的软件项目
<3>设置上线记录和描述(可跳过)
和之前jenkins文档里配置方式没区别
也可省略,到pipeline里配置
<4>配置流水线
选择2种语法格式的任意一个即可,点击右侧j进行选择 可以显示jenkins自带的模板
可以点击流水线语法,选择想要的步骤,生成流水线脚本
接着页面就会显示这个步骤要使用的语法
<5>创建dingding机器人的robot
创建dingding机器人
"https://blog.csdn.net/GX_1_11_real/article/details/98725787"
钉钉插件网址:
"http://updates.jenkins-ci.org/download/plugins/dingding-notifications/"
实际上从dingding插件的2.0及其以上的版本开始,钉钉通知的设置方式产生了较大的变化,要在系统管理里设置,之后的版本适应了不同的生产环境,通知的配置更加的灵活
建议在jenkins版本允许的基础上,使用2.0以上插件(钉钉2.0插件最低对应jenkins 2.176.4及其以上)
以下演示的是dingding插件2.0及其以上版本的配置方法
演示用的jenkins是2.3.44
id不用填,让其自动生成(这个就是后面pipeline中的robot)
填入webhook
和
认证方式(和钉钉创建机器人的设置保持一致)
2.0以前的版本,不能在系统设置中设置dingding
它是在安装后,直接在该项目的 构建后操作 中配置 钉钉通知,根据要求填入即可
pipeline { //首先表明这是一个声明式的pipeline agent any //指定整个管道或特定阶段在Jenkins环境中的执行位置,选择在jenkins的哪个节点执行,常见any, none, label, node, docker, dockerfile。此处的意思是 在任意jenkins环境中可用的机器上执行pipeline 也可以单独指定某个节点agent{ label 'slave1'} options { //用于配置Jenkins pipeline本身有的选项 buildDiscarder(logRotator(numToKeepStr: '30')) //表示保留30次构建历史 timestamps() //打印日志带上对应时间 timeout(time: 10, unit: 'MINUTES') //流水线构建超过10分钟,终止构建 } # environment { //设置设置环境变量,可定义在stage或pipeline部分。例如可以设置IP的变量,便于之后的阶段中调用 # TST = /data/workspace2 # } # triggers{ //设置触发器,格式类似Centos计划任务 # pollSCM('H/5 * * * *') # } stages { //声明这是一个多个阶段的流水线 stage('清理工作空间') { //声明这是一个什么阶段(根据自己的情况创建不同的阶段) steps { //下面需要填入这个阶段的具体步骤 script{ println env.WORKSPACE dir("${env.WORKSPACE}/"){ sh "pwd" } sh("ls -al ${env.WORKSPACE}") deleteDir() sh("ls -al ${env.WORKSPACE}") } } stage('拉取代码') { steps { git credentialsId: '89e62xxxx-xxxxxx', url: 'git@gitlab.xxx.cn:xxxx.git' } } stage('mvn构建'){ withMaven(maven: 'maven') { sh "cd $WORKSPACE/" sh "mvn clean install -Dmaven.test.skip=true" } } stage(部署){ steps{ sh 'scp $WORKSPACE/target/xxx.jar root@业务服务器的ip:/jar_dir_path/' sh 'ssh root@你业务服务器的ip "/script/deploy.sh"' //执行远程服务器上的脚本 } } } post { //post指的是构建后操作,success成功后执行,failure失败后执行 success { dingtalk ( robot: "你的机器人的id不是token", type:'ACTION_CARD', //通知的消息类型,即采用的格式 atAll: false, //是否@所有人 title: "构建成功:${env.JOB_NAME}", //通知的标题 text: [ "### xx平台上线 ${env.JOB_NAME} ", '---', "- 任务:[${currentBuild.displayName}](${env.BUILD_URL})", '- 状态:<font color=#00CD00 >上线成功</font>', "- 持续时间:${currentBuild.durationString}".split("and counting")[0], "- 执行人:${BUILD_USER}", ] ) } failure{ dingtalk ( robot: "你的机器人的id不是token", type:'ACTION_CARD', atAll: false, title: "构建失败:${env.JOB_NAME}", text: [ "### xx平台上线 ${env.JOB_NAME}", '---', "- 任务:[${currentBuild.displayName}](${env.BUILD_URL})", '- 状态:<font color=#EE0000 >上线失败</font>', "- 持续时间:${currentBuild.durationString}".split("and counting")[0], "- 执行人:${BUILD_USER}" ] ) } } } }
<1>
实际上,上面的示例可根据自己需求决定是否采用
本示例stages下的,
第一个阶段是上线前清理jenkins服务器上该项目的工作空间
WORKSPACE 是这个项目的工作目录的绝对路径,为了避免编译时产生干扰,所以上线前清理旧代码
dir() 改变当前的工作目录,相当于Centos 的 cd(为了演示所以加了一句dir)
deleteDir() 不加参数,默认递归删除WORKSPACE下的文件和文件夹
script 该script步骤需要一个脚本式Pipeline,并在声明性Pipeline中执行。用这个语法,后面可以用当前环境中的命令的执行操作
sh 用这个方法,后面可以执行shell命令,有时也会经常用来调用jenkins服务器上的脚本;bat是windows命令
<2>
第二个阶段是拉取代码
git的语法可根据需求使用流水线语法生成
可以选择分支,默认是master
<3>
第三个阶段是编译
withMaven需要装一个插件Pipeline Maven Integration,会根据后面填写的变量指定maven,默认读取的是jenkins服务器的环境变量中的maven
如不使用这个语法,去除后,编译命令直接写绝对路径也可以
sh "/data/bin/mvn clean install -Dmaven.test.skip=true"
<4>
第四个阶段是部署 可以用命令行、ansible、调用脚本等方式。构建镜像或k8s的apply都可以 目标是将代码弄到线上环境,并使服务生效 (别忘了产生代码备份,根据需求) 随着需求的不同,方法也不同,所以示例仅列举了部分常用的 # stage(部署){ # steps{ # ansiblePlaybook installation: 'ansible-playbook', inventory: '/etc/ansible/online1/hosts', playbook: '/etc/ansible/online1/project.yml' # } # } # stage(部署){ # steps{ # sh "sh $WORKSPACE/../script/online.sh" # } # }
补充:
实际上通常部署或其他阶段还能细分,使用when和当上线时工作人员手动从web界面填入的变量,产生不同的结果
创建文本或其他格式的环境变量,配置后,在上线时会要求工作人员去填入参数
stages {
stage('编译'){
when { //当下方的条件满足,这个阶段才执行
environment name: 'GITENV', value: 'uat' //如果环境变量的值与给定的值相同就执行
}
withMaven(maven: 'maven') {
sh "cd $WORKSPACE/"
sh "mvn clean package -Puat -Dmaven.test.skip=true"
}
}
<5>
第五个阶段是通知 也可以通过python或shell,使用邮箱或钉钉及其他方式,对上线结果进行通知 如果是使用相关插件的,注意jenkins版本和插件版本 补充1 2.0以前的dingding插件,项目如果用pipline的配置方法 post { success { dingTalk accessToken:'https://oapi.dingtalk.com/robot/send?access_token=你的token', imageUrl:'http:/xxxxxx/success.png', //要在通知中插入的图片 jenkinsUrl:'http://localhost/jenkins/', //要跳转的url message:'更新提示: xxxxxxxxx上线成功', //要发布的通知 notifyPeople:'' } failure { dingTalk accessToken:'https://oapi.dingtalk.com/robot/send?access_token=你的token', imageUrl:'http://xxxxxx/failure.png', jenkinsUrl:'http://localhost/jenkins/', message:'更新提示: xxxxxxxx上线失败', notifyPeople:'' } } 补充2 通过curl或python的请求并发送报警,无需安装钉钉插件 但是这个方式报警需要 符合配置钉钉机器人时 设置的关键字或ip等限制 stage("钉钉通知"){ sh """ curl -H 'Content-Type: application/json' "https://oapi.dingtalk.com/robot/send?access_token=你的token" \ -d ' { "actionCard": { "title": "上线通知", "text": "xx平台上线 \n\n ${env.JOB_NAME} 上线成功 \n\n", "hideAvatar": "0", "btnOrientation": "0", "singleTitle" : "查看详情", "singleURL" : "http://jenkins.com/" //你的jenkins地址 }, "msgtype": "actionCard" }' """ } 补充3 如果是一个邮件的脚本,脚本中的报警内容等参数可设置成变量,pipeline在通知这一阶段导入变量,即可实现报警内容的定制
钉钉的pipeline语法
"https://jenkinsci.github.io/dingtalk-plugin/guide/pipeline.html#参数说明"
先创建参数化构建,后面示例的pipelien中有用到
node { stage("清理工作空间"){ deleteDir() } } node("slave1"){ //指定整个管道或特定阶段在Jenkins环境中的执行的节点,不填默认是master节点执行 也可以单独指定某个节点agent{ label 'slave1'} stage('变量配置') { project_work_list=["192.168.1.1","192.168.1.2"] //要上线的IP TOKEN='xxx' //dingding机器人的token } stage('拉取代码') { checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'xxxx', url: 'http://xxxx.git']]]) //和声明式一样,可用流水线语法生成 } stage('构建') { sh "cd $WORKSPACE/" sh "mvn clean install -U -Puat -Dmaven.test.skip=true" } stage('部署') { for (i <project_work_list.size();i++){ def ip=project_work_list[i] if ( "${project_name}" == "bigdata" ){ //这里的project_name需要你去开启参数化构建,创建一个参数project_name。示例含义:当项目是大数据的时候,使用一种上线脚本,当项目是其他的时候,使用其他的上线脚本 sh "scp $WORKSPACE/target/xxx.jar root@${ip}:/jar_dir_path/" sh '"ssh root@${ip} "/script/start_project.sh"' }else { sh "scp $WORKSPACE/target/xxx.jar root@${ip}:/jar_dir_path/" sh 'ssh root@${ip} "/script/deploy.sh"' } } } stage("钉钉通知"){ sh """ curl -H 'Content-Type: application/json' "https://oapi.dingtalk.com/robot/send?access_token=${TOKEN}" \ -d ' { "actionCard": { "title": "上线通知", "text": "xx平台上线 \n\n ${env.JOB_NAME} 上线成功 \n\n", "hideAvatar": "0", "btnOrientation": "0", "singleTitle" : "查看详情", "singleURL" : "http://jenkins.com/" //你的jenkins地址 }, "msgtype": "actionCard" }' """ }
能看懂声明式的,应该能看懂脚本式,基本不用解释
虽然脚本式看着简单,但是如果要深入,用的更花,需要去官方网址再研究
脚本式区别于声明式pipeline的明显的一点是,只支持stage,像stages、steps更复杂的划分则不支持,因此在脚本中仅仅看到了stage,示例中的if和for用着很方便,但是如果要在声明式用循环需要script
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。