devops学习(十一) 构建主分支--触发器--钉钉通知

一、master分支构建报错问题

在前一章我们实现了不同版本快速进行交付,但我们如果不选择分支直接构建就会报错了

 1、尝试添加条件分支,master主分支镜像名为latest

我们前面构建镜像的时候选择的是以tag标签作为镜像的版本信息,当我们没有选择任何标签时,他会根据我们配置的默认值origin/master 主分支去构建,这样一来我们就要走两条路 master和tag版本,我们在构建镜像和部署/更新的任务中添加条件分支

        stage('4、通过jenkins主机构建docker镜像') {
            steps() {
                echo '通过jenkins主机构建docker镜像   - SUCCESS'

                script{
                 if ("${tag}" == "origin/master" ){
                     sh '''mv ./target/*.jar docker/
                      docker build -t "${JOB_NAME}:latest" ./docker/
                      docker login ${harborAddress} -u${harborUser} -p${harborPasswd}
                      docker tag ${JOB_NAME}:latest  ${harborAddress}/${harborRepo}/${JOB_NAME}:latest
                      docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:latest'''
                   }
                 else{
                     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'


                script{  //这里当我们是master分支时 上传的镜像为latest
                if ("${tag}" == "origin/master" ){
                     sshPublisher(publishers: [sshPublisherDesc(configName: 'test', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "helm upgrade -i ${JOB_NAME} --set containers.image=$harborAddress/$harborRepo/${JOB_NAME}:latest --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)])
                }
                else {
                  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)])
                }
               }
           }
         }
我们上面做了两条分支路线,当master时把镜像打成latest标签,并更新为latest,当为其他标签时和之前的步骤一样

devops学习(十一) 构建主分支--触发器--钉钉通知_第1张图片

构建是能够通过的,但是存在一个问题,当我们多次构建master分支的时候,因为helm识别镜像并没有被修改,所以不会更新,下面我们做个测试

2、修改输出代码上传

我们这里修改一下输出的值,然后去jenkins构建,如果成功,容器会重启,访问页面会为V6.0.0才对

测试构建

从结果可以看到,我们虽然用最新代码构建了,但是实际部署的容器并没有更新

3、测试 用latest标签构建更新

上面说了我们helm在更新时发现原来更新的镜像都是latest,helm认为并没有发生修改,所以不会去更新pod,我们应该让这个标签流动起来做为一个动态标签,这里我们使用git commithash的值作为最新的标签

cd /apps/devops_setup/data/jenkins/data/workspace/pipeline

//查看
git log 

 devops学习(十一) 构建主分支--触发器--钉钉通知_第2张图片

我们每次git写入到仓库都会生成一个commit hash值,可以通过这个值找到对应的操作,我们最新版本的镜像就以这个标签来指定

 4、jenkinsfile全量配置整理

pipeline {

  agent any

  environment {
     harborUser  = 'admin'
     harborPasswd  = 'Harbor12345'
     harborAddress = '101.43.4.210:30007'
     harborRepo   = 'repo'
     GIT_COMMIT_HASH = ""
  }
     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() {
              script {
                 GIT_COMMIT_HASH = sh (script: "git log -n 1 --pretty=format:'%H'", returnStdout: true)

                 if ("${tag}" == "origin/master" ){
                    echo '通过jenkins主机构建docker镜像   - SUCCESS'
                    sh """mv ./target/*.jar docker/
                    docker build -t "${JOB_NAME}:latest" ./docker/
                    docker build -t "${JOB_NAME}:${GIT_COMMIT_HASH}" ./docker/
                    docker login ${harborAddress} -u${harborUser} -p${harborPasswd}
                    docker tag ${JOB_NAME}:latest  ${harborAddress}/${harborRepo}/${JOB_NAME}:${GIT_COMMIT_HASH}
                    docker tag ${JOB_NAME}:latest  ${harborAddress}/${harborRepo}/${JOB_NAME}:latest
                    docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${GIT_COMMIT_HASH}
                    docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:latest
                    """
                  }
                else {
                    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'
                echo "${GIT_COMMIT_HASH}"

                script{
                if ("${tag}" == "origin/master"){
                     echo "${tag}"
                     sshPublisher(publishers: [sshPublisherDesc(configName: 'test', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "helm upgrade -i ${JOB_NAME} --set containers.image=$harborAddress/$harborRepo/${JOB_NAME}:${GIT_COMMIT_HASH} --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)])
                }
                else {
                     echo "${tag}"
                     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)])
                }
               }



           }
         }
       }
}

说明

1、 添加全局变量 GIT_COMMIT_HASH = ""   当分支为master时将git commit hash写入全局变量

2、 镜像构建那部分, 当为master分支时我们把git_commithash 作为标签打镜像
     //mytest:latest             后续单独拉取时的最新镜像
     //mytest:${git_commithash}   每次helm更新部署时所用的镜像

3、  在helm部署部分,当我们操作的是master分支时,helm --set 更新的镜像名称的标签就是全局变量的GIT_COMMIT_HASH值

 5、构建测试

我现在部署的版本是V5,我们下面的操作中会更新代码中输出的值为V7,作为master分支进行推送,通过jenkins构建后可以看到我们实际运行中使用的镜像是git_commithash的值

这样一来,我们就每次上传代码去jenkins构建就能得到最新的版本部署了

语法参考

// 获取shell命令的标准输出或者状态  
https://blog.csdn.net/liurizhou/article/details/86670092?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-2-86670092-blog-81546477.pc_relevant_vip_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-2-86670092-blog-81546477.pc_relevant_vip_default&utm_relevant_index=3

二、设置构建触发器

上面实现了master主分支的自动化构建部署,但master分支会一直迭代版本的,下面我们将实现一个在推送代码后,自动去触发jenkins构建的一个触发器

1、安装jenkins webhook插件

//插件列表
Generic Webhook Trigger
gitlab

2、获取jenkins上的项目地址

http://101.43.4.210:30004/project/pipeline

3、在gitlab上添加webhook勾子并允许网络请求

4、关闭jenkins上gitlab插件验证,测试勾子是否可用

如上我们去测试勾子后会自动触发jenkins流程构建,下面我们更新下代码试试

5、上传新代码测试自动化构建

这样一来每次我们上传代码都会自动帮忙部署,当我们需要使用指定版本时也可以选择标签去部署,持续部署完成~( •̀ ω •́ )y

持续集成:指程序员在代码的开发工程中,可以频繁的将代码部署到主干上,并进行自动化测试

持续交付:指在持续集成的基础之上,将代码部署到线上测试环境

持续部署:指在持续交付的基础之上,将要部署的代码实现自动部署

三、钉钉通知构建

 1、安装钉钉通知插件

Dingtalk

devops学习(十一) 构建主分支--触发器--钉钉通知_第3张图片

2、打开钉钉软件获取机器人地址

//获取到的webhook
https://oapi.dingtalk.com/robot/send?access_token=d677b287ca50a1ed3ab23eaf0c78b8b01c76c0826ce2f3741ae4df6ab41fc8a5

3、配置钉钉通知的webhook 

4、添加jenkinsfile 通知配置

post{
  success{
    dingtalk(
         robot: 'jenkins',   
         type: 'MARKDOWN',
         title: "success: ${JOB_NAME}",
         text: ["- 成功构建: ${JOB_NAME}! \n- 版本: ${tag} \n- 持续时间: ${currentBuild.durationString} "]
    )
  }
  failure {
    dingtalk(
         robot: 'jenkins',   
         type: 'MARKDOWN',
         title: "success: ${JOB_NAME}",
         text: ["- 构建失败: ${JOB_NAME}! \n- 版本: ${tag} \n- 持续时间: ${currentBuild.durationString} "]
    )
    }
}

配置说明

post{
  success{    //success  当构建成功时发送
    dingtalk(     //钉钉
         robot: 'jenkins',  // 指定全局配置中钉钉机器人对应配置的id号,通过id号来识别不同的钉钉机器人 
         type: 'MARKDOWN',   //输出的格式
         title: "success: ${JOB_NAME}",  //输出的标题信息
         text: ["- 成功构建: ${JOB_NAME}! \n- 版本: ${tag} \n- 持续时间: ${currentBuild.durationString} "]     //输出的文本信息 这里有一些是直接取jenkins全局变量的值${currentBuild.durationString}
    )
  }
  failure {      //当构建失败后的通知信息
    dingtalk(
         robot: 'jenkins',   
         type: 'MARKDOWN',
         title: "success: ${JOB_NAME}",
         text: ["- 构建失败: ${JOB_NAME}! \n- 版本: ${tag} \n- 持续时间: ${currentBuild.durationString} "]
    )
    }
}

后续如果想要其他全局变量的信息,可以在jenkins流水线语法处查看

devops学习(十一) 构建主分支--触发器--钉钉通知_第4张图片

5、全量配置

pipeline {

  agent any

  environment {
     harborUser  = 'admin'
     harborPasswd  = 'Harbor12345'
     harborAddress = '101.43.4.210:30007'
     harborRepo   = 'repo'
     GIT_COMMIT_HASH = ""
  }
     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() {
              script {
                 GIT_COMMIT_HASH = sh (script: "git log -n 1 --pretty=format:'%H'", returnStdout: true)

                 if ("${tag}" == "origin/master" ){
                    echo '通过jenkins主机构建docker镜像   - SUCCESS'
                    sh """mv ./target/*.jar docker/
                    docker build -t "${JOB_NAME}:latest" ./docker/
                    docker build -t "${JOB_NAME}:${GIT_COMMIT_HASH}" ./docker/
                    docker login ${harborAddress} -u${harborUser} -p${harborPasswd}
                    docker tag ${JOB_NAME}:latest  ${harborAddress}/${harborRepo}/${JOB_NAME}:${GIT_COMMIT_HASH}
                    docker tag ${JOB_NAME}:latest  ${harborAddress}/${harborRepo}/${JOB_NAME}:latest
                    docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:${GIT_COMMIT_HASH}
                    docker push ${harborAddress}/${harborRepo}/${JOB_NAME}:latest
                    """
                  }
                else {
                    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'
                echo "${GIT_COMMIT_HASH}"

                script{
                if ("${tag}" == "origin/master"){
                     echo "${tag}"
                     sshPublisher(publishers: [sshPublisherDesc(configName: 'test', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "helm upgrade -i ${JOB_NAME} --set containers.image=$harborAddress/$harborRepo/${JOB_NAME}:${GIT_COMMIT_HASH} --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)])
                }
                else {
                     echo "${tag}"
                     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)])
                }
               }
           }
         }
       }



    post{
      success{
        dingtalk(
             robot: 'jenkins',
             type: 'MARKDOWN',
             title: "success: ${JOB_NAME}",
             text: ["- 成功构建: ${JOB_NAME}! \n- 版本: ${tag} \n- 持续时间: ${currentBuild.durationString} "]
        )
      }
      failure {
        dingtalk(
             robot: 'jenkins',
             type: 'MARKDOWN',
             title: "success: ${JOB_NAME}",
             text: ["- 构建失败: ${JOB_NAME}! \n- 版本: ${tag} \n- 持续时间: ${currentBuild.durationString} "]
        )
        }
    }
    }

你可能感兴趣的:(devops,学习,devops,jenkins,运维,容器)