ADDOPS團隊霍明明 360雲計算
女主宣言
該文章出自于ADDOPS團隊,是一篇關于Jenkins 與 Docker 的持續內建實踐,目前使用Jenkins做CI,并且支援Docker插件做CD的實踐案例使用越來越多,該文章隻是一個開始,後續還會有Jenkins與docker內建的一個系列,希望大家能持續關注,最後希望該文章能給大家更多的一些關于持續內建的啟發。
PS:豐富的一線技術、多元化的表現形式,盡在“HULK一線技術雜談”,點關注哦!
前言
持續內建(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
[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站點為http://myjenkins.com:8080。那麼,通路http://myjenkins.com:8080/api 即可檢視到該站點所有可用的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 了。它的管理頁面為http://myjenkins.com:8080/job/my_job。那麼我們通路 /my_job/api/ 即可檢視到該job可用的API。
更多的 api 介紹可以參考Jenkins的官方wiki,這裡隻是個引子,在此就不過多進行介紹。
總結
該篇文章主要是介紹了Jenkins和docker的持續內建的實作部分,後續還有關于Jenkins的壓測、性能擴充、高可用等,還需要持續深入的介紹。敬請關注。