Jenkins & Docker 持續整合實踐

天府雲創發表於2017-12-25

前言

持續整合(CI/CD)是一種軟體開發實踐。用於幫助團隊成員頻繁、快速的整合,測試他們的工作成果,以儘快發現整合錯誤。 更頻繁、更早的整合意味著更早的發現問題。通過持續整合,及時發現和解決程式碼故障,提高程式碼質量,減少故障處理成本等等。

常見持續整合工具

目前持續整合的生態越來越完善,工具也有很多,開源的或商業的。如:

  • 最最流行的,也是使用最多的 Jenkins
  • 有著持續整合DNA的ThoughtWorks GO。理念:”Deployment as pipeline” (華為容器平臺應該是基於GO做的二次開發實現)
  • Atlassian工具鏈之一的Bamboo (數人云應該是基於Banboo實現的CI/CD)
  • 與Gitlab緊密整合的Gitlab CI
  • 專為開源打造的Travis CI,與Github緊密整合
  • 使用 python 語言實現的Buildbot,相信 pythoner 看到會喜歡

我們的選型是 Jenkins,所以我們來看下 Jenkins

Jenkins

Jenkins 特點

  • Jenkins是開源的應用最廣泛的持續整合工具,支援CI, CD;
  • Jenkins有很多外掛,而且使用者也可以自定義外掛,可擴充套件性非常強;
  • Jenkins對Docker支援非常好,有一套完善的Docker外掛;
  • Jenkins2.0開始支援Pipeline,一個非常強大的外掛,使用基於Groovy的DSL,支援CI/CD流水線;
  • Jenkins 基於 Java 語言開發;

Jenkins 幾個概念

  • master 是jenkins安裝和執行的地方,它負責解析job指令碼,處理任務,排程計算資源;
  • agent 負責處理從master分發的任務;
  • executor 就是執行任務的計算資源,它可以在master或者agent上執行。多個executor也可以合作執行一些任務;
  • job 任務,用來定義具體的構建過程;
  • Groovy 是一種基於JVM(Java虛擬機器)的敏捷開發語言,它結合了Python、Ruby和Smalltalk的許多強大的特性,Groovy 程式碼能夠與 Java 程式碼很好地結合,也能用於擴充套件現有程式碼。由於其執行在 JVM 上的特性,Groovy 可以使用其他 Java 語言編寫的庫。Jenkins 用Groovy作為DSL;
  • pipeline 流水線即程式碼(Pipeline as Code),通過編碼而非配置持續整合/持續交付(CI/CD)執行工具的方式定義部署。流水線使得部署是可重現、可重複的;

    流水線包括節點(Node)、階段(Stage)和步驟(Step)。
    流水線執行在節點上。節點是Jenkins安裝的一部分。流水線通常包含多個階段。一個階段包含多個步驟。流水線上手指南可以檢視到更多的內容。

    node 在Pipeline中的context中,node是 job 執行的地方。node會給job建立一個工作空間。工作空間就是一個檔案目錄,這是為了避免跟資源相關的處理互相產生影響。工作空間是node建立的,在node裡的所有step都執行完畢後會自動刪除。

    stage 階段,stage是一個任務執行過程的獨立的並且唯一的邏輯塊,pipeline定義在語法上就是由一系列的stage組成的。每一個stage邏輯都包含一個或多個step。

    step 步驟,一個step是整個流程中的一系列事情中的一個獨立的任務,step是用來告訴Jenkins如何做。

  • Jenkinfile Jenkins支援建立流水線。它使用一種基於Groovy的流水線領域特定語言(Pipeline DSL)的簡單腳。而這些指令碼,通常名字叫Jenkinsfile。它定義了一些根據指定引數執行簡單或複雜的任務的步驟。流水線建立好後,可以用來構建程式碼,或者編排從程式碼提交到交付過程中所需的工作。Jenkins中的Jenkinsfile有點類似Docker中的Dockfile的感覺

Jenkins 部署

Jenkins元件其實非常少,安裝部署也非常簡單。Jenkins按角色就兩類: master節點和slave節點。master安裝完成後,在控制檯中新增節點即可。

下面以Dcoker的部署方式為例說一下Jenkins的部署:

  • master 節點

檢視 docker hub 中 jenkins 的 image

可以看到第一個是官方提供的,所以我們選擇這個即可。

拉取 jenkins image

啟動 jenkins 容器

jenkins沒有資料庫,所有資料都是存放在檔案中的,首先在本地建立jenkins資料目錄,用於儲存jenkins的資料 這個目錄需要定期的備份,用於容災(當前jenkins容器所在節點由於不可抗因素無法使用時,可以在新機器上使用備份的資料啟動新的jenkins master節點)。

這樣jenkins就成功跑起來了。可以直接通過機器的8080埠訪問jenkins. 本地的/var/jenkins就相當於容器裡jenkins使用者的使用者主目錄,所以要保證該目錄的許可權為uid為j1000的使用者目錄。

配置 jenkins

啟動完 jenkins master 後,在瀏覽器中資料輸入 http://jenkins_master_ip:8080 登入 Jenkins 控制檯進行接下來的安裝和配置。 具體圖就不貼出來了~~

檢視jenkins的版本

  • slave 節點

安裝 java jdk

建立 jenkins 使用者

建立工作目錄

新增 jenkins 使用者到 docker 使用者組

配置 ssh 互信,master免密碼登陸slave

master 有多種管理 slave 的方式,我們選擇SSH方式 在master節點中,切換到jenkins使用者 ssh-keygen -t rsa 建立祕鑰對 把公鑰拷貝到slave節點

確保在scp前,slave節點根目錄下.ssh目錄已存在

使用 jenkins 來構建 docker 是需要安裝外掛的。那我們需要安裝哪些外掛呢?

Jenkins 有哪些 Docker 的 Plugins

docker

是非常豐富的,但並不是我們都能用的上,所以需要根據你使用的環境和平臺來選擇適合自己的 plugin 安裝就可以了。 每個 plugin 都需要適配 Jenkins 的版本,且每個 plugin 也需要依賴一些其它 plugin,上面都已經做了標註,需要配套來用。

這裡介紹幾個常用的 Docker 外掛

Docker Commons Plugin

其基本功能:

  • API for managing Docker image and container fingerprints
  • Credentials and location of Docker Registry
  • Credentials and location of Docker Daemon (aka Docker Remote API)
  • ToolInstallation for Docker CLI clients
  • DockerImageExtractor extension point to get Docker image relations from jobs
  • Simple UI referring related image fingerprints in Docker builds

Docker Plugins

該外掛是將 docker 作為 jenkins 的 slave 來使用,來在 docker 容器種完成專案的build,build 完成後該容器 slave 容器就會被銷燬。所有的工作都是在 slave 容器內完成。

docker-build-step

該外掛在 build 過程種增加了對 Docker 命令的支援。

Docker Pipeline Plugin

基於 Docker Commons Plugin 實現的一些上層的基於 Docker 的 Pipeline 編排

Docker Hub Notification Trigger Plugin

該外掛提供了當registry中的image發生變化時觸發build新映象的功能。

CloudBees Docker Build and Publish

該外掛提供了通過 Dockerfile 來構建專案並將生成的映象上傳到映象倉庫的功能。

CloudBees Docker Custom Build Environment

This plugin allows the definition of a build environment for a job using a Docker container.

該外掛適用於 “自由風格的軟體專案”,如圖:

docker

CloudBees Docker Traceability

用於追蹤通過jenkins啟停的容器的事件

Kubernetes

This plugin allows Jenkins agents to be dynamically provisioned on a Kubernetes cluster. The aim of the Kubernetes plugin is to be able to use a Kubernetes cluster to dynamically provision a Jenkins agent (using Kubernetes scheduling mechanisms to optimize the loads), run a single build, then tear-down that slave.

與 Kubernetes 結合,通過 kubernetes 提供 jenkins 的 slave 節點。利用 kubernetes 的排程功能提供快速的啟停 slave 節點執行 build 等任務。目前是0.11版本,穩定性有待驗證。

Jenkins 有沒有 API?

因為,我們不是直接在 Jenkins 的 Dashbord 來操作, 而是整合到現有平臺,所以我們需要使用它的API。

Jenkins的Remote API以REST的形式進行提供。例如,我們搭建的Jenkins站點為http://myjenkins.com:8080。那麼,訪問http://myjenkins.com:8080/api 即可檢視到該站點所有可用的API;

查詢操作

docker

執行一些動作

docker

例如,我要建立一個 job,名字為 my_job
my_job的配置檔案

docker

呼叫 api 建立 my_job

然後,你就可以在 Jenkins dashboard 上看到這個 job 了。它的管理頁面為http://myjenkins.com:8080/job/my_job。那麼我們訪問 /my_job/api/ 即可檢視到該job可用的API。

更多的 api 介紹可以參考Jenkins的官方wiki,這裡只是個引子,在此就不過多進行介紹。

相關文章