1. 程式人生 > >Jenkins 使用者文件

Jenkins 使用者文件

什麼是Jenkins流水線?

Jenkins Pipeline(或簡單的稱為“流水線”)是一套外掛,支援實現並整合持續的交付管道到Jenkins。

Jenkins 流水線提供了一套可擴充套件的工具,用於將“簡單到複雜”的交付管道建模為“程式碼”。Jenkins流水線的定義通常寫入到一個文字檔案(稱為Jenkinsfile)中,該檔案又被檢入到專案的原始碼控制庫中

有關管道和更新的更多資訊Jenkinsfile,請參閱使用者手冊中相應的流水線使用Jenkinsfile部分

執行多個步驟

流水線由多個步驟組成,允許您構建,測試和部署應用程式。Jenkins 流水線允許您以簡單的方式撰寫多個步驟,可以幫助您對任何型別的自動化過程建模。

想象一個“步驟”就像執行單個動作的單個命令一樣。當一個步驟成功時,它將轉到下一步。當一個步驟未能正確執行時,管道將失敗。

當管道中的所有步驟都成功完成時,管道被視為已成功執行。

Pipeline設計三個基本概念:

  • Stage: 一個流水線可以劃分為若干個Stage,每個Stage代表一組操作。注意,Stage是一個邏輯分組的概念,可以跨多個Node。

  • Node: 一個Node就是一個Jenkins節點,或者是Master,或者是Agent,是執行Step的具體執行期環境。

  • Step:Step是最基本的操作單元,小到建立一個目錄,大到構建一個Docker映象,由各類Jenkins Plugin提供。

在Linux, BSD, and Mac OS系統下操作(以下文章都是基於伺服器寫的, 沒有寫windows平臺)

在Linux、BSD和Mac OS (基於unix)系統中,sh步驟用於在流水線中執行shell命令。

最簡單的流水線

Jenkinsfile (Declarative Pipeline)
node {
   echo 'Hello World'
}

可以執行多行shell命令

Jenkinsfile(宣告式管道)
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'echo "Hello World"'
sh ''' echo "可以執行多行shell命令" ls -lah ''' } } } }

超時,重試

有一些強大的步驟可以“包裝”其他的步驟,這些步驟可以很容易地解決問題,比如重新嘗試(retry)步驟直到成功或退出,如果步驟花費太長(timeout)。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                retry(3) {
                    sh './flakey-deploy.sh'
                }

                timeout(time: 3, unit: 'MINUTES') {
                    sh './health-check.sh'
                }
            }
        }
    }
}

“Deploy”階段重試了flakely-Deploy.sh指令碼3次,然後等待healthy-check.sh指令碼執行最多3分鐘。如果healthy-check指令碼在3分鐘內沒有完成,流水線將在”Deploy”階段被標記為失敗。

“Wrapper”步驟(如timeoutretry)可能包含其他步驟,包括timeoutretry

我們可以一起組成這些步驟。例如,如果我們想重試我們的部署5次,但是在失敗之前不要花費超過3分鐘的時間

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Deploy') {
            steps {
                timeout(time: 3, unit: 'MINUTES') {
                    retry(5) {
                        sh './flakey-deploy.sh'
                    }
                }
            }
        }
    }
}

整理

當流水線完成執行時,您可能需要執行清理步驟或根據管道的結果執行一些操作。這些操作可以在post部分執行。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                sh 'echo "失敗!"; exit 1'
            }
        }
    }
    post {
        always {
            echo '這將會一直執行'
        }
        success {
            echo '只有在成功的情況下才會執行'
        }
        failure {
            echo '只有在失敗時才會執行'
        }
        unstable {
            echo '只有當執行被標記為不穩定時才會執行'
        }
        changed {
            echo '只有當管道的狀態發生變化時才會執行'
            echo '例如,如果管道以前失敗了,但是現在成功了。'
        }
    }
}

定義執行環境

每個示例中都出現了agent指令, 該agent指令告訴了Jenkins屬於哪個agent下, 以及如何執行流水線或其子集, agent對所有流水線來說都是必須的

在引擎蓋下, agent會導致如下幾件事:

  • 示例中程式碼由Jenkins線性執行, 只要agent有效, 這些步驟就會按順序執行
  • 同時將會分配一個agent專屬的workspace, 該workspace將包含從原始碼檢出的檔案以及流水線的任何其他工作檔案

有幾種方法可以定義 流水線中使用的代理, 本文不講docker容器

混合其他代理,在執行一個流水線時可以提供很大的靈活性

使用環境變數

環境變數可以全域性設定,如下面的示例或每個階段。正如您所預料的那樣,為每個階段設定環境變數意味著它們僅適用於定義它們的階段。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any

    environment {
        DISABLE_AUTH = 'true'
        DB_ENGINE    = 'sqlite'
    }

    stages {
        stage('Build') {
            steps {
                sh 'printenv'
            }
        }
    }
}

這種從Jenkinsfile中定義環境變數的方法對於指導指令碼非常有用。比如一個Makefile, 以不同的方式配置構建或測試,以在Jenkins內部執行它們。

環境變數的另一個常見用途是在構建或測試指令碼中設定或覆蓋“虛擬”憑證,因為將憑證直接放入Jenkinsfile中(顯然)是個壞主意。Jenkins流水線允許使用者快速、安全地訪問Jenkinsfile中預定義的憑證,而不需要知道它們的值。

環境中的憑證

請參閱處理使用者手冊中的憑證以獲取更多資訊

記錄測試和artifacts

雖然測試是一個良好的持續交付管道的關鍵部分,但大多數人不希望篩選數千行控制檯輸出來查詢有關失敗測試的資訊。為了簡化操作,只要您的測試執行器可以輸出測試結果檔案,Jenkins就可以記錄和彙總測試結果。Jenkins通常與junit步驟捆綁在一起,但如果您的測試執行器無法輸出JUnit樣式的XML報告,那麼還有其他外掛可以處理任何廣泛使用的測試報告格式。

為了收集我們的測試結果和工件,我們將使用該post部分。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                // sh 'make check || true',     使用內聯shell conditional(sh 'make || true')可確保該 sh步驟始終能看到零退出程式碼,從而為該junit步驟提供捕獲和處理測試報告的機會。
                sh './gradlew check'
            }
        }
    }
    post {
        always {
            // junit捕獲並關聯與包含模式(build/reports/**/*.xml)匹配的JUnit XML檔案。
            junit 'build/reports/**/*.xml'
        }
    }
}

這將始終抓住測試結果,讓Jenkins跟蹤他們,計算趨勢並報告他們。未通過測試的管道將被標記為“UNSTABLE”,在Web UI中用黃色表示。這與紅色表示的“失敗”狀態不同

當出現測試失敗時,從Jenkins抓取構建的artifacts以進行本地分析和調查通常很有用。這是由Jenkins的內建支援,用於儲存“artifacts”,這是Pipeline執行期間生成的檔案。

這很容易通過archiveArtifacts步驟和檔案匹配表示式來完成,如下例所示:

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh './gradlew build'
            }
        }
        stage('Test') {
            steps {
                sh './gradlew check'
            }
        }
    }

    post {
        always {
            //archiveArtifacts捕獲與包含模式(build/libs/**/*.jar)匹配的檔案,並將它們儲存到Jenkins主檔案中以供日後檢索。
            archiveArtifacts artifacts: 'build/libs/**/*.jar', fingerprint: true
            junit 'build/reports/**/*.xml'
        }
    }
}

如果在archiveArtifacts步驟中指定了多個引數,那麼每個引數的名稱都必須在步驟程式碼中顯式地指定,即artifacts的路徑、檔名和fingerprint,以選擇該選項。如果您只需指定artifacts的路徑和檔名,則可以省略引數名稱artifacts,例如
archiveArtifacts 'build/libs/**/*.jar'

在Jenkins中記錄測試和artifacts對於快速輕鬆地向團隊中的各個成員提供資訊非常有用。在下一節中,我們將討論如何告訴團隊成員管道中發生的事情

清理和通知

由於管道的post部分保證在管道執行結束時執行,因此我們可以新增一些通知或其他步驟來執行終結、通知或其他管道結束任務。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('No-op') {
            steps {
                sh 'ls'
            }
        }
    }
    post {
        always {
            echo '不管怎樣,我已經做完了'
            deleteDir() /* 清理我們的 workspace */
        }
        success {
            echo '我成功了!'
        }
        unstable {
            echo '我現在不穩定 :/'
        }
        failure {
            echo '我失敗了 :('
        }
        changed {
            echo '跟之前的不一樣了...'
        }
    }
}

有很多方法可以傳送通知,下面是一些演示如何傳送關於流水線的通知的資訊,比如郵件

Email

post {
    failure {
        mail to: '[email protected]',
             subject: "Failed Pipeline: ${currentBuild.fullDisplayName}",
             body: "Something is wrong with ${env.BUILD_URL}"
    }
}

現在,如果事情失敗,不穩定甚至成功,團隊將得到通知,我們可以通過令人興奮的部分完成我們的持續交付管道:運輸!

部署

最基本的連續交付管道至少應有三個階段,這些階段應在Jenkinsfile進行定義:Build, Test 和Deploy。在本節中,我們主要關注Deploy階段,但應該注意到,穩定的Build和Test階段是任何部署活動的重要前提。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                echo 'Building'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying'
            }
        }
    }
}

作為部署環境的階段

一個常見的模式是擴充套件階段的數量,以捕獲額外的部署環境,比如“分段環境”或“生產”,如下面的程式碼片段所示。

stage('Deploy - Staging') {
    steps {
        sh './deploy staging'
        sh './run-smoke-tests'
    }
}
stage('Deploy - Production') {
    steps {
        sh './deploy production'
    }
}

在這個例子中,我們假設任何“smoke tests”都是由我們執行的。./run-smoke-tests指令碼足以勝任或驗證釋出到生產環境。這種自動部署程式碼到生產的流水線可以被看作是“持續部署”的實現。雖然這是一種崇高的理想,但對於許多人來說,持續部署可能並不實用,但仍然可以享受持續交付的好處。Jenkins流水線很容易支援這兩種方式。

要求人類輸入進行

通常在階段之間,特別是在環境階段之間,您可能希望在繼續之前進行人工輸入。例如,判斷應用程式是否處於足夠好的狀態以“促進”生產環境。這可以通過輸入步驟來完成。在下面的示例中,“完整性檢查”階段實際上是阻塞了輸入,並且在沒有人確認進度的情況下不會進行。

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any
    stages {
        /* "Build" and "Test" stages omitted */

        stage('Deploy - Staging') {
            steps {
                sh './deploy staging'
                sh './run-smoke-tests'
            }
        }

        stage('Sanity check') {
            steps {
                input "分段環境看起來還可以嗎?"
            }
        }

        stage('Deploy - Production') {
            steps {
                sh './deploy production'
            }
        }
    }
}

結論

本次導遊向您介紹了使用Jenkins和Jenkins 流水線的基礎知識。由於Jenkins具有極高的可擴充套件性,因此可以對其進行修改和配置,以處理幾乎任何自動化方面的問題。要詳細瞭解Jenkins可以執行的操作,請檢視 使用者手冊Jenkins部落格以獲取最新的事件,教程和更新。