最近,将公司的CI/CD
从jenkins传统配置
更改成了jenkins最新的声明式流水线(Declarative Pipeline)
,这样就可以使用jenkins的清爽的Pipeline界面Blue Ocean
,向jenkins的老旧繁杂界面say goodbye!
之前看网上写的一些文章,这给我读的,脑瓜子疼!明明一个很简单的东西,要搞的那么复杂,害得我踩坑踩了很久!!!
在这里记录下,也给广大码农同胞一条捷径吧!
1 环境准备
- jenkins
- git
- vscode(可选,主要用jenkins代码高亮,代码提示,校验插件)
1.1 配置jenkins插件镜像源
这里我不得不说一句,
清华
牛B!因为清华的镜像源真的是无所不有!竟然连jenkins的插件镜像源都有,着实惊艳了我!
如果你不替换镜像源,可能会导致
Blue Ocean
安装失败
- 进入jenkins的
系统管理
- 进入
插件管理
- 点击
高级
- 在下方的
升级站点URL中输入
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
- 点击
提交
- 重启jenkins
1.2 安装Blue Ocean
- 进入jenkins的
系统管理
- 进入
插件管理
- 点击
可选插件
- 搜索
Blue Ocean
- 安装
2 Declarative Pipeline语法
在这里,我将说明一些常用的标签块,基本可以满足大家大部分的构建场景,剩下的冷门的大家可以在BlueOcean中编辑或去官网查看
默认所有二级标签块是无序的
2.1 pipeline(一级)
jenkinsfile的最外层,所有的步骤都要写在这个块里面 pipeline文档
pipeline{
}
2.2 agent(二级)
指定jenkins的执行节点,默认就是any
就可以了 agent文档
pipeline{
agent any
}
2.3 environment(二级)
就看这个名,你还能不知道是干啥的?环境变量!!!一个非常有用的东西,贯穿整个pipeline
使用的时候通过这种格式使用:$变量名
environment文档
pipeline{
environment{
// 下方的变量都是举例说明,用户可以自定义
// 版本,只改这个就行!!!
version = '0.1'
// docker镜像名
docker_app_name = 'demo'
// docker私库地址
docker_base_url = '192.168.1.100:1234'
// docker路径
docker_base_path = 'service'
}
}
2.4 tools(二级)
这个标签块就是用来声明你在jenkins中安装的插件的
例如下方就是用来声明jenkins中配置的maven
插接件 tools文档
pipeline{
tools {
// 两个单引号之间放你在插件中配置的name
// 插件 '配置中的插件名'
maven 'maven3.6.1'
}
}
2.5 stages(二级)
真正由你来自定义的构建流程的标签块,之后的stage
和``就放在这个代码块里的
其中要包括至少一个stage
stages文档
pipeline{
stages {
stage('Maven Build'){
}
}
}
2.5.1 stage(三级及以下)
终于进入这个高潮阶段了!我们将在这里定义我们的构建流程!
定义至少一个stage
stage文档
pipeline{
stages {
// 括号内是我们给这个流程定义一个名字
stage('Maven Build'){
steps {
// 打印 不要跟linux的sh混淆 跟linux的sh并不通用
echo 'Maven Building....'
}
}
stage('Test'){
steps {
echo 'Testing....'
}
}
stage('Sonar Check'){
steps {
echo 'Sonar Checking....'
}
}
stage('Docker Build'){
steps {
echo 'Docker Building....'
}
}
stage('Rancher Deploy'){
steps {
echo 'Rancher Deploying....'
}
}
}
}
2.5.2 steps(四级及以下)
这个标签快就是用来让我们在流程中编写执行的步骤
定义至少一个steps
steps文档
pipeline{
stages {
stage('Maven Build'){
// 步骤,用来定义流程内的具体实现
steps {
// 打印
echo 'Maven Building1....'
}
steps {
// 打印
echo 'Maven Building2....'
}
}
}
}
2.5.3 when(四级及以下)
这个标签块跟我们写程序时用的if
异曲同工!用来控制该节点是否运行
该标签块有几个条件,我们这里以branch
举例, 其他的可以去看when文档
pipeline{
stages {
stage('Maven Build'){
when {
// 当分支是develop时执行
branch 'develop'
}
steps {
echo 'Maven Building....'
}
}
stage('Test'){
when {
// 当分支是test时执行
branch 'test'
}
steps {
echo 'Testing....'
}
}
}
}
2.5.4 parallel(四级及以下)
这个标签块很迷惑人,叫做并行
当我第一次看到这个语法的时候,没有在意,以为是多线程的概念,然而我错了!
这个标签块可以配合when
来达到多环境同流程不同构建的目的 parallel文档
pipeline{
stages {
stage('Docker Build') {
parallel {
stage('Dev') {
when {
branch 'develop'
}
steps {
echo 'Dev Building....'
}
}
stage('Test') {
when {
branch 'test'
}
steps {
echo 'Test Building....'
}
}
}
}
stage('Rancher Deploy'){
echo 'Rancher Deploying....'
}
}
}
2.5.5 post(二级)
这个标签块就是jenkins中原来的构建后执行,大家可以自由发挥,我这里主要用来钉钉通知
这里我以成功
,失败
,总是
举例,还有其他条件,大家可以去看post文档
pipeline{
post {
failure {
echo '构建失败'
script{
jenkins_projectname=env.JOB_NAME.substring(0,env.JOB_NAME.indexOf('/'))
log_url=env.JENKINS_URL+"blue/organizations/jenkins/"+jenkins_projectname+"/detail/"+env.BRANCH_NAME+"/"+env.BUILD_NUMBER+"/pipeline#"
}
echo "${log_url}"
dingTalk(accessToken: "$jenkins_dingding_token", imageUrl: 'http://www.iconsdb.com/icons/preview/soylent-red/x-mark-3-xxl.png',
message: "构建失败", jenkinsUrl: "${log_url}")
}
success {
echo '构建成功'
script{
jenkins_projectname=env.JOB_NAME.substring(0,env.JOB_NAME.indexOf('/'))
log_url=env.JENKINS_URL+"blue/organizations/jenkins/"+jenkins_projectname+"/detail/"+env.BRANCH_NAME+"/"+env.BUILD_NUMBER+"/pipeline#"
}
dingTalk(accessToken: "$jenkins_dingding_token", imageUrl: 'http://icons.iconarchive.com/icons/paomedia/small-n-flat/1024/sign-check-icon.png',
message: "构建成功",jenkinsUrl: "${log_url}")
}
always {
echo '开始构建'
script{
jenkins_projectname=env.JOB_NAME.substring(0,env.JOB_NAME.indexOf('/'))
log_url=env.JENKINS_URL+"blue/organizations/jenkins/"+jenkins_projectname+"/detail/"+env.BRANCH_NAME+"/"+env.BUILD_NUMBER+"/pipeline#"
}
dingTalk(accessToken: "$jenkins_dingding_token", imageUrl: 'http://icon-park.com/imagefiles/loading7_gray.gif',
message: "开始构建", jenkinsUrl: "${log_url}")
}
}
}
3 构建CI/CD流程
3.1 编写Jenkinsfile
在我们的项目根目录下创建Jenkinsfile
文件
下面的代码包含,maven打包
,sonar检查
,检查钉钉通知
,docker打包
,RancherWebhook部署
,钉钉构建通知
这些在我的文章里有讲,感兴趣可以去看看
Jenkinsfile 举例:
pipeline {
agent any
environment {
//版本,只改这个就行!!!
version = '0.1'
//docker镜像名
docker_app_name = 'demo'
//docker私库地址
docker_base_url = '192.168.1.100:1234'
//docker路径
docker_base_path = 'service'
//docker线上地址
docker_ali_base_url = 'registry.cn-hangzhou.aliyuncs.com'
//docker线上路径
docker_ali_base_path = 'demo-service'
//sonar_scanner的home路径
sonar_scanner_home = tool name: 'SonarScanner4'
//sonar project名
sonar_app_name = 'demo'
//sonar服务地址
sonar_url = 'http://192.168.1.200'
//sonar钉钉机器人token
sonar_dingding_token = '111111111111111111111111111111111111'
//sonar钉钉通知服务地址
sonar_dingding_url = '192.168.1.300'
//rancher webhook地址
rancher_notify_url = '192.168.1.400'
rancher_uat_notify_url = 'webhook-demo.rancher.ocom'
//webhook配置名
rancher_app_name = 'demo'
//webhook配置token
rancher_token = '2222222222222222222222222'
//rancher命名空间
rancher_namespace = 'default'
//rancher的服务类型
rancher_workload = 'deployment/demo'
//rancher容器名
rancher_container_name = 'demo'
//镜像仓库类型
rancher_repo_name = 'custom'
//jenkins钉钉机器人token
jenkins_dingding_token = '3333333333333333333333333'
}
tools {
maven 'maven3.6.1'
}
stages {
// 开发环境maven打包
stage('Maven Build'){
when {
branch 'develop'
}
steps{
sh 'mvn clean package dependency:copy-dependencies'
}
}
// 开发环境sonar检查
stage('Sonar Check') {
when {
branch 'develop'
}
steps {
echo 'Sonar Checking....'
withSonarQubeEnv('sonarqube') {
sh "${sonar_scanner_home}/bin/sonar-scanner -Dsonar.projectVersion=$version"
}
// sonar的钉钉通知
sh(label: 'Sonar DingDing Notify', script:
'''
#!/bin/bash
sonarreport=$(curl -s http://$sonar_dingding_url?projectname=$sonar_app_name)
message_url="http://icons.iconarchive.com/icons/paomedia/small-n-flat/1024/sign-check-icon.png"
strB="ERROR"
case $sonarreport in
*"$strB"*) message_url=\"http://www.iconsdb.com/icons/preview/soylent-red/x-mark-3-xxl.png\" ;;
*) message_url=\"http://icons.iconarchive.com/icons/paomedia/small-n-flat/1024/sign-check-icon.png\" ;;
esac
echo $message_url
curl -s "https://oapi.dingtalk.com/robot/send?access_token=$sonar_dingding_token" \\
-H "Content-Type: application/json" \\
-d "{
\\"msgtype\\": \\"link\\",
\\"link\\": {
\\"title\\":\\"sonarqube代码质量报告:$sonar_app_name\\",
\\"text\\": \\"$sonarreport\\",
\\"picUrl\\": \\"$message_url\\",
\\"messageUrl\\":\\"$sonar_url/dashboard?id=$sonar_app_name\\"
}
}"
'''
)
}
}
stage('Docker Build') {
parallel {
//开发环境构建docker
stage('Dev') {
when {
branch 'develop'
}
steps {
echo 'Docker Building....'
sh(label: 'Docker Build', script:
'''
docker build -t $docker_base_url/$docker_base_path/$docker_app_name:$version .
docker push $docker_base_url/$docker_base_path/$docker_app_name:$version
'''
)
}
}
//测试环境构建docker
stage('Test') {
when {
branch 'test'
}
steps {
echo 'Docker Building....'
sh(label: 'Docker Build', script:
'''
docker pull $docker_base_url/$docker_base_path/$docker_app_name:$version
docker tag $docker_base_url/$docker_base_path/$docker_app_name:$version $docker_ali_base_url/$docker_ali_base_path/$docker_app_name:$version
docker push $docker_ali_base_url/$docker_ali_base_path/$docker_app_name:$version
'''
)
}
}
}
}
stage('Test') {
steps {
echo 'Testing..'
}
}
stage('Rancher Deploy') {
parallel {
// 开发环境部署
stage('Dev') {
when {
branch 'develop'
}
// rancher webhook
steps {
echo 'Rancher Deploying....'
sh(label: 'Rancher Deploy', script:
'''
#!/bin/bash
curl -X POST "http://$rancher_notify_url/hooks/$rancher_app_name?token=$rancher_token&ns=$rancher_namespace&workload=$rancher_workload&container=$rancher_container_name&repo_type=$rancher_repo_name" -H \'Content-Type: application/json\' -H \'cache-control: no-cache\' \\
-d "{
\\"push_data\\": {
\\"tag\\": \\"$version\\"
},
\\"repository\\": {
\\"repo_url\\": \\"$docker_base_url\\",
\\"name\\": \\"$docker_app_name\\",
\\"namespace\\": \\"$docker_base_path\\"
}
}"
'''
)
}
}
//测试环境部署
stage('Test') {
when {
branch 'test'
}
steps {
echo 'Rancher Deploying....'
sh(label: 'Rancher Deploy', script:
'''
#!/bin/bash
curl -X POST "http://$rancher_uat_notify_url/hooks/$rancher_app_name?token=$rancher_token&ns=$rancher_namespace&workload=$rancher_workload&container=$rancher_container_name&repo_type=$rancher_repo_name" -H \'Content-Type: application/json\' -H \'cache-control: no-cache\' \\
-d "{
\\"push_data\\": {
\\"tag\\": \\"$version\\"
},
\\"repository\\": {
\\"repo_url\\": \\"$docker_ali_base_url\\",
\\"name\\": \\"$docker_app_name\\",
\\"namespace\\": \\"$docker_ali_base_path\\"
}
}"
'''
)
}
}
}
}
}
post {
failure {
echo '构建失败'
dingTalk(accessToken: "$jenkins_dingding_token", imageUrl: 'http://www.iconsdb.com/icons/preview/soylent-red/x-mark-3-xxl.png',
message: "构建失败", jenkinsUrl: "${env.BUILD_URL}")
}
// success {
// echo '构建成功'
// dingTalk(accessToken: "$jenkins_dingding_token", imageUrl: 'http://icons.iconarchive.com/icons/paomedia/small-n-flat/1024/sign-check-icon.png',
// message: "项目[${env.JOB_NAME}#${env.BUILD_NUMBER}]构建成功",jenkinsUrl: "${env.BUILD_URL}")
// }
// always {
// echo '开始构建'
// dingTalk(accessToken: "$jenkins_dingding_token", imageUrl: 'http://icon-park.com/imagefiles/loading7_gray.gif',
// message: "项目[${env.JOB_NAME}#${env.BUILD_NUMBER}]开始构建", jenkinsUrl: "${env.BUILD_URL}")
// }
}
}
3.2 Jenkinsfile的高亮、提示和校验
这个点,我将在另一篇文章中进行说明Jenkinsfile的高亮、提示和校验
3.3 创建PipeLine
1.进入jenkins
2.点击左侧的Blue Ocean
3.点击Create a new Pipeline
4.输入git
地址等信息,创建项目
5.pipline就会自动构建,你可以点进去看看呦!
下面是网上拿的图进行简单展示