通過pipeline實現jenkins的ci/cd功能


pipeline是基於groove進行實現的,不過從jenkins官方的說明中,pipeline分為腳本式和聲明式,參見鏈接。經過對兩種的比較,個人比較偏向腳本式的方法。也就是

Jenkinsfile (Scripted Pipeline)

node {  
    stage('Build') { 
        // 
    }
    stage('Test') { 
        // 
    }
    stage('Deploy') { 
        // 
    }
}

 因為聲明式的方法用起來不方便,還有就是語句執行的結果不知道怎么賦值到變量中去。

如下簡單介紹下現有的jenkinsfile,由於能力有限,如有錯誤,請指正。

1.由於是部署的spring-cloud的項目,會依賴maven環境,所以使用了dockerfile的多步編譯。

 1 FROM maven:3-alpine as builder
 2 ADD . /build/
 3 WORKDIR /build
 4 COPY ./settings.xml   /root/.m2/
 5 COPY ./repository   /root/.m2/
 6 RUN   mvn  -DskipTests clean install package -q -U -Ppro
 7 
 8 
 9 
10 FROM frolvlad/alpine-oraclejdk8:slim
11 WORKDIR /home/
12 ENV LC_ALL=en_US.UTF-8\
13     LANG=en_US.UTF-8\
14     JAVA_OPTS="-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8 -Djava.security.egd=file:/dev/./urandom "
15 
16 RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
17 RUN apk add --no-cache tzdata \
18     && ln -sf /usr/share/zoneinfo/Asia/Chongqing /etc/localtime \
19     && echo "Asia/Chongqing" > /etc/timezone \
20     &&rm -rf /var/cache/apk/* /tmp/* /var/tmp/* $HOME/.cache ## 清除緩存
21 
22 
23 COPY --from=builder /build/target/x.jar /home/app.jar
24 EXPOSE 19090
25 ENTRYPOINT [ "sh", "-c", "java -server -Xms2048m -Xmx2048m $JAVA_OPTS -jar app.jar --spring.profiles.active=test" ]

 

 多步編譯完成之后,編寫pipeline文件

node('xx-jnlp'){
          def  DockerTestImage = ''
          def  DockerProductImage = ''
          def  REPOSITORY = 'imagename'


      stage('clone git'){
        echo "BRANCH IS :${BRANCH}"
        checkout([$class: 'GitSCM', branches: [[name: "${BRANCH}"]],
        userRemoteConfigs: [[url: 'git@x.x.x.x:java/x.git',credentialsId:'xxxxxxxxxxxxxxxx']]
        ])
        echo "hello ${DockerTestImage}"
        echo "hello ${BRANCH}"
      }
      
      stage('init'){
        script {

            build_tag = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
            GIT_COMMIT=sh(script:"echo ${build_tag} | cut -c 1-8", returnStdout:true).trim()
            LOCALDATE=sh(script:"date '+%F'",returnStdout:true).trim()
            VERSION = "V1-${LOCALDATE}-${GIT_COMMIT}"
          }
      }
      stage('Build master') {
        if (env.BRANCH_NAME == 'master'){
          echo "3.Build Docker Image Stage for master"
          sh "ls -l /root/.m2"
          echo "ls -l /root/.m2"
          sh "cp /root/.m2/settings.xml /root/.m2/repository . -rfp"
          sh "docker build -f Dockerfile_product_k8s -t ${REPOSITORY} . "

        }
      }
      stage('Build test'){
        if (env.BRANCH_NAME != 'master'){
          echo "3.Build Docker Image Stage for test"
          sh "ls -l /root/.m2"
          echo "ls -l /root/.m2"
          sh "cp /root/.m2/settings.xml /root/.m2/repository . -rfp"
          sh "docker build -f Dockerfile_test_k8s -t ${REPOSITORY}  . "
        }
      }
      stage('Push to master') {
        if(env.BRANCH_NAME == 'master'){
          echo "4.Push Docker Image master Stage"
          withCredentials([usernamePassword(credentialsId: 'registry.cn-hangzhou.aliyuncs.com', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]){
            sh "docker login --username=${dockerHubUser} --password=${dockerHubPassword} registry.cn-hangzhou.aliyuncs.com"
            sh "docker tag  ${REPOSITORY}  ${DockerProductImage}:${VERSION}"
            sh "docker push  ${DockerProductImage}:${VERSION}"

          }
          
          

        }
      }


      stage('Push to test'){
        if(env.BRANCH_NAME != 'master'){
          echo "4.Push Docker Image test Stage"
          withCredentials([usernamePassword(credentialsId: 'registry.cn-hangzhou.aliyuncs.com', passwordVariable: 'dockerHubPassword', usernameVariable: 'dockerHubUser')]){
            sh "docker login --username=${dockerHubUser} --password=${dockerHubPassword} registry.cn-hangzhou.aliyuncs.com"
            sh "docker tag  ${REPOSITORY}  ${DockerTestImage}:${VERSION}"
            sh "docker tag  ${REPOSITORY}  ${DockerTestImage}:latest"
            sh "docker push  ${DockerTestImage}:${VERSION}"

          }
        }
      }
      stage('YAML') {
          echo "5. Change YAML File Stage"
        
      }
      stage('Deploy') {

          echo "6. Deploy Stage"
      }


}

 說明:

1、node后面指定的是k8s slave節點的tag名稱,當運行此任務時k8s會新建節點,在此節點上運行節點,並執行dockerfile,完成打包和生成鏡像的功能。

2、git clone stage是復制代碼到slave節點

3、init stage 初始化變量

4、build stage根據不同的代碼分支執行不同的創建命令步驟,並完成不同的鏡像文件創建

5、push stage將創建好的鏡像推送到服務器上。

6、發布的命令暫時使用的阿里雲的觸發器來實現的。

如上。

 

遇到過的坑。

1、如果使用聲明式的流水線,會發現bash變量的值不是太好賦值到變量中,而只能使用parameter實現,不能滿足要求。后面忍痛切換到node方式。

2、由於node和pipeline用法上有很多區別,所以切換的時候注意小心小心。

3、由於docker的編譯環境和鏡像生成環境是使用不同的鏡像,所以生成后的jar包如果不使用多步編譯只能stash到生成鏡像的docker鏡像中,會比較麻煩。目前使用的dockerfile的多步編譯,會好些。但是每次編譯都會下載網絡依賴,會耗時比較久。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM