一.pipeline是什么?
pipeline是部署流水線(Deployment pipeline),指從軟件版本控制庫到用戶手中這一過程的自動化表現形式。
Jenkins 1.x只能通過界面手動配置來配置描述過程,讓Jenkins完成任務,例如選擇自由風格的項目,通過選項等操作進行配置,讓jenkins可以下載代碼、編譯構建、然后部署到遠程服務器上。
而Jenkins 2.x終於支持pipeline as code了,可以通過代碼來描述部署流水線,還是同樣的功能,部分操作通過代碼配置運行后,也會在界面里顯示出來。
Pipeline 簡而言之,就是一套運行於Jenkins上的工作流框架,將原本獨立運行於單個或者多個節點的任務連接起來,實現單個任務難以完成的復雜流程編排與可視化。
pipeline的功能由pipeline插件提供,有的jenkins會自帶,若沒有則需要安裝。
使用代碼而不是UI的意義在於:
- 更好的版本化:將pipeline提交到版本庫中進行版本控制
- 更好地協作:pipeline的每次修改對所有人都是可見的。除此之外,還可以對pipeline進行代碼審查
- 更好的重用性:手動操作沒法重用,但是代碼可以重用
二.jenkinsfile是什么
Jenkinsfile就是一個文本文件,里面記錄着邏輯,在執行jenkins job的時候,會讀取這個文件按照上面的描述來進行各種操作。像Dockerfile之於Docker,Playbook之於Ansible。
Jenkinsfile有2種方式,可以直接在web配置中進行編寫,這樣只適合臨時項目調試或簡短的內容。
更多的是將pipeline的腳本在遠程倉庫上進行管理,這里配置遠程倉庫地址,讓job每次執行的時候拉取這個項目,然后執行其中的某個文件。
可以將腳本放到一個倉庫集中管理,也可以放到每個項目中,和代碼在一起進行維護,具體方式可以根據公司情況來安排。
三.pipeline語法選擇
Jenkins pipeline有2種語法:腳本式(Scripted)語法和聲明式(Declar-ative)語法。pipeline插件從2.5版本開始,才同時支持兩種格式的語法,推薦使用聲明式語法,它的使用人群更廣泛,也更好表達維護。
Jenkins團隊在一開始實現Jenkins pipeline時,Groovy語言被選擇作為基礎來實現pipeline。所以,在寫pipeline腳本時,就是在寫groovy腳本。但區別是,pipeline是在上面封裝了一層,需要用固定格式,jenkins才可以識別。
pipeline {
agent any
stages {
stage('pull') {
steps {
git branch: 'master', credentialsId: 'jenkins', url: 'http://代碼'
echo '開始拉取代碼'
}
}
}
}
按照格式編寫,在其中可以加入groovy的腳本,例如循環、判斷、添加變量等等。這樣的好處是降低了學習成本,例如上面的下載代碼的git指令,用groovy單純實現就如下方式。
"git clone http://代碼".execute().text
那如果根據不同分支拉取、配置秘鑰等操作,這里還要再增加切換的操作,要單獨學習groovy相關的知識。
四.腳本式和聲明式
腳本式語法比較靈活,編寫清晰簡單,groovy的語法可以直接使用套用,例如直接定義個變量。
node () {
def branch = 'test'
stage 'pull'
sh " echo 拉取代碼"
stage 'build'
sh " echo 構建代碼"
}
聲明式的語法在內容多的時候會更清晰
pipeline {
agent any
stages {
stage('pull') {
steps {
echo '拉取代碼'
}
}
stage('build') {
steps {
echo '構建代碼'
}
}
}
}
對比2個例子,可以發現聲明式好像才是復雜的那個。但其實在后續使用中,可以發現腳本式會比較凌亂,就像沒用函數的感覺,沒有一個標准和結構。腳本式和聲明式只是語法上有些區別,對於方法和功能大多都是一樣支持的。
五.插件與pipeline
pipeline基本結構決定的是pipeline整體流程,stage代表每個階段,但實際具體做操作的是pipeline中的每一個步驟。步驟是pipeline中已經不能再拆分的最小操作。像echo執行echo指令,sh執行shell命令。
那是不是說,Jenkins pipeline內置了所有可能需要用到的步驟呢?顯然沒有必要,因為很多步驟可能永遠不會用到。
就像自由Jenkins的插件,安裝各種插件后,可以在自由風格的項目里,看到多出來的選項,進行配置。pipeline也是如此,安裝某些插件后,就可以在pipeline中用代碼調用插件了。