pipeline&jenkins

1:部署完成之后检测pod状态,获取同名pod的个数,一个就执行检测,多个就直接报失败,设置超时时间内检测

stage("get pod and test to rollouting"){
        steps{
            script {
                def namespace="${params.namespace}";
                def depName="dep-${params.moduleCode}";
                timeout(240) {
                   while(true) {
                     def result = sh(script: "kubectl get pod -n " +namespace+ " --kubeconfig=/root/.kube/dev-config  |grep " +depName+"-*|wc -l", returnStdout:true).trim()
                     sh "echo ${result}"
                        if("${result}" == "1"){
                           sleep (10)
                           sh "kubectl get pod -n " +namespace+ " --kubeconfig=/root/.kube/dev-config |grep " +depName+ " > appname.txt"
                           def data = readFile(file: "appname.txt")
                           println data
                           def list =data.split(' ')
                           sh "kubedog  rollout track -n "  +namespace+ " pod " +list[0]+ " --kube-config=/root/.kube/dev-config && kubectl logs --since=2m " +list[0]+ " -n " +namespace+ " --kubeconfig=/root/.kube/dev-config  || kubectl  rollout undo deployment/"+depName+ " -n "  +namespace+ " --kubeconfig=/root/.kube/dev-config"
                           sh "break"
                        }else{
                           sleep (10)
                           def result1 = sh(script: "kubectl get pod -n " +namespace+ " --kubeconfig=/root/.kube/dev-config |grep " +depName+"-*|wc -l", returnStdout:true).trim()
                           sh "echo ${result1}"
                           if("${result1}" == "1"){
                               sh "kubectl get pod -n " +namespace+ " --kubeconfig=/root/.kube/dev-config |grep " +depName+ " > appname.txt"
                               def data = readFile(file: "appname.txt")
                               println data
                               def list =data.split(' ')
                               sh "kubedog  rollout track -n "  +namespace+ " pod " +list[0]+ " --kube-config=/root/.kube/dev-config && kubectl logs --since=2m " +list[0]+ " -n " +namespace+ " --kubeconfig=/root/.kube/dev-config ||  kubectl  rollout undo deployment/"+depName+ " -n "  +namespace+ " --kubeconfig=/root/.kube/dev-config"
                               sh "break"
                           }else{
                               sh "echo '继续检测中.....'"
                           }
                            
                        }
                    }
                }  
            } 
        }
    }

2:选分支拉取代码

stage("git pull code") {
  steps {
    //clear workspace
    cleanWs()
    script {
      //pull code
      print "repoBranch : ${params.repoBranch}"
      checkout([$class: 'GitSCM', branches: [[name: "${params.repoBranch}"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${params.repoCred}", url: "${params.repoUrl}"]]])
    }
  }
  }

3:kubernetes之服务回滚

stage("rollout pod"){
        steps{
            script{
                def namespace="${params.namespace}";
                def controller="${params.controller}";
                def depName="${params.depName}";
                sh "kubectl get " +controller+  " -n " +namespace+ " |grep " +depName+ " > controllerName.txt"
                def data = readFile(file: "controllerName.txt")
                println data
                def list =data.split(' ')
                sh "kubectl  rollout undo " +controller+"/"+list[0]+ " -n "  +namespace
                //sh "kubedog  rollout track -n "  +namespace+ " " +controller+ " " +list[0]+ " && echo 'undo start success' || echo 'undo start faild'"
                
            }
        }
    }

4:gradle结合sonar编译加扫描

stage("gradle and sonar"){
        steps{
              script {
                  def timeStamp=new Date().format("yyyy-MM-dd");
                  def targetDir="${WORKSPACE}/${params.targetDir}";
                  dir(targetDir){
                      withSonarQubeEnv('sonarqube-jenkins') {
                          print "repoBranch : ${params.repoBranch}"
                          sh "gradle clean build --parallel -x test sonarqube -Dsonar.projectKey=${params.projectKey} -Dsonar.projectName=${params.projectKey} -Dsonar.sourceEncoding=UTF-8 -Dsonar.analysis.buildNumber=${env.BUILD_NUMBER} -Dsonar.analysis.jobName=${env.JOB_NAME} -Dsonar.java.binaries=build/classes -Dsonar.analysis.isFortify=true -Dsonar.projectDate="+timeStamp
                      }
                  }
            }
     }
}

5:docker镜像编译

pipeline {
    agent any
    environment {
        def tag = sh(script: "echo `date +%s`", returnStdout: true).trim()
    }
    stage("docker build"){
        steps{
                //def IMAGE_URL="10.10.0.100:8081/test-docker-dev/${params.IMAGE_NAME}:${tag};
                sh "cd ${WORKSPACE}/ && docker build -t 10.10.0.100:8081/test-docker-dev/${params.IMAGE_NAME}:${tag} -f Dockerfile ."
                sh "docker push  10.10.0.100:8081/test-docker-dev/${params.IMAGE_NAME}:${tag}"
        }
    }
}

6:灵活部署yaml资源,如存在就打上原始标注,不存在就部署并打上标注,方便后期回滚

stage("k8s build"){
        steps{
            script{
                def filePath="${params.ymlPath}";
                def namespace="${params.namespace}";
                def depName="${params.depName}";
                def imageUrl="${params.imageUrl}";
               def imageTag="${params.imageTag}";
                //def artifactVersion="${params.artifactVersion}";
                def imageName="${params.imageName}"
                def namesp="devops-test"
                def nFile="${WORKSPACE}/management-deployment-svc.yaml"
                def data = readFile(file: filePath)
                data=data.replaceAll("imageUrl",imageUrl+"/"+imageName)
                data=data.replaceAll("imageTag",imageTag)
                data=data.replaceAll("depName",depName)
                //data=data.replaceAll("artifactVersion",artifactVersion)
                println(data)
                writeFile(file: nFile, text: data)
                def resulting = sh(script: "kubectl annotate deployment/"+depName+ " kubernetes.io/change-cause=image-tag:initial -n " +namespace , returnStatus: true)
                if ("${resulting}" == 0){
                    sh "kubectl annotate deployment/"+depName+ " kubernetes.io/change-cause=image-tag:initial -n " +namespace
                    sh "kubectl apply -f " +nFile
                    sh "kubectl annotate deployment/"+depName+ " kubernetes.io/change-cause=image-tag:"+imageTag+ " -n " +namespace
                }else{
                    sh "kubectl apply -f " +nFile
                    sh "kubectl annotate deployment/"+depName+ " kubernetes.io/change-cause=image-tag:"+imageTag+ " -n " +namespace
                }
            }
        }
    }

7:maven结合sonar扫描

stage("mavne and sonar"){
        steps{
            withSonarQubeEnv('sonarqube-jenkins') {
                sh "mvn -U -s ${params.mavenXml} -f ${params.pomXml} clean compile -P dev -Dmaven.test.skip=true sonar:sonar -Dsonar.projectKey=${params.projectKey} -Dsonar.projectName=${params.projectKey} -Dsonar.sourceEncoding=UTF-8 -Dsonar.java.binaries=target/ -Dsonar.exclusions=src/test/** -Dsonar.sources=src/ -Dsonar.language=java    -Dsonar.analysis.jobName=${env.JOB_NAME} -Dsonar.analysis.buildNumber=${env.BUILD_NUMBER} -Dsonar.analysis.isFortify=true"
            }
            script {
                timeout(1) {
                  sleep(5)
                  def qg = waitForQualityGate()
                  if (qg.status != 'OK') {
                      error "未通过Sonarqube的代码质量阈检查,请及时修改!failure: ${qg.status}"
                  }
                }
            } 
        }
}

8:npm,maven,gradle,python四种编译结合,传参选择

stage("gradle or maven or npm or python"){
             steps{
                 script {
                     if("${params.compileType}" == "maven"){
                         def targetDir="${WORKSPACE}/${params.targetDir}";
                         dir(targetDir){
                             if("${params.needSonarScan}" == "no"){
                                 if ("${params.settingXml}" == "" && "${params.pomXml}" == "") {
                                        withMaven(globalMavenSettingsConfig: "${env.mavenSettingsId}") {
                                     sh "mvn -U clean package -Dmaven.test.skip=true"
                                     }
                                 }else if("${params.settingXml}" != "" && "${params.pomXml}" == ""){
                                        withMaven(globalMavenSettingsConfig: "${env.mavenSettingsId}") {
                                     sh "mvn -U -s ${params.settingXml} clean package -Dmaven.test.skip=true"
                                     }
                                 }else if("${params.settingXml}" == "" && "${params.pomXml}" != ""){
                                        withMaven(globalMavenSettingsConfig: "${env.mavenSettingsId}") {
                                     sh "mvn -U -f ${params.pomXml} clean package -Dmaven.test.skip=true"
                                     }
                                 }else {
                                        withMaven(globalMavenSettingsConfig: "${env.mavenSettingsId}") {
                                     sh "mvn -U -s ${params.settingXml} -f ${params.pomXml} clean package -Dmaven.test.skip=true"
                                     }
                                 }
                             }else{
                                 withSonarQubeEnv('sonarqube-jenkins') {
                                     if ("${params.settingXml}" == "" && "${params.pomXml}" == "") {
                                            withMaven(globalMavenSettingsConfig: "${env.mavenSettingsId}") {
                                         sh "mvn -U clean package -Dmaven.test.skip=true sonar:sonar -Dsonar.projectKey=${params.moduleCode} -Dsonar.projectName=${params.moduleCode} -Dsonar.sourceEncoding=UTF-8 -Dsonar.java.binaries=target/ -Dsonar.exclusions=src/test/** -Dsonar.sources=src/ -Dsonar.language=java    -Dsonar.analysis.jobName=${env.JOB_NAME} -Dsonar.analysis.buildNumber=${env.BUILD_NUMBER} -Dsonar.analysis.isFortify=true"
                                         }
                                     }else if("${params.settingXml}" != "" && "${params.pomXml}" == ""){
                                            withMaven(globalMavenSettingsConfig: "${env.mavenSettingsId}") {
                                         sh "mvn -U -s ${params.settingXml} clean package -Dmaven.test.skip=true sonar:sonar -Dsonar.projectKey=${params.moduleCode} -Dsonar.projectName=${params.moduleCode} -Dsonar.sourceEncoding=UTF-8 -Dsonar.java.binaries=target/ -Dsonar.exclusions=src/test/** -Dsonar.sources=src/ -Dsonar.language=java    -Dsonar.analysis.jobName=${env.JOB_NAME} -Dsonar.analysis.buildNumber=${env.BUILD_NUMBER} -Dsonar.analysis.isFortify=true"
                                         }
                                     }else if("${params.settingXml}" == "" && "${params.pomXml}" != ""){
                                            withMaven(globalMavenSettingsConfig: "${env.mavenSettingsId}") {
                                         sh "mvn -U -f ${params.pomXml} clean package -Dmaven.test.skip=true sonar:sonar -Dsonar.projectKey=${params.moduleCode} -Dsonar.projectName=${params.moduleCode} -Dsonar.sourceEncoding=UTF-8 -Dsonar.java.binaries=target/ -Dsonar.exclusions=src/test/** -Dsonar.sources=src/ -Dsonar.language=java    -Dsonar.analysis.jobName=${env.JOB_NAME} -Dsonar.analysis.buildNumber=${env.BUILD_NUMBER} -Dsonar.analysis.isFortify=true"
                                         }
                                     }else {
                                            withMaven(globalMavenSettingsConfig: "${env.mavenSettingsId}") {
                                         sh "mvn -U -s ${params.settingXml} -f ${params.pomXml} clean package -Dmaven.test.skip=true sonar:sonar -Dsonar.projectKey=${params.moduleCode} -Dsonar.projectName=${params.moduleCode} -Dsonar.sourceEncoding=UTF-8 -Dsonar.java.binaries=target/ -Dsonar.exclusions=src/test/** -Dsonar.sources=src/ -Dsonar.language=java    -Dsonar.analysis.jobName=${env.JOB_NAME} -Dsonar.analysis.buildNumber=${env.BUILD_NUMBER} -Dsonar.analysis.isFortify=true"
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
                 script {
                     if("${params.compileType}" == "npm"){
                         def targetDir="${WORKSPACE}/${params.targetDir}";
                         dir(targetDir){
                             sh "npm install --unsafe-perm=true --allow-root --registry=https://registry.npm.taobao.org && npm run build:prod"
                         }
                     }
                 }
                 script {
                     if("${params.compileType}" == "gradle"){
                         def targetDir="${WORKSPACE}/${params.targetDir}";
                         dir(targetDir){
                             if("${params.needSonarScan}" == "no"){
                                 print "repoBranch : ${params.repoBranch}"
                                 sh "gradle clean build --parallel -x test"
                             }else{
                                 withSonarQubeEnv('sonarqube-jenkins') {
                                     print "repoBranch : ${params.repoBranch}"
                                     sh "gradle clean build --parallel -x test sonarqube -Dsonar.projectKey=${params.moduleCode} -Dsonar.projectName=${params.moduleCode} -Dsonar.sourceEncoding=UTF-8  -Dsonar.branch.name=${params.repoBranch} -Dsonar.analysis.buildNumber=${env.BUILD_NUMBER} -Dsonar.analysis.jobName=${env.JOB_NAME} -Dsonar.java.binaries=build/classes -Dsonar.analysis.isFortify=true"
                                 }
                             }
                         }

                     }
                 }
                 script {
                     if("${params.compileType}" == "python"){
                         def targetDir="${WORKSPACE}/${params.targetDir}";
                         dir(targetDir){
                             sh "pwd && ls -l"
                             sh "source /etc/profile && pyinstaller -F httpsrv.py"
                         }
                     }
                 }
                 script{
                     if("${params.needSonarScan}" == "yes"){
                         timeout(1) {
                             sleep(5)
                             def qg = waitForQualityGate()
                             if (qg.status != 'OK') {
                                 error "未通过Sonarqube的代码质量阈检查,请及时修改!failure: ${qg.status}"
                             }
                         }
                     }
                 }
             }
         }

9:kubernetes部署最终版

stage("kubernetes yaml build"){
        steps{
            script{
                def ymlPath="${params.ymlPath}";
                def namespace="${params.namespace}";
                def appName="${params.appName}";
                def depName="${params.depName}";
                def appPort="${params.appPort}";
                def cmName="${params.cmName}";
                def svcName="${params.svcName}";
                def svcPort="${params.svcPort}";
                def imageName="${params.imageName}";
                def imageTag="${params.imageTag}";
                def envKubeconfig="${params.envKubeconfig}";
                def nFile="${WORKSPACE}/deployment-svc.yaml"
                def data = readFile(file: ymlPath)
              data=data.replaceAll("#namespace#",namespace)
              data=data.replaceAll("#appName#",appName)
              data=data.replaceAll("#depName#",depName)
              data=data.replaceAll("#appPort#",appPort)
              data=data.replaceAll("#cmName#",cmName)
              data=data.replaceAll("#svcName#",svcName)
              data=data.replaceAll("#svcPort#",svcPort)
              data=data.replaceAll("#imageName#",imageName)
              data=data.replaceAll("#imageTag#",imageTag)
                println(data)
                writeFile(file: nFile, text: data)
                def resulting = sh(script: "kubectl get deployment " +depName+ " -n " +namespace+ " --kubeconfig="+envKubeconfig , returnStatus: true)
                sh "echo ${resulting}"
                if ("${resulting}" == "0"){
                    sh "kubectl annotate deployment/"+depName+ " kubernetes.io/change-cause=image-tag:initial -n " +namespace+ " --kubeconfig="+envKubeconfig
                    sh "kubectl apply -f " +nFile+ " --kubeconfig="+envKubeconfig
                    sh "curl -X PUT -u user:passwd -T ${WORKSPACE}/deployment-svc.yaml  https://10.10.10.10:8081/artifactory/test-docker-dev/"+imageName+"/"+imageTag+"/"
                    sh "kubectl annotate deployment/"+depName+ " kubernetes.io/change-cause=image-tag:"+imageTag+ " -n " +namespace+ " --kubeconfig="+envKubeconfig
                }else{
                    sh "kubectl apply -f " +nFile+ " --kubeconfig="+envKubeconfig   #envKubeconfig是不同环境的config文件,可以对不同环境操作
                    sh "curl -X PUT -u user:passwd -T ${WORKSPACE}/deployment-svc.yaml  https://10.10.10.10:8081/artifactory/test-docker-dev/"+imageName+"/"+imageTag+"/"     #每次部署完,将yaml文件传入jfrog保存,方便下次根据yaml指定镜像名镜像标签回滚
                    sh "kubectl annotate deployment/"+depName+ " kubernetes.io/change-cause=image-tag:"+imageTag+ " -n " +namespace+ " --kubeconfig="+envKubeconfig     #每次部署完成,给deployment打上标签,方便回滚以及知道当前版本
                }
            }
        }
    }


10:K8S服务回滚和检测pod状态

stage("New kubernetes server building"){
    steps{
        script{
            def environment = "${params.environment}"
            def url = "${env.DEVOPS_URL}/rTaskRunRecord/getYamlAndRecordVariable"
            def jsonParamsHttp = [:];
            jsonParamsHttp.put("env", environment);
            jsonParamsHttp.put("taskId", "${env.JOB_NAME}");
            jsonParamsHttp.put("buildNumber", "${env.BUILD_NUMBER}");
            jsonParamsHttp.put("pipelineId", "${env.pipelineId}");
            def postResult = httpRequestStage(url,jsonParamsHttp);
            serYamlData = jsonParseText(postResult.result).data

            sh "touch ${WORKSPACE}/server.yaml;echo '@depData@' > ${WORKSPACE}/server.yaml"
            def depYmlPath="${WORKSPACE}/server.yaml"
            def nFile="${WORKSPACE}/deployment.yaml"
            def data = readFile(file: depYmlPath)
            data=data.replaceAll("@depData@",serYamlData)
            writeFile(file: nFile, text: data)
            sh "cat " +nFile


            def depName = null
            def namespace = null
            def yamlContent = serYamlData
            def yamlList = yamlConvertToList(yamlContent)
            if(null != yamlList){
                for(def map : yamlList){
                    def kind = map.get("kind")
                    if("Deployment" == kind){
                        def metadata = (Map)map.get("metadata")
                        depName = metadata.get("name")
                        namespace = metadata.get("namespace")
                        break
                    }
                }
            }
            println("==================================================")
            println("部署检测所需参数: depName=" + depName + ", namespace=" + namespace)
            println("==================================================")
            if(null == depName || null == namespace){
                error "解析部署包名与命名空间失败, 请检查yaml解析脚本"
            }


            sh "kubectl apply -f " +nFile+ " --validate=false --kubeconfig=/root/.kube/" +environment+ "-config"
            println("等待60s后, 开始检测服务")
            sleep 60



            def i=0;
            while(true) {
                if(i>=10){      
                    sh """
                        echo "服务启动失败,开始回滚........"
                        kubectl rollout undo deployment ${depName} -n ${namespace} \
                        --kubeconfig=/root/.kube/${environment}-config 
                        echo "服务回滚完成"
                        """
                    error "服务启动失败,完成回滚"
                }
                i++;
                def result = sh(script: "kubectl get pod -n  "+namespace+"  --kubeconfig=/root/.kube/"+environment+"-config  |grep " +depName+"-[0-9/a-z][0-9/a-z][0-9/a-z][0-9/a-z][0-9/a-z][0-9/a-z][0-9/a-z]* |wc -l", returnStdout:true).trim()
                sh "echo ${result}"
                if("${result}" == "1"){
                    sleep 10
                    sh "kubectl get pod -n  "+namespace+"  --kubeconfig=/root/.kube/"+environment+"-config |grep " +depName+ " > appname.txt"
                    def fileData = readFile(file: "appname.txt")
                    println fileData
                    def list =fileData.split(' ')
                    sh "kubedog  rollout track -n  "+namespace+"  pod " +list[0]+ " --kube-config=/root/.kube/"+environment+"-config && kubectl logs --since=4m " +list[0]+ " -n  "+namespace+"  --kubeconfig=/root/.kube/"+environment+"-config  || kubectl  rollout undo deployment/"+depName+ " -n  "+namespace+"  --kubeconfig=/root/.kube/"+environment+"-config"
                    break;
                }else{
                    sleep 10
                    sh "kubectl get pod -n  "+namespace+"  --kubeconfig=/root/.kube/"+environment+"-config |grep " +depName
                    def result1 = sh(script: "kubectl get pod -n  "+namespace+"  --kubeconfig=/root/.kube/"+environment+"-config |grep " +depName+"-[0-9/a-z][0-9/a-z][0-9/a-z][0-9/a-z][0-9/a-z][0-9/a-z][0-9/a-z]* |wc -l", returnStdout:true).trim()
                    sh "echo ${result1}"
                    if("${result1}" == "1"){
                        sh "kubectl get pod -n  "+namespace+"  --kubeconfig=/root/.kube/"+environment+"-config |grep " +depName+ " > appname.txt"
                        def fileData = readFile(file: "appname.txt")
                        println fileData
                        def list =fileData.split(' ')
                        sh "kubedog  rollout track -n  "+namespace+"  pod " +list[0]+ " --kube-config=/root/.kube/"+environment+"-config && kubectl logs --since=4m " +list[0]+ " -n  "+namespace+"  --kubeconfig=/root/.kube/"+environment+"-config ||  kubectl  rollout undo deployment/"+depName+ " -n  "+namespace+"  --kubeconfig=/root/.kube/"+environment+"-config"
                        break;
                    }else{
                        sh "echo '继续检测中.....'"
                    }
                }
            }
        }
    }
}

11:一键导入变量并引用yaml文件

stage("envsubst kubernetes yaml build"){
        steps{
            script{
              def replicas="${params.replicas}";
                sh "curl -O -u user:passwd https://10.10.10.10:8081/artifactory/test-docker-dev/yaml/dep-svc-sso-app.yaml"
                sh " envsubst < dep-svc-sso-app.yaml | kubectl apply -f -  --kubeconfig=/root/.kube/dev-config"
            }
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

推荐阅读更多精彩内容