基于K8s的DevOps平台实践(二)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录


1. 流水线入门

工厂的流水线如下

在这里插入图片描述

官方文档 的流水线如下

在这里插入图片描述

为什么叫做流水线其实和工厂产品的生产线类似pipeline 是从源码到发布到线上环境。

关于流水线需要知道的几个点

  • 重要的功能插件帮助 Jenkins 定义了一套工作流框架

  • Pipeline 的实现方式是一套 Groovy DSL 领域专用语言 所有的发布流程都可以表述为一段 Groovy 脚本

  • 将 WebUI 上需要定义的任务以脚本代码的方式表述出来

  • 帮助jenkins实现持续集成 CIContinue Integration和持续部署 CDContinue Deliver的重要手段

🍑 流水线基础语法

官方文档

两种语法类型

  • Scripted Pipeline脚本式流水线最初支持的类型
  • Declarative Pipeline声明式流水线为 Pipeline plugin 在 2.5 版本之后新增的一种脚本类型后续 Open Blue Ocean 所支持的类型。与原先的 Scripted Pipeline 一样都可以用来编写脚本。Declarative Pipeline 是后续 Open Blue Ocean 所支持的类型写法简单支持内嵌 Scripted Pipeline 代码

注意为与 BlueOcean 脚本编辑器兼容通常建议使用 Declarative Pipeline 的方式进行编写从 jenkins 社区的动向来看很明显这种语法结构也会是未来的趋势。

🍑 脚本示例

json 脚本

pipeline { 
    agent {label '172.21.51.68'}
    environment { 
        PROJECT = 'myblog'
    }
    stages {
        stage('Checkout') { 
            steps { 
                checkout scm 
            }
        }
        stage('Build') { 
            steps { 
                sh 'make' 
            }
        }
        stage('Test'){
            steps {
                sh 'make check'
                junit 'reports/**/*.xml' 
            }
        }
        stage('Deploy') {
            steps {
                sh 'make publish'
            }
        }
    }
	post {
        success { 
            echo 'Congratulations!'
        }
		failure { 
            echo 'Oh no!'
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

🍑 脚本解释

  • checkout 步骤为检出代码scm 是一个特殊变量指示 checkout 步骤克隆触发此 Pipeline 运行的特定修订

  • agent指明使用哪个 agent 节点来执行任务定义于 pipeline 顶层或者 stage 内部

    • any可以使用任意可用的 agent 来执行

    • label在提供了标签的 Jenkins 环境中可用的代理上执行流水线或阶段。例如agent { label 'my-defined-label' }最常见的使用方式

    • none当在 pipeline 块的顶部没有全局代理该参数将会被分配到整个流水线的运行中并且每个 stage 部分都需要包含他自己的 agent 部分。比如agent none

    • docker 使用给定的容器执行流水线或阶段。 在指定的节点中通过运行容器来执行任务

agent {
    docker {
        image 'maven:3-alpine'
        label 'my-defined-label'
        args  '-v /tmp:/tmp'
    }
}
  • options允许从流水线内部配置特定于流水线的选项。

    • buildDiscarder为最近的流水线运行的特定数量保存组件和控制台输出。例如: options { buildDiscarder(logRotator(numToKeepStr: '10')) }
    • disableConcurrentBuilds不允许同时执行流水线。 可被用来防止同时访问共享资源等。 例如: options { disableConcurrentBuilds() }
    • timeout设置流水线运行的超时时间, 在此之后Jenkins将中止流水线。例如: options { timeout(time: 1, unit: 'HOURS') }
    • retry在失败时, 重新尝试整个流水线的指定次数。 For example: options { retry(3) }
  • environment指令制定一个 键-值对序列该序列将被定义为所有步骤的环境变量

  • stages包含一系列一个或多个 stage 指令stages 部分是流水线描述的大部分 “work” 的位置。 建议 stages 至少包含一个 stage 指令用于连续交付过程的每个离散部分比如构建、测试和部署。

pipeline {
    agent any
    stages { 
        stage('Example') {
            steps {
                echo 'Hello World'
            }
        }
    }
}
  • steps在给定的 stage 指令中执行的定义了一系列的一个或多个 steps

  • post定义一个或多个 steps 这些阶段根据流水线或阶段的完成情况而运行 post 支持以下 post-condition 块中的其中之一 alwayschangedfailuresuccessunstableaborted

    • always无论流水线或阶段的完成状态如何都允许在 post 部分运行该步骤
    • changed当前流水线或阶段的完成状态与它之前的运行不同时才允许在 post 部分运行该步骤
    • failure当前流水线或阶段的完成状态为 “failure”才允许在 post 部分运行该步骤通常 web UI 是红色
    • success当前流水线或阶段的完成状态为 “success”才允许在 post 部分运行该步骤通常 web UI 是蓝色或绿色
    • unstable当前流水线或阶段的完成状态为 “unstable”才允许在 post 部分运行该步骤通常由于测试失败代码违规等造成。通常 web UI 是黄色
    • aborted只有当前流水线或阶段的完成状态为 “aborted”才允许在 post 部分运行该步骤通常由于流水线被手动的aborted。通常 web UI 是灰色

创建 pipeline 示意新建任务 -> 流水线

jenkins/pipelines/p1.yaml

pipeline {
   agent {label '172.21.51.68'}
   environment { 
      PROJECT = 'myblog'
   }
   stages {
      stage('printenv') {
         steps {
            echo 'Hello World'
            sh 'printenv'
         }
      }
      stage('check') {
         steps {
            checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-user', url: 'http://gitlab.luffy.com/root/myblog.git']]])
         }
      }
      stage('build-image') {
         steps {
            sh 'docker build . -t myblog:latest -f Dockerfile'
         }
      }
      stage('send-msg') {
         steps {
            sh """
            curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
   -H 'Content-Type: application/json' \
   -d '{"msgtype": "text", 
        "text": {
             "content": "我就是我, 是不一样的烟火"
        }
      }'
      """
         }
      }
   }
}

点击 “立即构建”同样的我们可以配置触发器使用 webhook 的方式接收项目的 push 事件

  • 构建触发器选择 Build when a change is pushed to GitLab.
  • 生成 Secret token
  • 配置 gitlab创建 webhook发送 test push events 测试

🍑 Blue Ocean

官方文档

关于 Blue Ocean 我们需要知道的几点

  • 是一个插件 旨在为 Pipeline 提供丰富的体验
  • 连续交付CDPipeline 的复杂可视化允许快速和直观地了解 Pipeline 的状态
  • 目前支持的类型仅针对于 Pipeline尚不能替代 Jenkins 经典版UI

思考

  1. 每个项目都把大量的 pipeline 脚本写在 Jenkins 端对于谁去维护及维护成本是一个问题
  2. 没法做版本控制

2. Jenkinsfile实践

Jenkins Pipeline 提供了一套可扩展的工具用于将 “简单到复杂” 的交付流程实现为 “持续交付即代码”。

Jenkins Pipeline 的定义通常被写入到一个文本文件称为 Jenkinsfile 中该文件可以被放入项目的源代码控制库中。

🍑 演示一

演示1使用 Jenkinsfile 管理 pipeline

  • 在项目中新建 Jenkinsfile 文件拷贝已有 script 内容
  • 配置 pipeline 任务流水线定义为 Pipeline Script from SCM
  • 执行 push 代码测试

Jenkinsfilejenkins/pipelines/p2.yaml

pipeline {
   agent {label '172.21.51.68'}
   environment { 
      PROJECT = 'myblog'
   }
   stages {
      stage('printenv') {
         steps {
            echo 'Hello World'
            sh 'printenv'
         }
      }
      stage('check') {
         steps {
            checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'gitlab-user', url: 'http://gitlab.luffy.com/root/myblog.git']]])
         }
      }
      stage('build-image') {
         steps {
            sh 'docker build . -t myblog:latest -f Dockerfile'
         }
      }
      stage('send-msg') {
         steps {
            sh """
            curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
   -H 'Content-Type: application/json' \
   -d '{"msgtype": "text", 
        "text": {
             "content": "我就是我, 是不一样的烟火"
        }
      }'
      """
         }
      }
   }
}

🍑 演示二

演示2优化及丰富流水线内容

  • 优化代码检出阶段

    由于目前已经配置了使用 git 仓库地址且使用 SCM 来检测项目因此代码检出阶段完全没有必要再去指定一次

  • 构建镜像的 tag 使用 git 的 commit id

  • 增加 post 阶段的消息通知丰富通知内容

  • 配置 webhook实现 myblog 代码推送后触发 Jenkinsfile 任务执行

jenkins/pipelines/p3.yaml

pipeline {
    agent { label '172.21.51.68'}

    stages {
        stage('printenv') {
            steps {
            echo 'Hello World'
            sh 'printenv'
            }
        }
        stage('check') {
            steps {
                checkout scm
            }
        }
        stage('build-image') {
            steps {
            	retry(2) { sh 'docker build . -t myblog:${GIT_COMMIT}'}
            }
        }
    }
    post {
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😄👍构建成功👍😄\n 关键字luffy\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😖❌构建失败❌😖\n 关键字luffy\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

🍑 演示三

演示3使用 k8s 部署服务

  • 新建 deploy 目录将 k8s 所需的文件放到 deploy 目录中

  • 将镜像地址改成模板在 pipeline 中使用新构建的镜像进行替换

  • 执行 kubectl apply -f deploy 应用更改需要配置 kubectl 认证

$ scp -r k8s-master:/root/.kube /root

jenkins/pipelines/p4.yaml

pipeline {
    agent { label '172.21.51.68'}

    environment {
        IMAGE_REPO = "172.21.51.143:5000/myblog"
    }

    stages {
        stage('printenv') {
            steps {
              echo 'Hello World'
              sh 'printenv'
            }
        }
        stage('check') {
            steps {
                checkout scm
            }
        }
        stage('build-image') {
            steps {
                retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
            }
        }
        stage('push-image') {
            steps {
                retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
            }
        }
        stage('deploy') {
            steps {
                sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
                timeout(time: 1, unit: 'MINUTES') {
                    sh "kubectl apply -f manifests/"
                }
            }
        }
    }
    post {
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😄👍构建成功👍😄\n 关键字myblog\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=4778abd23dbdbaf66fc6f413e6ab9c0103a039b0054201344a22a5692cdcc54e' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😖❌构建失败❌😖\n 关键字luffy\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

🍑 演示四

演示4使用凭据管理敏感信息

上述 Jenkinsfile 中存在的问题是敏感信息使用明文暴漏在代码中如何管理流水线中的敏感信息包含账号密码之前我们在对接 gitlab 的时候需要账号密码已经使用过凭据来管理这类敏感信息同样的我们可以使用凭据来存储钉钉的 token 信息那么创建好凭据后如何在 Jenkinsfile 中获取已有凭据的内容

Jenkins 的声明式流水线语法有一个 credentials() 辅助方法在 environment 指令中使用它支持 secret 文本带密码的用户名以及 secret 文件凭据。

下面的流水线代码片段展示了如何创建一个使用带密码的用户名凭据的环境变量的流水线。

在该示例中带密码的用户名凭据被分配了环境变量用来使你的组织或团队以一个公用账户访问 Bitbucket 仓库这些凭据已在 Jenkins 中配置了凭据 ID jenkins-bitbucket-common-creds

当在 environment 指令中设置凭据环境变量时

environment {
    BITBUCKET_COMMON_CREDS = credentials('jenkins-bitbucket-common-creds')
}

这实际设置了下面的三个环境变量

  • BITBUCKET_COMMON_CREDS - 包含一个以冒号分隔的用户名和密码格式为 username:password
  • BITBUCKET_COMMON_CREDS_USR - 附加的一个仅包含用户名部分的变量。
  • BITBUCKET_COMMON_CREDS_PSW - 附加的一个仅包含密码部分的变量。
pipeline {
    agent {
        // 此处定义 agent 的细节
    }
    environment {
        //顶层流水线块中使用的 environment 指令将适用于流水线中的所有步骤。 
        BITBUCKET_COMMON_CREDS = credentials('jenkins-bitbucket-common-creds')
    }
    stages {
        stage('Example stage 1') {
 			//在一个 stage 中定义的 environment 指令只会将给定的环境变量应用于 stage 中的步骤。
            environment {
                BITBUCKET_COMMON_CREDS = credentials('another-credential-id')
            }
            steps {
                // 
            }
        }
        stage('Example stage 2') {
            steps {
                // 
            }
        }
    }
}

因此对 Jenkinsfile 做改造jenkins/pipelines/p5.yaml

pipeline {
    agent { label '172.21.51.68'}

    environment {
        IMAGE_REPO = "172.21.51.143:5000/myblog"
        DINGTALK_CREDS = credentials('dingTalk')
    }

    stages {
        stage('printenv') {
            steps {
            echo 'Hello World'
            sh 'printenv'
            }
        }
        stage('check') {
            steps {
                checkout scm
            }
        }
        stage('build-image') {
            steps {
                retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
            }
        }
        stage('push-image') {
            steps {
                retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
            }
        }
        stage('deploy') {
            steps {
                sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
                timeout(time: 1, unit: 'MINUTES') {
                    sh "kubectl apply -f manifests/"
                }
            }
        }
    }
    post {
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😄👍构建成功👍😄\n 关键字luffy\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype": "text", 
                            "text": {
                                "content": "😖❌构建失败❌😖\n 关键字luffy\n 项目名称: ${JOB_BASE_NAME}\n Commit Id: ${GIT_COMMIT}\n 构建地址${RUN_DISPLAY_URL}"
                        }
                }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

🍑 总结

上面我们已经通过 Jenkinsfile 完成了最简单的项目的构建和部署那么我们来思考目前的方式

目前都是在项目的单一分支下进行操作企业内一般会使用 feature、develop、release、master 等多个分支来管理整个代码提交流程如何根据不同的分支来做构建

构建视图中如何区分不同的分支

如何不配置 webhook 的方式实现构建

如何根据不同的分支选择发布到不同的环境开发、测试、生产

3. 多分支流水线实践

官方示例

我们简化一下流程假如使用 develop 分支作为开发分支master 分支作为集成测试分支看一下如何使用多分支流水线来管理。

🍑 演示一

演示1多分支流水线的使用

1提交develop分支

$ git checkout -b develop
$ git push --set-upstream origin develop

2禁用 pipeline 项目

3Jenkins 端创建多分支流水线项目

  • 增加 git 分支源
  • 发现标签
  • 根据名称过滤develop|master|v.*
  • 高级克隆设置浅克隆

保存后会自动检索项目中所有存在 Jenkinsfile 文件的分支和标签若匹配我们设置的过滤正则表达式则会添加到多分支的构建视图中。所有添加到视图中的分支和标签会默认执行一次构建任务。

🍑 演示二

演示2美化消息通知内容

  • 添加构建阶段记录
  • 使用 markdown 格式添加构建分支消息

jenkins/pipelines/p6.yaml

pipeline {
    agent { label '172.21.51.68'}

    environment {
        IMAGE_REPO = "172.21.51.143:5000/myblog"
        DINGTALK_CREDS = credentials('dingTalk')
        TAB_STR = "\n                    \n                    "
    }

    stages {
        stage('printenv') {
            steps {
                script{
                    sh "git log --oneline -n 1 > gitlog.file"
                    env.GIT_LOG = readFile("gitlog.file").trim()
                }
                sh 'printenv'
            }
        }
        stage('checkout') {
            steps {
                checkout scm
                script{
                    env.BUILD_TASKS = env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('build-image') {
            steps {
                retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('push-image') {
            steps {
                retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('deploy') {
            steps {
                sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
                timeout(time: 1, unit: 'MINUTES') {
                    sh "kubectl apply -f manifests/"
                }
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
    }
    post {
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown",
                        "markdown": {
                            "title":"myblog",
                            "text": "😄👍 构建成功 👍😄  \n**项目名称**luffy  \n**Git log**: ${GIT_LOG}   \n**构建分支**: ${GIT_BRANCH}   \n**构建地址**${RUN_DISPLAY_URL}  \n**构建任务**${BUILD_TASKS}"
                        }
                    }'
            """ 
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown",
                        "markdown": {
                            "title":"myblog",
                            "text": "😖❌ 构建失败 ❌😖  \n**项目名称**luffy  \n**Git log**: ${GIT_LOG}   \n**构建分支**: ${GIT_BRANCH}  \n**构建地址**${RUN_DISPLAY_URL}  \n**构建任务**${BUILD_TASKS}"
                        }
                    }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

🍑 演示三

演示3通知 gitlab 构建状态

Jenkins 端做了构建可以通过 gitlab 通过的 api 将构建状态通知过去作为开发人员发起 Merge Request 或者合并 Merge Request 的依据之一。

注意一定要指定 gitLabConnection('gitlab')不然没法认证到 Gitlab 端

jenkins/pipelines/p7.yaml

pipeline {
    agent { label '172.21.51.68'}
    
    options {
		buildDiscarder(logRotator(numToKeepStr: '10'))
		disableConcurrentBuilds()
		timeout(time: 20, unit: 'MINUTES')
		gitLabConnection('gitlab')
	}

    environment {
        IMAGE_REPO = "172.21.51.143:5000/demo/myblog"
        DINGTALK_CREDS = credentials('dingTalk')
        TAB_STR = "\n                    \n                    "
    }

    stages {
        stage('printenv') {
            steps {
                script{
                    sh "git log --oneline -n 1 > gitlog.file"
                    env.GIT_LOG = readFile("gitlog.file").trim()
                }
                sh 'printenv'
            }
        }
        stage('checkout') {
            steps {
                checkout scm
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS = env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('build-image') {
            steps {
                retry(2) { sh 'docker build . -t ${IMAGE_REPO}:${GIT_COMMIT}'}
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('push-image') {
            steps {
                retry(2) { sh 'docker push ${IMAGE_REPO}:${GIT_COMMIT}'}
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
        stage('deploy') {
            steps {
                sh "sed -i 's#{{IMAGE_URL}}#${IMAGE_REPO}:${GIT_COMMIT}#g' manifests/*"
                timeout(time: 1, unit: 'MINUTES') {
                    sh "kubectl apply -f manifests/"
                }
                updateGitlabCommitStatus(name: env.STAGE_NAME, state: 'success')
                script{
                    env.BUILD_TASKS += env.STAGE_NAME + "√..." + env.TAB_STR
                }
            }
        }
    }
    post {
        success { 
            echo 'Congratulations!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown",
                        "markdown": {
                            "title":"myblog",
                            "text": "😄👍 构建成功 👍😄  \n**项目名称**luffy  \n**Git log**: ${GIT_LOG}   \n**构建分支**: ${BRANCH_NAME}   \n**构建地址**${RUN_DISPLAY_URL}  \n**构建任务**${BUILD_TASKS}"
                        }
                    }'
            """ 
        }
        failure {
            echo 'Oh no!'
            sh """
                curl 'https://oapi.dingtalk.com/robot/send?access_token=${DINGTALK_CREDS_PSW}' \
                    -H 'Content-Type: application/json' \
                    -d '{
                        "msgtype": "markdown",
                        "markdown": {
                            "title":"myblog",
                            "text": "😖❌ 构建失败 ❌😖  \n**项目名称**luffy  \n**Git log**: ${GIT_LOG}   \n**构建分支**: ${BRANCH_NAME}  \n**构建地址**${RUN_DISPLAY_URL}  \n**构建任务**${BUILD_TASKS}"
                        }
                    }'
            """
        }
        always { 
            echo 'I will always say Hello again!'
        }
    }
}

我们可以访问 gitlab然后找到 commit 记录查看同步状态

在这里插入图片描述

提交 merge request也可以查看到相关的任务状态可以作为项目 owner 合并代码的依据之一

在这里插入图片描述

🍑 总结

优势

  • 根据分支展示视图人性化
  • 自动检测各分支的变更

思考

  • Jenkins 的 slave 端没有任务的时候处于闲置状态slave 节点多的话造成资源浪费
  • 是否可以利用 kubernetes 的 Pod 来启动 slave动态 slave pod 来执行构建任务
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: k8s