Jenkins與Docker的持續整合實踐

Docker精選發表於2017-08-16

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

【3 天燒腦式基於Docker的CI/CD實戰訓練營 | 北京站】本次培訓圍繞基於Docker的CI/CD實戰展開,具體內容包括:持續整合與持續交付(CI/CD)概覽;持續整合系統介紹;客戶端與服務端的 CI/CD 實踐;開發流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及實踐經驗分享等。

常見持續整合工具

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

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

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

Jenkins

Jenkins特點

  • Jenkins是開源的應用最廣泛的持續整合工具,支援CI, CD;
  • Jenkins有很多外掛,而且使用者也可以自定義外掛,可擴充套件性非常強;
  • Jenkins對Docker支援非常好,有一套完善的Docker外掛;
  • Jenkins 2.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
[root@k3128v /home/huomingming]# docker search jenkinsNAME DESCRIPTION STARS OFFICIAL AUTOMATEDjenkins Official Jenkins Docker image 2600 [OK] stephenreed/jenkins-java8-maven-git Automated build that provides a continuous... 53
可以看到第一個是官方提供的,所以我們選擇這個即可。

拉取jenkins image
docker pull jenkins
啟動Jenkins容器

Jenkins沒有資料庫,所有資料都是存放在檔案中的,首先在本地建立Jenkins資料目錄,用於儲存Jenkins的資料 這個目錄需要定期的備份,用於容災(當前Jenkins容器所在節點由於不可抗因素無法使用時,可以在新機器上使用備份的資料啟動新的jenkins master節點)。
sudo mkdir /var/jenkins sudo chown 1000:1000 /var/jenkins sudo docker run -p 8080:8080 -p 50000:50000 -v /var/jenkins:/var/jenkins_home --name my_jenkins -d jenkins
這樣Jenkins就成功跑起來了。可以直接通過機器的8080埠訪問Jenkins,本地的/var/jenkins就相當於容器裡Jenkins使用者的使用者主目錄,所以要保證該目錄的許可權為uid為j1000的使用者目錄。

配置Jenkins

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

檢視Jenkins的版本
java -jar /usr/share/jenkins/jenkins.war --version

slave 節點

安裝Java JDK
yun install java-1.8.0-openjdk

建立Jenkins使用者
$ useradd -m jenkins -d /home/jenkins$ passwd jenkins

建立工作目錄
mkdir /data/jenkinschown jenkins.jenkins /data/jenkins

新增Jenkins使用者到Docker使用者組
sudo usermod -a -G docker jenkins

配置SSH互信,Master免密碼登陸Slave

Master有多種管理Slave的方式,我們選擇SSH方式在Master節點中,切換到Jenkins使用者ssh-keygen -t rsa建立祕鑰對把公鑰拷貝到Slave節點
scp ~/.ssh/id_rsa.pub jenkins@slave_ip:~/.ssh/authorized_keys

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

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

Jenkins有哪些Docker的Plugins


是非常豐富的,但並不是我們都能用的上,所以需要根據你使用的環境和平臺來選擇適合自己的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。該外掛適用於 “自由風格的軟體專案”,如圖:


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站點為myjenkins.com:8080。那麼,訪問http://myjenkins.… 即可檢視到該站點所有可用的API。

查詢操作


執行一些動作

例如,我要建立一個 job,名字為 my_job,my_job的配置檔案:
<?xml version='1.0' encoding='UTF-8'?><project> <actions/> <description></description> <keepDependencies>false</keepDependencies> <properties/> <scm class="hudson.scm.NullSCM"/> <canRoam>true</canRoam> <disabled>false</disabled> <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding> <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding> <triggers class="vector"/> <concurrentBuild>false</concurrentBuild> <builders/> <publishers/> <buildWrappers/></project>

呼叫API建立 my_job:
curl -X POST http://www.xxx.xxx/jenkins/createItem?name=my_job --user uname:pass --data-binary "my_job_config.xml" -H "Content-Type: application/xml"
然後,你就可以在Jenkins Dashboard上看到這個job了。它的管理頁面為myjenkins.com:8080/job/my_job。… /my_job/api/ 即可檢視到該job可用的API。

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

總結

該篇文章主要是介紹了Jenkins和Docker的持續整合的實現部分,後續還有關於Jenkins的壓測、效能擴充套件、高可用等,還需要持續深入的介紹。

原文連結:dockone.io/article/259…

相關文章