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 指令碼示例
注:m3表示Jenkins配置的maven名稱。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" } }
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參考: