Jenkins - Pipeline詳解

1 - Jenkins Pipeline

在Jenkins 2.0中,基於 Jenkins Pipeline,用戶可以在一個 JenkinsFile 中快速實現一個項目的從構建、測試以到發佈的完整流程,靈活方便地實現持續交付,並且可以保存和管理這個流水線的定義。
也就是說,Jenkins 2.0把Jenkins1.0中相關配置信息都轉換成Code形式,即Pipeline as Code。

Jenkinsfile 定義了流水線的各個階段,在每個階段可以執行相應的任務,實現了構建步驟代碼化、構建過程視圖化。
不同的Jenkins Plugin 擴展了Pipeline DSL可用的步驟和操作。

1.1 使用條件

  • Jenkins 2.x或更高版本
  • 安裝了Pipeline插件

1.2 創建方式

以流水線任務爲例:
在Jenkins job配置頁面的pipeline部分,可以選擇pipeline script 或者 pipeline script from SCM
點擊“Pipeline Syntax”可以查看Pipeline內置文檔。

  • pipeline script : 直接script輸入框裏面輸入pipeline script語句即可
  • pipeline script from SCM : 配置代碼存儲地址,並指定Jenkinsfile路徑

2 - 腳本式(Scripted Pipeline)

在Scripted Pipeline的JenkinsFile 中可以定義多個 Groovy 函數來擴展 Jenkins Pipeline 的能力
因此這種方式受 Jenkins 的限制較少,可以靈活控制和定義一個流水線,實現複雜的功能。

  • Node: Jenkins 節點,是執行 Step 的具體運行環境
  • Stage: 每個 Stage 代表一組操作,是一個邏輯分組的概念,可以跨多個 Node
  • Step: 最基本的操作單元,例如:執行Shell腳本、構建Docker鏡像等。

3 - 聲明式(Declarative Pipeline)

使用預定義的結構,Jenkins 已經預置了很多描述流水線的結構,可以快速建立流水線
雖然同樣支持寫 Groovy 腳本,官方推薦將Groovy 腳本內容定義在 Shared Libraries 中
由於需要使用預定義的結構,對於複雜性的功能難以有效支持
爲與BlueOcean腳本編輯器兼容,通常建議使用Declarative Pipeline的方式進行編寫,這種語法結構也會是未來的趨勢。

3.1 常用結構

所有有效的Declarative Pipeline必須包含在一個pipeline塊內。
除了個別限定外,Declarative Pipeline中的基本語句和表達式遵循與Groovy語法相同的規則。

pipeline {
    agent {}
	options {}
	parameters {}
    stages {
        stage {
		    when {}
            steps {}
		}
		parallel {
		    stage {}
			stage {}
		}
	}
    post {
	   always {}
	}
}

stages

  • 是stage的集合,Pipeline完成的所有實際工作都將包含在一個或多個stage指令中
  • 一般情況下,stages至少包含一個stage指令,用於連接各個交付過程,如構建,測試和部署等

stage

  • 用來區分pipeline的各個階段
  • 包含的steps部分定義了具體操作內容
  • stage與stages可以互相嵌套,stage中可以包含stages

steps

  • 包含一個或多個具體操作步驟
  • 可以使用Steps reference(https:///pipeline-syntax/html)中的所有可用步驟
  • script步驟可以提供一個有效的功能增強

3.2 常用語法

# agent
- 通過 agent 定義整個Pipeline或特定階段的執行環境,實現靈活調度資源
- Agent在Pipeline中必需存在
- 參數
    - any : 在任何可用的agent 上執行Pipeline或stage
    - none : 當在pipeline塊的頂層使用none時,將不會爲整個Pipeline運行分配全局agent ,每個stage部分將需要包含其自己的agent部分
    - label : 指定具體的 Jenkins Slave Node,也可以單獨指定Stage的執行環境
    - docker : 執行Pipeline或stage時會動態啓動一個docker節點執行Pipelines,還可以接受一個args,直接傳遞給docker run調用
    - dockerfile : 使用從Dockerfile源存儲庫中包含的容器來構建執行Pipeline或stage 
	- node : 在node中可以定義 label 和 customWorkspace(自定義運行的工作空間)等

	
# 環境變量
- 可以爲全局或stage定義變量,例如`environment { aaa = 'bbb' }`
- 通過 env 訪問自定義的和Jenkins預置的環境變量,例如`${env.JOB_NAME}`


# 參數
- 通過 parameters 定義參數,例如`parameters { string(defaultValue: "xxx", description: 'yyy', name: 'zzz') }`
- 通過 params 訪問構建時的參數,例如`${params.xxx}`
- 支持booleanParam, choice, credentials, file, text, password, string等參數類型


# options
- 在Pipeline本身內配置Pipeline專用選項
- buildDiscarder : pipeline保持構建的最大個數
- disableConcurrentBuilds : 不允許並行執行Pipeline,可用於防止同時訪問共享資源等
- skipStagesAfterUnstable : 一旦構建狀態進入了“Unstable”狀態,就跳過此stage
- timeout : 設置Pipeline運行的超時時間,例如`options { timeout(time: 1, unit: 'HOURS') }`
- retry : 失敗後,重試整個Pipeline的次數,例如`options { retry(3) }`
- timestamps : 預定義由Pipeline生成的所有控制檯輸出時間,例如`options { timestamps() }`


# tools
- 通過tools可自動安裝工具,並放置環境變量到PATH。如果agent none,將被忽略。
- 工具名稱必須在Jenkins的全局工具配置中存在。
- 示例`tools { maven 'apache-maven-3.5.2' }`


# when
- 通過 when 根據給定的條件確定是否執行該階段,控制流程走向
- 必須至少包含一個條件
- 多種內置條件
    - branch : 當正在構建的分支與給出的分支模式匹配時執行(僅適用於多分支Pipeline)
    - environment : 當指定的環境變量設置爲給定值時執行
    - expression : 當指定的Groovy表達式求值爲true時執行
    - not : 當嵌套條件爲false時執行。必須包含一個條件
    - allOf : 當所有嵌套條件都爲真時執行。必須至少包含一個條件
    - anyOf : 當至少一個嵌套條件爲真時執行。必須至少包含一個條件

# Parallel	
- 通過 parallel 定義併發步驟
- 對耗時長,相互不存在依賴的stage可以使用此方式提升運行效率
- 除了parallel stage,單個parallel裏的多個step也可以使用並行的方式運行

	
# 超時、重試
- 通過 timout 定義超時時間,例如`timeout(time: 3, unit: "MINUTES") { xxxyyyzzz }`
- 通過 retry 定義重試次數,例如`retry(3) { xxxyyyzzz }`


# post
- 通過 post 定義資源清理、通知等,也就是定義Pipeline或stage運行結束時的操作
- 與Stages平級
- 有多種不同的condition: always、success、failure、unstable、changed
    - always : 總是運行,無論Pipeline運行的完成狀態如何。
    - changed : 只有當前Pipeline運行的狀態與先前完成的Pipeline的狀態不同時,才能運行。
    - failure : 僅當前Pipeline處於“失敗”狀態時才運行,通常在Web UI中用紅色指示表示。
    - success : 僅當前Pipeline具有“成功”狀態時才運行,通常在具有藍色或綠色指示的Web UI中表示。
    - unstable : 僅當前Pipeline具有“不穩定”狀態時才運行,通常在具有黃色指示的Web UI中表示。
    - aborted : 只有當前Pipeline處於“中止”狀態時,纔會運行,通常在具有灰色指示的Web UI中表示。


# 觸發方式
- 通過 triggers 定義Pipeline自動化觸發的方式
- cron : 以cron風格來定義Pipeline觸發的常規間隔
- pollSCM : 以cron風格來定義Jenkins檢查SCM源更改的常規間隔。如果存在新的更改,則Pipeline將被重新觸發

4 - 聲明式與腳本式的比較

都是pipeline代碼的持久實現,都能夠使用pipeline內置的插件或者插件提供的steps,兩者都可以利用共享庫擴展。
不同之處在於語法和靈活性:

  • Declarative pipeline對用戶來說,語法更嚴格,有固定的組織結構,更容易生成代碼段,使其成爲用戶更理想的選擇。但是
  • Scripted pipeline更加靈活,因爲Groovy本身只能對結構和語法進行限制,對於更復雜的pipeline來說,用戶可以根據自己的業務進行靈活的實現和擴展。

5 - pipeline-syntax

5.1 變量

  • 環境變量: https://<jenkins-server-url>/env-vars.html/
  • Global Variable Reference: https://<jenkins-server-url>/pipeline-syntax/globals

5.2 代碼段生成器

  • Snippet Generator: https://<jenkins-server-url>/pipeline-syntax/
  • 內置的“Snippet Generator”程序有助於爲單個步驟生成代碼段。
  • 只需要選擇所需的步驟並配置,然後單擊生成Pipeline腳本以創建一個可以複製並粘貼到Pipeline中的Pipeline代碼段。

6 - 參考信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章