此次實習的任務之一就是搭建一個持續集成(Continuous Integration)環境。html
咱們選擇Jenkins做爲持續集成工具,其優勢是提供web GUI配置界面,方便配置,還能夠安裝不少第三方插件(plugin)進行定製與擴展,功能強大。前端
其次選擇Gitlab做爲git server。Gitlab的功能和Github差很少,可是是開源的,能夠用來搭建私有git server,也提供很是強大的web GUI,好比開發者互相review源代碼的時候就會很方便。java
本文首先介紹整個系統的結構,而後再一一敘述各個組件的安裝及使用方法。linux
1.系統概覽git
系統結構以下圖所示:github
系統的工做流程大概分爲如下幾步:web
1> 開發者將新版本push到git server (Gitlab)。shell
2> Gitlab隨後觸發jenkins master結點進行一次build。(經過web hook或者定時檢測)bootstrap
3> jenkins master結點將這個build任務分配給若干個註冊的slave結點中的一個,這個slave結點根據一個事先設置好的腳本進行build。這個腳本能夠作的事情不少,好比編譯,測試,生成測試報告等等。這些本來須要手動完成的任務均可以交給jenkins來作。ubuntu
4> 咱們在build中要進行編譯,這裏使用了分佈式編譯器distcc來加快編譯速度。
notes
jenkins的工做原理是先將源代碼從gitlab中拷貝一份到本地,而後根據設置的腳本進行build。咱們能夠看出,整個系統的關鍵就是那個build腳本,用來告訴jenkins在一次集成中須要執行的任務。
2.Jenkins的安裝與配置
1> 安裝Jenkins
首先說如何安裝 jenkins ,必定要安裝最新版本纔不會出各類奇怪的問題,參考官網wiki, Installing Jenkins on Ubuntu 上的指示,
$ wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
$ sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list' $ sudo apt-get update $ sudo apt-get install jenkins
便可以獲得最新版的jenkins。
Jenkins安裝完畢後,能夠經過瀏覽器訪問其Dashboard,例如192.168.16.183:8080,IP地址即爲Jenkins所在機器的IP地址。
2> Jenkins插件安裝
Jenkins其實沒有什麼須要特別配置的,因爲此次任務中須要利用Jenkins與git,gitlab協做,因此須要安裝一些插件。在主面板上點擊Manage Jenkins -> Manage Plugins。
因爲公司使用代理鏈接外網,首先須要爲Jenkins插件安裝配置proxy。點擊Advanced標籤即進入proxy設置頁面。
Aailable標籤下就是能夠安裝的插件。
要讓Jenkins能夠自動build git repo中的代碼,須要安裝GIT Client Plugin和GIT Plugin。
要想Jenkins能夠收到Gitlab發來的hook從而自動build,須要安裝 Gitlab Hook Plugin。
要讓Jenkins能夠在build完成以後根據TAP(test anything protocol)文件生成graph,須要安裝 TAP Plugin。
3> Jenkins Job
咱們嘗試新建一個Jenkins Job,必須填的內容不是不少,並且每一項後面都有意一個問號,點擊後會有關於這項的一些提示。
(1)首先是Project name;
(2)而後在Source Code Management 中選擇Git,咱們只須要提供Repository URL便可,這個URL能夠是Jenkins機器上的一個本地repo,例如/home/woody/repo;也能夠是一個遠程機器上的repo,例如Gitlab上經過ssh鏈接的repo: git@192.168.16.194:user/test_gitlab_repo.git
注意,咱們須要在Jenkins機器上設置Git username 和 email,否則後面會build不成功。
(3)下面須要在Build中選擇Add build step,這裏以最熟悉的shell爲例,選擇Execute shell。Jenkins的工做原理很簡單,就是從剛纔的Repository URL裏clone到當前的一個workspace中並切換到最新的branch而後執行Execute shell中的command,若是每條command都返回0則build成功,不然則算失敗。 因此咱們的shell command能夠是簡單的編譯指令例如:
#!/bin/sh
make
(這須要你的git repo中有一個makfile)
也能夠執行repo中的另外一個腳本,例如
#!/bin/sh
perl test.pl
甚至能夠什麼都不作,或者是隻輸入一些字符。
(4)接下來咱們須要設置一個觸發選項,在Build Triggers中,Jenkins提供三個選擇
Build after other projects are built 顧名思義
Build periodically 週期性地build
Poll SCM 週期性的檢測SCM(如Git)中是否有新的提交,若是有則build
選擇後面兩項咱們都須要在Schedule中設置週期,點擊後面的問號能夠查看的設置週期的語法。
到這一步結束後咱們就能夠Save配置了,能夠在面板中點擊Build Now看看是否能夠正常工做。在下面的Build History中有該Job的全部build歷史,點擊任意一條進去後能夠進行查看,特別說明能夠在Console Output中看到執行此次build時控制檯的輸出信息。
(5)若是安裝了TAP Plugin,咱們還能夠配置Job在build完成後根據TAP result生成一副Graph例以下圖:
這幅圖顯示了每次build中成功與失敗次數的走勢。
想要獲得這張圖的話,須要在Configure的Post-build Action中選擇Add post-build action -> Publish TAP result。 而後在test result 中輸入你的TAP result文件的路徑,例如tap.tap指的就是當前文件下的tap.tap文件。也就是說在你的Execute Shell中,你須要在編譯完成後根據結果本身生成一個TAP文件,TAP的語法能夠參考Jenkins TAP Plugin的說明。
4> 搭建Jenkins Master - Slaves 架構
咱們在配置Jenkins時,有一個# of executors 選項,這項表明了Jenkins能夠同時處理的Job的數量。
Jenkins還支持將Job分給Slave處理的功能。這就須要咱們爲Jenkins配置一些Slaves。
在Dashboard中點擊 Mamage Jenkins -> Manage Nodes -> New Node
而後輸入Node name 並選擇Dumb Slave 點擊OK後進入配置頁面。須要填的內容以下圖所示:
# of executors指的是該slave上容許同時處理的job數量; 其餘選項也都顧名思義, 咱們這裏選擇用SSH的方式進行鏈接,Host即爲Slave的IP地址。
Slave上不須要安裝Jenkins,只須要安裝java環境和git便可:
$ sudo aptitude install default-jre
$ sudo aptitude install git
還須要爲slave的jenkins用戶配置git user.name & user.email
這裏須要說明一個地方,Jenkins在工做時是利用一個名爲jenkins的用戶登入機器的。
在master節點上,安裝Jenkins時自動爲系統添加了一個名爲jenkins的用戶,因爲slave機器上不須要安裝jenkins,因此咱們須要在slave機器上手動添加一個名爲jenkins的用戶。並且Jenkins master只能經過不用輸入密碼的SSH方式鏈接slave,須要在master上用jenkins用戶生成一對ssh密鑰,並把公鑰加入slave機器上jenkins用戶的用戶目錄裏.ssh/authorized_keys中。
注意,沒有密碼的用戶在ubuntu下可能切換不成功,咱們用下面的方法:
$ sudo su jenkins
$ bash
3.Gitlab的安裝與配置
Gitlab的功能和Github差很少,都是做爲git server。
Gitlab是開源的,咱們能夠利用Gitlab搭建本身私有的git server。
咱們能夠在bitnami上下載 Gitlab 。
公司有現成的Gitlab,因此我沒有嘗試Gitlab的安裝,看上去成功安裝並不容易。
爲了測試,仍是在虛擬機環境下配置了Gitlab,直接下載了Virtual Machine鏡像,因爲鏡像是Vmware的,還須要將其轉爲Virtual Box鏡像,方法參見http://wiki.bitnami.com/Virtual_Appliances_Quick_Start_Guide。
在虛擬機上跑起來後,發現是一個沒有GUI的ubuntu。。。系統用戶名和密碼都是bitnami。
咱們還能夠經過訪問其IP地址登入Gitlab,初始用戶名爲user,密碼爲bitnami,看上去和github很象。
因爲在此次任務中Jenkins須要從Gitlab中獲取文件並build,因此咱們須要在Gitlab的工程中設置一些東西。
首先是settings -> Deploy Keys, 這裏須要加入Jenkins所在機器jenkins用戶的公鑰。
若是Jenkins中使用slave,還須要將slave的公鑰加入deloy keys中。 由於slave的工做原理是收到master的指示直接clone repository。
而後是一個叫Web Hooks的東東。還記得咱們在Jenkins中安裝過Gitlab Hook Plugin麼,若是設置了Web Hooks,Gitlab就會在每次push上來後發送一條消息到指定的地址(即hook的地址),Jenkins Gitlab Hook Plugin收到消息後當即build。
不過我按照Gitlab Hook Plugin的說明設置裏hooks後並無什麼做用,多是那個插件的bug吧。。
後來大哥告訴我一個巧妙的辦法,就是將Jenkins Job裏的build now鏈接做爲hook地址,例如http://192.168.16.183:8080/job/test_gitlab/build?delay=0sec
這樣每次Gitlab收到push後就會促使Jenkins當即build。
4.distcc的安裝與配置
distcc是一個分佈式的編譯器,他能夠將編譯任務分配給多個其餘機器上的destccd-daemon,從而加速編譯過程。
1> 安裝
ubuntu下distcc很容易安裝
$ sudo aptitude install distcc
2> 配置
distcc分爲前端和守護進程,前端的用法和gcc差很少,用來編譯源代碼文件。
守護進程即distcc-daemon,須要一些配置。
守護進程的配置文件在 /etc/default/distcc 中,
$ sudo vim /etc/default/distcc
STARTDISTCC="true" //這項容許distccd啓動 ALLOWEDNETS=「192.168.16.0/24」 //這項指出裏容許那些IP的distcc鏈接上來, /24指的是子網掩碼前24位爲1,後面爲0,即表明192.168.16.0 ~ 192.168.16.255 LISTENER=「192.168.16.183」 //這項應該填本機的IP地址,即須要監聽的IP地址 ZEROCONF = 「false」 //這項指出不開啓zeroconf,咱們先講不開啓zeroconf,後面再討論使用它的狀況
這樣一個distccd就配置完成了。
經過如下命令能夠開啓和中止distccd
$ sudo service distcc start
$ sudo service distcc stop
在進行編譯前,由於distccd都沒有開啓zeroconf,因此distcc沒法知道有哪些host可供使用,因此這裏須要在環境變量中加入,例如
export DISTCC_HOSTS="192.168.16.183 192.168.16.198"
使用下面的命令能夠查看hosts是否配置成功。
$ distcc --show-hosts
而後就可使用distcc進行分佈式編譯,例如編譯linux kernel,
$ make CC=distcc
下面講當咱們爲distccd開啓ZEROCONF時即配置
ZEROCONF=「true」
這就說明distcc能夠不須要手動配置hosts地址便可以發現可用的hosts,具體原理不是很清楚,反正用命令
$ distcc --show-hosts
能夠看到distccd的地址。
可是這裏貌似對IPv6的解析上有一個bug,百度裏一下說須要關閉avahi的IPv6
編輯 /etc/avahi/avahi-daemon.conf
修改如下內容
use-ipv6=no
便可。
而後還須要在調用distcc的用戶的環境變量中加入
export DISTCC_HOSTS="+zeroconf"
咱們還能夠在調用distcc的用戶中用如下命令查看編譯的進度
$ distccmom-text 5