1. 程式人生 > >Jenkins Pipeline 專案持續整合互動實踐路徑

Jenkins Pipeline 專案持續整合互動實踐路徑

Jenkins Pipleline外掛介紹


Jenkins 2.x的精髓是Pipeline as Code,是幫助Jenkins實現CI到CD轉變的重要角色。什麼是Pipeline,簡單來說,就是一套運行於Jenkins上的工作流框架,將原本獨立運行於單個或者多個節點的任務連線起來,實現單個任務難以完成的複雜釋出流程。Pipeline的實現方式是一套Groovy DSL,任何釋出流程都可以表述為一段Groovy指令碼,並且Jenkins支援從程式碼庫直接讀取指令碼,從而實現了Pipeline as Code的理念。

Pipeline的幾個基本概念:

  • Stage: 階段,一個Pipeline可以劃分為若干個Stage,每個Stage代表一組操作。注意,Stage是一個邏輯分組的概念,可以跨多個Node。
  • Node: 節點,一個Node就是一個Jenkins節點,或者是Master,或者是Agent,是執行Step的具體執行期環境。
  • Step: 步驟,Step是最基本的操作單元,小到建立一個目錄,大到構建一個Docker映象,由各類Jenkins Plugin提供。

Jenkins Pipleline外掛:

Jenkins Pipeline語法參考

以下是完整的Jenkins Pipeline語法參考卡。 當然,當您新增外掛或外掛更新時,新的流水線指令碼元素將在您的環境中可用。 Pipeline程式碼段生成器和UI將自動新增這些和任何相關的幫助文字,以便您知道如何使用它們!

Basics

Advanced

File System

Flow Control

Docker



Jenkins Pipleline 指令碼示例

stage 'build'
node {
     git 'https://github.com/cloudbees/todo-api.git'
     withEnv(["PATH+MAVEN=${tool 'm3'}/bin"]) {
          sh "mvn -B –Dmaven.test.failure.ignore=true clean package"
     }
     stash excludes: 'target/', includes: '**', name: 'source'
}
stage 'test'
parallel 'integration': { 
     node {
          unstash 'source'
          withEnv(["PATH+MAVEN=${tool 'm3'}/bin"]) {
               sh "mvn clean verify"
          }
     }
}, 'quality': {
     node {
          unstash 'source'
          withEnv(["PATH+MAVEN=${tool 'm3'}/bin"]) {
               sh "mvn sonar:sonar"
          }
     }
}
stage 'approve'
timeout(time: 7, unit: 'DAYS') {
     input message: 'Do you want to deploy?', submitter: 'ops'
}
stage name:'deploy', concurrency: 1
node {
     unstash 'source'
     withEnv(["PATH+MAVEN=${tool 'm3'}/bin"]) {
          sh "mvn cargo:deploy"
     }
}
注:m3表示Jenkins配置的maven名稱。

Jenkins Pipeline Docker指令碼示例

Docker Pipeline外掛公開了一個Docker全域性變數,它為普通的Docker操作提供DSL,只需要在執行步驟的執行程式上使用一個Docker客戶端(在您的節點步驟中使用一個標籤來定位啟用Docker的代理)。

預設情況下,Docker全域性變數連線到本地Docker守護程式。 您可以使用docker.withServer步驟連線到遠端Docker主機。 影象步驟為特定的Docker影象提供控制代碼,並允許執行其他與影象相關的其他步驟,包括image.inside步驟。 內部步驟將啟動指定的容器並在該容器中執行一個步驟:

示例1:

docker.image('maven:3.3.3-jdk8').inside('-v ~/.m2/repo:/m2repo') {
     sh 'mvn -Dmaven.repo.local=/m2repo clean package'
}
node{  
  // 程式碼檢出
  stage('get Code') {
    git credentialsId: 'git-credentials-id', url: 'http://192.168.19.250/ufleet/uflow.git'
  }
  
    // 映象中進行單元測試
  stage('unit testing'){ 
    // 啟動golnag:1.7並在golang內編譯程式碼
    docker.image('golang:1.7').inside {
      sh './script/unittest.sh'
    }
  }
  
  // 映象中程式碼構建
  stage('Build'){    

    def confFilePath = 'conf/app.conf'
    def config = readFile confFilePath

    writeFile file: confFilePath, text: config
    
    // 啟動golnag:1.7並在golang內編譯程式碼
    docker.image('golang:1.7').inside {
      sh './script/build.sh'
    }
  }
  
  // 編譯映象並push到倉庫
  def imagesName = '192.168.18.250:5002/ufleet/uflow:v0.9.1.${BUILD_NUMBER}'  
  stage('Image Build And Push'){
    docker.withRegistry('http://192.168.18.250:5002', 'registry-credentials-id') {
      docker.build(imagesName).push()
    }
  }
  
  // 啟動剛執行的容器
  stage('deploy iamegs'){    
    // 需要刪除舊版本的容器,否則會導致端口占用而無法啟動。
    try{
      sh 'docker rm -f cicdDemo'
    }catch(e){
        // err message
    }
    docker.image(imagesName).run('-p 9091:80 --name cicdDemo') 
  }
}


更多使用方法請參考Jenkins Pipeline docker語法。

另外可以藉助Pipeline Syntax來生成基本的指令碼:


Jenkins Pipeline war 包部署示例

Pipeline通過增強stage原語來提供此功能。 例如,一個階段可以具有一個定義的併發級別,以指示在任何時候只有一個執行緒應該在該階段中執行。 這實現了執行部署的期望狀態,就像執行一樣快。
參考:https://jenkins.io/doc/book/pipeline-as-code/

 stage name: 'Production', concurrency: 1
 node {
     unarchive mapping: ['target/x.war' : 'x.war']
     deploy 'target/x.war', 'production'
     echo 'Deployed to http://localhost:8888/production/'
 }

本博參考文章:

更多閱讀Jenkinsfile參考: