|
[注:原文發(fā)布于2011年12月23日]
背景
現(xiàn)如今,單元測(cè)試、自動(dòng)化驗(yàn)收測(cè)試、持續(xù)集成等技術(shù)手段已被很多項(xiàng)目團(tuán)隊(duì)所采用,它們可以在軟件開發(fā)活動(dòng)中很大程度的保證開發(fā)軟件的正確性,即是否滿足了新的需求并且沒有破壞已有的需求。但是如果軟件無(wú)法順利的部署到生產(chǎn)環(huán)境上,就不能帶來(lái)任何商業(yè)價(jià)值。
作為軟件開發(fā)人員,為了驗(yàn)證軟件是否能夠部署成功,不應(yīng)該只有當(dāng)軟件設(shè)計(jì)、開發(fā)、測(cè)試等階段結(jié)束后才向生產(chǎn)環(huán)境或準(zhǔn)生產(chǎn)環(huán)境部署,而應(yīng)該把部署作為整個(gè)軟件開發(fā)活動(dòng)的一部分,從項(xiàng)目之初,在項(xiàng)目整個(gè)持續(xù)過(guò)程中,實(shí)現(xiàn)自動(dòng)化的構(gòu)建、部署、測(cè)試,即“部署流水線”。
挑戰(zhàn)
有了“部署流水線”之后,當(dāng)我們?cè)诿看未a提交時(shí),都有可能向測(cè)試環(huán)境、準(zhǔn)生產(chǎn)環(huán)境等不同環(huán)境部署軟件并測(cè)試,會(huì)有如下情況涉及到自動(dòng)化部署:
- 自動(dòng)化驗(yàn)收測(cè)試前,需要使用最新構(gòu)造的結(jié)果部署到持續(xù)集成的測(cè)試環(huán)境上;
- 當(dāng)測(cè)試需要驗(yàn)證某一個(gè)版本的產(chǎn)品時(shí),可以自動(dòng)的創(chuàng)建出來(lái)該版本的一個(gè)環(huán)境;
- 對(duì)于性能測(cè)試、UAT驗(yàn)收測(cè)試、給業(yè)務(wù)人員演示(showcase)時(shí),可以自動(dòng)化創(chuàng)建出某一個(gè)版本的環(huán)境;
- 自動(dòng)化的向生產(chǎn)環(huán)境部署。
這就要求我們擁有自動(dòng)化部署的能力,它有如下若干特點(diǎn):
- 需要有自動(dòng)化的基礎(chǔ)設(shè)施管理能力,比如很方便的創(chuàng)建一個(gè)節(jié)點(diǎn)甚至一整套環(huán)境;
- 部署過(guò)程代碼化,能夠自動(dòng)化的安裝、配置軟件;
- 在向各個(gè)環(huán)境部署時(shí),使用相同的自動(dòng)化代碼;
- 各個(gè)環(huán)境與生產(chǎn)環(huán)境都需要盡可能的相似,有同樣的操作系統(tǒng)底層組件網(wǎng)絡(luò)配置等。
這樣當(dāng)我們將軟件最終向生產(chǎn)環(huán)境部署時(shí),同樣的部署代碼已經(jīng)在類似的環(huán)境中使用并測(cè)試過(guò),對(duì)于這次發(fā)布我們就有足夠的信心能夠成功。
自動(dòng)化部署
由上可以看出,自動(dòng)化部署最主要的問(wèn)題在于如何創(chuàng)建基礎(chǔ)設(shè)施,以及如何安裝和配置軟件產(chǎn)品。
在這里我們先說(shuō)說(shuō)如何自動(dòng)化的安裝和配置軟件產(chǎn)品。只要是手工過(guò)程可以完成的安裝和配置工作,理論上我們都可以將其代碼腳本化。開發(fā)人員或者系統(tǒng)管理員完全可以通過(guò) bash 或者 PowerShell 來(lái)完成這些工作。這要求我們將部署代碼以及更為重要的環(huán)境配置文件都當(dāng)作產(chǎn)品的一部分,放入版本控制庫(kù)中。
現(xiàn)如今已經(jīng)有了很多自動(dòng)化準(zhǔn)備技術(shù)可以幫助開發(fā)人員實(shí)現(xiàn)部署腳本,比如比較流行的 Puppet 和 Chef。以 [Chef](http://wiki.opscode.com/display/chef/Home) 舉例,Chef 是一個(gè)開源的系統(tǒng)配置和集成框架,它通過(guò)自定義的 DSL 領(lǐng)域語(yǔ)言來(lái)實(shí)現(xiàn)基礎(chǔ)設(shè)施和軟件環(huán)境的搭建,并支持物理機(jī)器、虛擬機(jī)、云節(jié)點(diǎn)(理論上開放了 ssh 端口都可以)。由于 Chef 的部署代碼是 ruby 語(yǔ)言,所以我們也可以很方便的對(duì)其擴(kuò)展,實(shí)現(xiàn)任何自定義的功能。
有了自動(dòng)化的部署腳本,既可以可控的可重復(fù)的執(zhí)行部署過(guò)程。這里需要指出的是,當(dāng)開發(fā)或測(cè)試人員在某個(gè)環(huán)境上發(fā)現(xiàn)產(chǎn)品配置問(wèn)題時(shí)(比如發(fā)現(xiàn)性能測(cè)試環(huán)境上應(yīng)用服務(wù)器調(diào)用某一個(gè) API 服務(wù)的地址有誤),應(yīng)該極力避免開發(fā)人員直接遠(yuǎn)程連接到該機(jī)器上手工修改。一旦在版本控制中有了自動(dòng)化部署腳本和配置管理,就應(yīng)該從源代碼級(jí)別來(lái)修改,通過(guò)重新觸發(fā)一次新的“部署流水線”來(lái)修正問(wèn)題并驗(yàn)證修改是否正確。
云和虛擬化技術(shù)
對(duì)于自動(dòng)化的基礎(chǔ)設(shè)施管理,近來(lái)年已經(jīng)逐漸成熟的云和虛擬化技術(shù)可以給我們帶來(lái)很大的好處。云和虛擬化其實(shí)并不是一個(gè)新的概念,只是最近幾年在技術(shù)圈子里很火熱。拋去云和虛擬化華麗的外表,其實(shí)這里只需要它們提供給開發(fā)人員基礎(chǔ)設(shè)施管理的能力,使用云和虛擬化的好處有:
- 快速響應(yīng)環(huán)境的需求
- 平臺(tái)標(biāo)準(zhǔn)化,屏蔽底層的硬件物理實(shí)現(xiàn)
- 實(shí)現(xiàn)對(duì)環(huán)境搭建的可重復(fù)性
- 可以維護(hù)環(huán)境基線,根據(jù)鏡像或副本復(fù)制環(huán)境
- 可以對(duì)環(huán)境中的每個(gè)節(jié)點(diǎn)進(jìn)行有效監(jiān)控
當(dāng)然云和虛擬化的合理使用也會(huì)帶來(lái)成本上的好處,但更為重要的是給我們開發(fā)團(tuán)隊(duì)的自動(dòng)化部署、持續(xù)交付帶來(lái)了可能。可以想象,通過(guò)云和虛擬化技術(shù),開發(fā)人員可以在實(shí)現(xiàn)一個(gè)需求后,通過(guò)一條命令可以幾分鐘內(nèi)將其自動(dòng)化部署到一個(gè)新創(chuàng)建的環(huán)境中,在向業(yè)務(wù)人員做完演示后,又能通過(guò)一條命令將該環(huán)境清除。
下面舉兩個(gè)目前較為流行的例子,給出大家云和虛擬化技術(shù)對(duì)自動(dòng)化部署時(shí)基礎(chǔ)設(shè)施管理提供的便利。
Amazon平臺(tái)
以 Amazon 的 EC2 服務(wù)為例,目前已經(jīng)有了很多對(duì)其提供支持的工具,比如 [Amazon EC2 API Tools]( http://aws.amazon.com/developertools/351)。配置好 Amazon 的 key 后,我們可以很方便的創(chuàng)建一個(gè) EC2 Node:
ec2-run-instances ami-a54d67d1 --instance-type t1.micro --region us-west-1 --key MY_AMZ_KEY
# =>服務(wù)器在美國(guó)西海岸,大小為 micro,系統(tǒng)鏡像為 ami-a54d67d1
但這樣僅僅是創(chuàng)建出一臺(tái)最基本的基礎(chǔ)設(shè)施,對(duì)于開發(fā)人員來(lái)講,仍需要通過(guò)腳本代碼來(lái)對(duì)其進(jìn)行自動(dòng)化配置。不過(guò),目前已經(jīng)有許多工具已經(jīng)集成了對(duì) EC2 的自動(dòng)化部署。比如,Chef 通過(guò)一個(gè)插件 [knife-ec2]( https://github.com/opscode/knife-ec2)來(lái)直接對(duì) Amazon EC2 進(jìn)行支持。當(dāng)我們用 Chef 寫出對(duì)自己產(chǎn)品的部署配置代碼后,可以通過(guò)一條命令自動(dòng)化地創(chuàng)建出一個(gè)具有某種角色的服務(wù)器,安裝并配置項(xiàng)目的產(chǎn)品及其依賴,示例腳本如下:
knife ec2 server create "role[rails_server]" --image ami-31814f58 --flavor t1.micro --availability-zone us-east-1a--ssh-key MY_AMZ_KEY
# =>服務(wù)器在美國(guó)東海岸,大小為micro,系統(tǒng)鏡像為 ami-a54d67d1,Chef 按照部署代碼將其配置為rails_server的角色
vagrant
對(duì)于虛擬化來(lái)說(shuō),現(xiàn)在也有許多技術(shù)可以給開發(fā)提供自動(dòng)化基礎(chǔ)設(shè)施管理。這里舉 vagrant 為例。[vagrant](http://vagrantup.com/)是一個(gè)基于 VirtualBox 創(chuàng)建和發(fā)布虛擬化環(huán)境的工具,它可以自動(dòng)化創(chuàng)建虛擬機(jī),并對(duì)其進(jìn)行基礎(chǔ)設(shè)施配置。vagrant 的使用非常方便,并且 vagrant 也直接支持 Chef 和 Puppet。我們創(chuàng)建一個(gè) VagrantFile 表示一臺(tái)虛擬機(jī),簡(jiǎn)單腳本內(nèi)容如下:
Vagrant::Config.run do |config|
config.vm.box = "centos6"
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = "/PATH/TO/chef-repo/cookbooks"
chef.roles_path = "/PATH/TO/chef-repo/roles"
chef.add_role "db_master_server"
end
end
VagrantFile也是由 ruby 寫成,這份VagrantFile表示是一臺(tái)基于 centos6 box (vagrant 初始化一個(gè)虛擬機(jī)的鏡像)的虛擬機(jī),在創(chuàng)建時(shí)會(huì)通過(guò) Chef 向其部署 `db_master_server` 的角色。有了VagrantFile我們就只需要通過(guò)簡(jiǎn)單的命令就可以控制虛擬機(jī)了。
vagrant up # =>創(chuàng)建、啟動(dòng)虛擬機(jī)
vagrant suspend # =>掛起虛擬機(jī),保存狀態(tài)
vagrant halt # =>停止虛擬機(jī)
vagrant destroy # =>銷毀虛擬機(jī)
鏡像及部署腳本管理
大部分的云和虛擬化技術(shù)都支持從一個(gè)鏡像(image 或 box)開始創(chuàng)建節(jié)點(diǎn),然后再結(jié)合我們的部署腳本對(duì)其進(jìn)行安裝和配置。對(duì)于有些已經(jīng)比較固定的基礎(chǔ)設(shè)置,或者一些配置耗時(shí)很長(zhǎng)的過(guò)程,我們完全可以直接將其做入鏡像中。而對(duì)于屬于我們產(chǎn)品的部分,以及一些很容易變化的依賴,應(yīng)該通過(guò)部署腳本來(lái)管理。
對(duì)于我們自定義創(chuàng)建出來(lái)的鏡像,很難放置到團(tuán)隊(duì)的版本控制中去(一般這些鏡像文件都會(huì)很大),但是,我們可以把創(chuàng)建鏡像的過(guò)程自動(dòng)化,并將其添加到版本控制中(這就如同我們的版本控制中只有源代碼而不要保存二進(jìn)制構(gòu)建結(jié)果一樣)。比如 vagrant 就可以通過(guò)簡(jiǎn)單的命令將當(dāng)前虛擬機(jī)做成鏡像(box)。我們可以通過(guò)最基礎(chǔ)的 box 創(chuàng)建虛擬機(jī),通過(guò) Chef 安裝配置機(jī)器,然后再通過(guò) vagrant 將其做成鏡像,這個(gè)過(guò)程完全可以代碼化。
環(huán)境管理
通過(guò)云和虛擬化技術(shù),再結(jié)合自動(dòng)化部署腳本,提供給了開發(fā)人員一種通過(guò)受版本控制的腳本代碼來(lái)自動(dòng)創(chuàng)建部署機(jī)器的能力。但以上過(guò)程還是僅僅在針對(duì)一個(gè)節(jié)點(diǎn)的管理?;谶@種能力之上,我們可以實(shí)現(xiàn)完整的對(duì)環(huán)境的自動(dòng)化管理。
通過(guò)對(duì)項(xiàng)目系統(tǒng)拓?fù)浣Y(jié)構(gòu)的配置文件化,我們只需再添加少許工作,完全可以通過(guò)一個(gè)拓?fù)浣Y(jié)構(gòu)的配置文件(比如一個(gè) xml 或者 yaml)結(jié)合持續(xù)集成構(gòu)造出來(lái)的產(chǎn)品庫(kù)(二進(jìn)制構(gòu)建結(jié)果),實(shí)現(xiàn)對(duì)整個(gè)環(huán)境的控制:
environment create uat-env --topology.yml
# => 創(chuàng)建出一個(gè)名為`uat-env` 的完整環(huán)境(集成多個(gè)節(jié)點(diǎn))
項(xiàng)目實(shí)例
最后給大家提供一個(gè)實(shí)際的項(xiàng)目案例。在本項(xiàng)目中,團(tuán)隊(duì)中任何一個(gè)人員修改并提交了代碼(這里包括生產(chǎn)代碼、測(cè)試代碼、驗(yàn)收用例、部署腳本、配置文件等),都會(huì)在“部署流水線”上觸發(fā)一個(gè)新的流程:
- 打包:編譯、靜態(tài)檢查、單元測(cè)試、構(gòu)建安裝包(rpm);
- 本地測(cè)試:通過(guò) localhost 方式運(yùn)行前臺(tái)產(chǎn)品,執(zhí)行自動(dòng)化驗(yàn)收測(cè)試;
- 類生產(chǎn)測(cè)試:通過(guò) Chef 在 Amazon EC2 上創(chuàng)建測(cè)試環(huán)境,部署多個(gè)節(jié)點(diǎn),執(zhí)行自動(dòng)化集成測(cè)試;
- 歸檔:將本次流程的構(gòu)建結(jié)果(安裝包、部署腳本、配置)發(fā)布到一個(gè)歸檔倉(cāng)庫(kù)中
- 手工測(cè)試、用戶演示等:任何需要新建一個(gè)環(huán)境的人員,可以使用已歸檔的安裝包、部署腳本和配置文件在 Amazon EC2 上自動(dòng)化的創(chuàng)建出來(lái)一個(gè)環(huán)境;
- 準(zhǔn)生產(chǎn)環(huán)境、生產(chǎn)環(huán)境:生產(chǎn)環(huán)境是部署在數(shù)據(jù)中心的 VMware 虛擬機(jī)上,當(dāng)業(yè)務(wù)人員需要發(fā)布某一版本時(shí),使用同樣的安裝包、部署腳本和配置文件,執(zhí)行自動(dòng)化的發(fā)布。
這樣任何人所作的修改都會(huì)得到一個(gè)漸進(jìn)的增強(qiáng),流水線走的越遠(yuǎn),團(tuán)隊(duì)得到的信心就越強(qiáng)。這種信心不僅僅只限于我們的代碼功能實(shí)現(xiàn)的正確性,更重要是對(duì)我們的產(chǎn)品能夠順利部署上線的信心。
總結(jié)
在自動(dòng)化測(cè)試和持續(xù)集成之上,我們通過(guò)“部署流水線”可以實(shí)現(xiàn)持續(xù)交付的能力??赡軐?duì)于國(guó)內(nèi)某些項(xiàng)目團(tuán)隊(duì),特別是遺留系統(tǒng),還需要付出很多努力。但是可以逐步實(shí)施,一步一步打造每一個(gè)過(guò)程。云和虛擬化技術(shù)給我們提供了一個(gè)自動(dòng)化基礎(chǔ)設(shè)施管理的能力,很大的幫助了我們持續(xù)交付中的每一個(gè)過(guò)程,最終達(dá)到了將團(tuán)隊(duì)每一個(gè)成員的工作能夠順利的轉(zhuǎn)化為線上的商業(yè)價(jià)值。
it知識(shí)庫(kù):使用云和虛擬化技術(shù)實(shí)現(xiàn)持續(xù)交付,轉(zhuǎn)載需保留來(lái)源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。