CI Dojo背景
最近組織了一次關(guān)于CI的Dojo倘要,將自己在Team中的CI實(shí)踐分享出來习勤。如果你是Dev或QA或BA,并且還不是很了解CI倦青,那么Dojo將會(huì)對(duì)你很有幫助。如果你已經(jīng)熟悉CI并正在實(shí)踐CI盹舞,那么Dojo對(duì)你也是有幫助的产镐,因?yàn)檫@里里面將會(huì)介紹優(yōu)秀的實(shí)踐。
此次Dojo旨在引導(dǎo)那些對(duì)CI有興趣的IT從業(yè)者正確地認(rèn)識(shí)CI踢步,通過Step by step的方式來搭建Jenkins CI平臺(tái)癣亚,并借鑒一些優(yōu)秀的實(shí)踐來改善CI設(shè)施,從而優(yōu)化交付流程获印,提高軟件的交付質(zhì)量述雾。
Dojo一共有四節(jié)課程:
- CI基礎(chǔ) & Setup環(huán)境
- 手把手搭建CI (待續(xù))
- 構(gòu)建可持續(xù)部署Pipeline (待續(xù))
- 持續(xù)交付 (待續(xù))
CI基礎(chǔ)
CI (Continous Integration)鳍征,持續(xù)集成黍翎。在我的印象中,它是一個(gè)項(xiàng)目開始前必須
搭建起來的基礎(chǔ)設(shè)施蟆技。在現(xiàn)在的軟件開發(fā)項(xiàng)目中玩敏,幾乎沒有項(xiàng)目是只有一個(gè)人在開發(fā)的斗忌。超過一個(gè)人就形成了團(tuán)隊(duì)质礼,每個(gè)人同時(shí)并行開發(fā)不同模塊的功能,這就涉及到代碼的集成织阳,所以代碼集成是幾乎所有開發(fā)團(tuán)隊(duì)都要面臨的問題(一個(gè)人的開發(fā)項(xiàng)目不在本文范疇中)眶蕉。
CI是什么?
Martin FLower 這樣定義持續(xù)集成:持續(xù)集成是一種軟件開發(fā)實(shí)踐,即團(tuán)隊(duì)開發(fā)成員經(jīng)常集成他們的工作唧躲,通常每個(gè)成員每天至少集成一次造挽,這就意味著每天可能會(huì)發(fā)生多次集成碱璃。
每次集成都通過自動(dòng)化的構(gòu)建(編譯,自動(dòng)化測試饭入,部署)來驗(yàn)證正確性嵌器,從而盡快地發(fā)現(xiàn)集成錯(cuò)誤。大多數(shù)團(tuán)隊(duì)發(fā)現(xiàn)這個(gè)過程可以大大減少集成的問題谐丢,讓團(tuán)隊(duì)能夠更快的開發(fā)內(nèi)聚的軟件爽航。
集成
這個(gè)詞出現(xiàn)這么多次,那么到底是在集成什么呢乾忱? 程序員寫的是什么讥珍?當(dāng)然是代碼
。所以持續(xù)集成主要是針對(duì)代碼的集成窄瘟,而我們后面所討論的的范疇也集中在代碼的集成衷佃。
集成,就少不了要借助一些工具蹄葱,將這些工具通過合理的方式組合在一起形成一種工作流模式氏义。且看一張圖:
從圖中可以看出,同時(shí)會(huì)存在多個(gè)開發(fā)者
(兩個(gè)以上)新蟆,他們會(huì)向同一個(gè)版本控制代碼庫
中提交代碼觅赊,存在一個(gè)CI Master
去監(jiān)測代碼庫是否存在更新,一旦更新琼稻,就會(huì)在Build Server
中觸發(fā)構(gòu)建
吮螺,一次構(gòu)建通常包含一下幾個(gè)步驟:
Check out, Run build, Compile, Test (Unit, Integration, E2E), Deploy
構(gòu)建運(yùn)行完畢,Build Server
會(huì)輸出構(gòu)建結(jié)果帕翻,CI Master
會(huì)根據(jù)結(jié)果失敗與否設(shè)置狀態(tài)(失旔埂:紅,成功:綠)嘀掸,最后通知開發(fā)人員
紫岩、QA
以及Team Leader
。
實(shí)踐指導(dǎo):
在Jenkins中睬塌,存在Master
和Slave
概念泉蝌,通常由Master負(fù)責(zé)管理各個(gè)Slave,具體的構(gòu)建任務(wù)由
Slave來完成揩晴,Master起到一個(gè)協(xié)調(diào)的作用勋陪。在大型復(fù)雜的構(gòu)建系統(tǒng)中,Slave和Slave之間是獨(dú)立的(獨(dú)立的物理主機(jī)獨(dú)立的IP)硫兰,通過Master將它們協(xié)調(diào)在一起去完成大型的構(gòu)建任務(wù)诅愚。當(dāng)然Master也是可以獨(dú)立完成構(gòu)建任務(wù)的,通常一些小型簡單構(gòu)建系統(tǒng)中值創(chuàng)建了以個(gè)Master就可以完成所有的事情劫映。
為什么要構(gòu)建CI?
如今軟件開發(fā)不再是少數(shù)人的活動(dòng)了违孝,Dev光桿司令的時(shí)代已經(jīng)不再刹前,曾經(jīng)流行了一段時(shí)間的神廟逃亡
也是又一對(duì)夫婦開發(fā)的〈粕#或許你會(huì)說喇喉,微服務(wù)的天下即將到來,一個(gè)資深的架構(gòu)師將系統(tǒng)拆分成足夠多足夠細(xì)粒度的微服務(wù)校坑,每個(gè)微服務(wù)小到可以由一個(gè)人去開發(fā)完成轧飞,這還需要集成嗎?需要撒踪!因?yàn)檫@樣眾多的微服務(wù)雖然都是獨(dú)立的小個(gè)體过咬,但它們的集成將是所面臨的一大挑戰(zhàn),所以CI將能夠更快地給你提供反饋制妄,讓你知道你負(fù)責(zé)的微服務(wù)是否跟其它的微服務(wù)是否還良好合作著掸绞。
不可否認(rèn),我確實(shí)經(jīng)歷過一個(gè)人開發(fā)的項(xiàng)目耕捞,如果再加上這個(gè)項(xiàng)目對(duì)外界的依賴很少衔掸,CI的價(jià)值可能就體現(xiàn)的不是那么明顯,但絕大多數(shù)情況下俺抽,都是有多個(gè)開發(fā)人員去完成的一個(gè)項(xiàng)目:
CI是需要付出成本的敞映,既然大家愿意付出成本去搭建CI,它就一定能帶來價(jià)值磷斧,CI能夠給我們帶來的益處有:
1. 減少重復(fù)的過程
2. 降低風(fēng)險(xiǎn)
3. 可視化
4. 增強(qiáng)團(tuán)隊(duì)的信心
5. 隨時(shí)隨地可以生成可部署的軟件(CD)
減少重復(fù)過程
CI通過自動(dòng)化振愿,將一些需要重復(fù)執(zhí)行的操作(代碼審查、編譯弛饭、測試冕末、構(gòu)建、部署)自動(dòng)化管理起來侣颂,大大減少了重復(fù)的過程档桃,節(jié)省了大量的時(shí)間。
降低風(fēng)險(xiǎn)
開發(fā)過程中憔晒,每天進(jìn)行多次集成藻肄,并且添加了足夠相應(yīng)的測試,每次集成CI都會(huì)快速檢查代碼中的缺陷并提供及時(shí)的反饋拒担,降低了未知的風(fēng)險(xiǎn)嘹屯。
可視化
提供一個(gè)人人都能抬頭即見且低頭還可見的Dashboard(借助Chrom插件BuildReactor,將CI Dashboard集成到Chrom瀏覽器中來)澎蛛。
CI提供了大量真實(shí)且最新的數(shù)據(jù)抚垄,能夠讓我們關(guān)注當(dāng)前集成的趨勢(例如構(gòu)建時(shí)間蜕窿、構(gòu)建失敗比例谋逻、測試覆蓋率等)呆馁,有利于有效決策。
增強(qiáng)團(tuán)隊(duì)信心
每次構(gòu)建的結(jié)果都是公開透明的毁兆,所有人清楚地知道自己的每次提交改動(dòng)對(duì)軟件所造成的影響浙滤。
隨時(shí)隨地可以生成可部署的軟件(CD)
客戶最關(guān)心的是可以部署的軟件產(chǎn)品!
CI讓我們就可以在任何時(shí)間發(fā)布可以部署的軟件气堕,在外界來看纺腊,這是持續(xù)集成最明顯的好處【グ牛或許我們將提升軟件質(zhì)量和減少項(xiàng)目風(fēng)險(xiǎn)說的滔滔不絕揖膜。但對(duì)于客戶來說,可以部署的軟件產(chǎn)品是最實(shí)際的資產(chǎn)梅桩。
1. 持續(xù)集成壹粟,我們可以經(jīng)常對(duì)源代碼進(jìn)行一些小改動(dòng),并快速將這些改動(dòng)和其他的代碼進(jìn)行集成宿百。如有問題趁仙,相關(guān)成員馬上就會(huì)被通知到,問題也會(huì)在第一時(shí)間被修復(fù)垦页。
2. 沒有持續(xù)集成雀费,問題有可能直到交付前的集成測試(回顧測試)的時(shí)候才發(fā)現(xiàn),這就有可能會(huì)導(dǎo)致延遲發(fā)布產(chǎn)品痊焊,而在緊急狀態(tài)下修復(fù)這些bug的時(shí)候又有可能引入新bug盏袄,最終可能導(dǎo)致項(xiàng)目失敗。
如何搭建CI?
CI產(chǎn)生這么多實(shí)際的價(jià)值薄啥,是不是說搭建一個(gè)CI是一件很復(fù)雜的事情呢貌矿?恰恰相反,搭建一個(gè)簡單的CI本身并不用花費(fèi)太多的時(shí)間罪佳。當(dāng)然逛漫,不花費(fèi)太多時(shí)間并不代表它就能夠發(fā)揮出那些價(jià)值,所以在開始前赘艳,我們需要了解一些CI的原則和最佳實(shí)踐酌毡,這將有助于我們打造出一個(gè)能夠創(chuàng)造實(shí)際價(jià)值的CI:
CI需要遵守的原則:
1. 統(tǒng)一的代碼庫。
2. 每次提交都會(huì)在CI服務(wù)器(專門的機(jī)器)上觸發(fā)一次構(gòu)建蕾管。
3. 快速構(gòu)建枷踏。
4. 自動(dòng)化測試。CI猶如巧婦掰曾,巧婦難為無米之炊旭蠕,所以一定要給她足夠的米(測試)。
5. 所有人在本地機(jī)器上構(gòu)建成功后再提交到代碼庫中。
6. 每次構(gòu)建100%通過掏熬,如果失敗佑稠,修復(fù)構(gòu)建優(yōu)先級(jí)最高(CI不過夜)。
7. 自動(dòng)化部署旗芬。
最佳實(shí)踐:
1. 開發(fā)人員每天至少要向代碼庫push一次代碼舌胶。
2. 開發(fā)人員每天至少要從代碼庫pull一次代碼。
3. CI定時(shí)去檢查代碼庫的更新疮丛,只要有更新幔嫂,就觸發(fā)構(gòu)建。
4. 一鍵部署誊薄。對(duì)于UAT和生產(chǎn)環(huán)境履恩,屏蔽自動(dòng)部署,引入人為手動(dòng)的一鍵部署呢蔫。
要搭建CI似袁,我們還缺一個(gè)工具
,因?yàn)槲移綍r(shí)開發(fā)過程中對(duì)Jenkins情有獨(dú)鐘咐刨,這里就選用Jenkins作為CI工具昙衅,它簡單易用,功能強(qiáng)大定鸟,并且所有的操作幾乎都可以在Web GUI上完成而涉。下面列出一些比較流行的開源工具:
Setup Ubuntu虛擬環(huán)境
方便起見,我們準(zhǔn)備在Mac主機(jī)上Setup一個(gè)Ubuntu的虛擬環(huán)境联予,將借助 Vagrant 和 Virtualbox 來完成啼县。在Mac上安裝如下版本工具:
1. Vagrant 1.9.1
2. Virtualbox 5.0.10
安裝好Vagrant之后,查看版本:
$ vagrant -v
Vagrant 1.9.1
創(chuàng)建一個(gè)目錄dojo-ci
沸久,在dojo-ci目錄中進(jìn)行初始化:
$ mkdri dojo-ci
$ cd dojo-ci
$ vagrant init ubuntu/trusty64
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
首次運(yùn)行季眷,Vagrant會(huì)聯(lián)網(wǎng)下載ubuntu/trusty64
,需要等待一段時(shí)間卷胯。
執(zhí)行完畢子刮,會(huì)生成一個(gè)Vagrantfile文件,我們對(duì)該文件做一些配置窑睁,添加如下配置信息:
Vagrant.configure("2") do |config|
config.vm.define :jenkins_ubuntu do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.hostname = "jenkins-ubuntu"
config.vm.synced_folder "~/Personal-sjyuan/ysj_hub/docker-jenkins", "/home/vagrant/docker-jenkins"
config.vm.network "private_network", ip: "10.29.2.122"
config.vm.network "forwarded_port", guest: 80, host: 80
config.vm.network :forwarded_port, guest: 8080, host: 8080
# config.vm.provision :shell, path: "./setup-jenkins.sh"
config.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
end
end
end
上面主要配置信息注釋:
1. hostname挺峡,指定虛擬機(jī)用戶名
2. synced_folder,Host主機(jī)與虛擬機(jī)所掛載的同步目錄担钮,前者是Host主機(jī)上的目錄橱赠,必須存在,后者在虛擬機(jī)創(chuàng)建之后會(huì)自動(dòng)創(chuàng)建箫津。
3. network狭姨,配置網(wǎng)絡(luò)選項(xiàng)宰啦,可以配置虛擬機(jī)IP,以及與Host主機(jī)的端口映射饼拍。
4. provision赡模,指定運(yùn)行的文件,可以在虛擬機(jī)創(chuàng)建好之后自動(dòng)運(yùn)行腳本安轉(zhuǎn)所需要的環(huán)境惕耕,該文件必須存在于Host主機(jī)上。
Vagrant是一個(gè)命令行工具诫肠,用于管理虛擬機(jī)生命周期(啟動(dòng)司澎,關(guān)機(jī),注銷栋豫,移除等)挤安,非常易用,官方文檔的getting-started是一個(gè)很好的學(xué)習(xí)文檔丧鸯。
配置好Vagrantfile蛤铜,就可以一鍵啟動(dòng):
$ vagrant up
等待虛擬機(jī)啟動(dòng)完畢,ssh登錄到虛擬機(jī)丛肢,此后的一切操作跟在一臺(tái)Linux機(jī)器的終端上操作別無兩樣:
$ vagrant ssh
安裝Jenkins
Setup好Ubuntu虛擬機(jī)围肥,我們就有了CI服務(wù)器,最后蜂怎,我們來安轉(zhuǎn)Jenkins:
$ wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -
$ sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
$ sudo apt-get update
$ sudo apt-get install -y jenkins
安裝完畢后穆刻,查看Jenkins服務(wù)是否正常啟動(dòng):
$ sudo service jenkins status
Jenkins Continuous Integration Server is running with the pid 1112
如果沒有啟動(dòng),需要運(yùn)行以下命令啟動(dòng)jenkins:
$ sudo service jenkins start
* Starting Jenkins Continuous Integration Server jenkins [ OK ]
訪問localhost:8080杠步,可以看到:
快要成功了氢伟,根據(jù)頁面提示,需要一個(gè)密碼校驗(yàn)幽歼,這個(gè)密碼在jenkins運(yùn)行的Server上朵锣,也就是之前使用Vagrant啟動(dòng)的Ubuntu的虛擬機(jī)上:
$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword
1ed2af4*****************5ad29e
輸入密碼之后,選擇Continue甸私,然后選擇Install suggested plugins
诚些,等待安裝完畢,創(chuàng)建一個(gè)用戶皇型,可以看到Jenkins Dashboard: