摘要
傳統(tǒng)的虛擬化技術(shù)僅提供了從物理機(jī)到操作系統(tǒng)級的虛擬化服務(wù),而正在如火如荼發(fā)展的Docker容器技術(shù)做到了在系統(tǒng)級虛擬化之上,對應(yīng)用服務(wù)進(jìn)行方便的管理。但是當(dāng)開發(fā)者需要測試和上線Web應(yīng)用時(shí),由于版本迭代問題,常需要手動(dòng)進(jìn)行重新部署。本文基于Docker對于應(yīng)用服務(wù)的快速發(fā)布和部署能力,結(jié)合已有的jenkins持續(xù)集成服務(wù),嘗試對Web應(yīng)用的持續(xù)集成進(jìn)行探究。
正文
持續(xù)集成既能夠?qū)崿F(xiàn)代碼頻繁集成,進(jìn)行頻繁迭代測試,通過頻繁構(gòu)建盡發(fā)現(xiàn)問題,從而在保證軟件質(zhì)量的同時(shí)加速軟件開發(fā)的過程。
持續(xù)集成不是用來防止代碼缺陷的出現(xiàn),但是它能夠在軟件開發(fā)前期盡早發(fā)現(xiàn)代碼缺陷,使修復(fù)缺陷變得相對輕松簡單。
Jenkins就是一個(gè)持續(xù)集成的開源軟件項(xiàng)目,旨在提供一個(gè)開放易用的軟件平臺(tái),使軟件的持續(xù)集成變成可能。其基本工作流程如圖1所示,開發(fā)者提交代碼更新,Jenkins通過鉤子監(jiān)聽源碼管理工具獲取最新代碼。根據(jù)創(chuàng)建好的Jenkins任務(wù)及編寫好的執(zhí)行腳本依次完成代碼構(gòu)建、打包、部署、集成測試過程,最后把構(gòu)建后的結(jié)果包括自動(dòng)化測試的結(jié)果通過郵件發(fā)送給相關(guān)負(fù)責(zé)人。

而Docker 是一個(gè)基于LXC(Linux Containers)虛擬化技術(shù)的高級容器引擎,使用Go語言實(shí)現(xiàn)的一種面向云平臺(tái)的虛擬化技術(shù)。它是一款開源的應(yīng)用容器引擎,讓開發(fā)者可以打包他們的應(yīng)用以及依賴包到一個(gè)可移植的容器中,然后發(fā)布到任何流行的 Linux 機(jī)器上,也可以實(shí)現(xiàn)虛擬化。容器是完全使用沙箱機(jī)制,相互之間不會(huì)有任何接口。因此它具有啟動(dòng)時(shí)間短,空間占用少、分發(fā)和復(fù)制方便、資源開銷少等特點(diǎn),卻具備和傳統(tǒng)虛擬機(jī)一樣的隔離性和安全性。
在這里的代碼更新和版本控制過程中,使用Git工具來作為代碼同步更新工具。開發(fā)人員完成本地代碼開發(fā)后,先通過命令或Git工具把代碼提交到分支上,再將分支代碼推送到項(xiàng)目經(jīng)理處進(jìn)行代碼審核,審核成功后再把代碼推送到主干。一旦Git倉庫有更新后,Jenkins服務(wù)器會(huì)拉取新代碼進(jìn)行集成構(gòu)建。Github的主要工作模式如圖2所示。

這里有一個(gè)需要注意的是,Docker 跟Jenkins并沒有直接的聯(lián)系,Jenkins是實(shí)現(xiàn)自動(dòng)打包的,打包完也是可以實(shí)現(xiàn)自動(dòng)部署的,并不是沒有Docker 就不可以實(shí)現(xiàn)自動(dòng)部署了,這里需要強(qiáng)調(diào)一點(diǎn)。之所以用Docker,是因?yàn)镈ocker 是一個(gè)相比較而言比較成熟的一種技術(shù),而且它的優(yōu)勢在于,可以實(shí)現(xiàn)隔離,可以在不同的操作系統(tǒng)跑應(yīng)用(Windows,Linux)并且還可以做到日志分離。
傳統(tǒng)的Web應(yīng)用從開發(fā)到上線的過程,需要開發(fā)者手動(dòng)將開發(fā)好的工程部署到服務(wù)器上。在服務(wù)器上的相關(guān)環(huán)境和配置都需要開發(fā)者自己動(dòng)手進(jìn)行解決,同時(shí)需要解決很多形形色色與Web服務(wù)本身可能沒有太大關(guān)系的問題。另外,如果開發(fā)者對于開發(fā)版本有修改和迭代更新,每次需要手動(dòng)去在服務(wù)器上更新代碼,并且如果是一個(gè)負(fù)載均衡集群的場景下,需要一臺(tái)一臺(tái)服務(wù)器進(jìn)行更新代碼,這樣的工作量是很大的,并且都是重復(fù)性的勞動(dòng)。
在這里,通過已有資料和文獻(xiàn),結(jié)合Jenkins和Docker各自的優(yōu)點(diǎn),探究兩者集成后對Web自動(dòng)部署快捷性方面的作用,簡化Web部署為以下流程:
提交代碼
獲取代碼
構(gòu)建環(huán)境
自動(dòng)部署
Jenkins是基于Java環(huán)境的,因此在宿主機(jī)中需要安裝Java環(huán)境支持,另外,宿主機(jī)中還需要安裝Git工具和Docker。此處的系統(tǒng)實(shí)驗(yàn)環(huán)境為Centos7.4。

首先安裝Java環(huán)境,這里使用Java1.8的版本,查看版本可以看到,具體的安裝版本是

并且由于Jenkins需要Tomcat的支持,同時(shí)下載Tomcat9的版本進(jìn)行安裝。


接下來下載Jenkins的war包,war包內(nèi)是Jenkins的所有內(nèi)容。可以通過直接部署在安裝好的Tomcat9中來通過Web形式訪問。Jenkins第一次啟動(dòng)需要進(jìn)行安裝,包括其中的Folders Plugin、Script Security Plugin等插件,安裝完成后需要進(jìn)行用戶配置,用戶名和密碼是自定義的。



Git工具是必不可少的,由于對于版本沒有太大的要求,可以直接通過自帶的yum包管理進(jìn)行下載,安裝git。通過在Github上建立一個(gè)測試工程,向此測試工程中更新推送Web服務(wù)的代碼,Jenkins通過監(jiān)聽指定的Github地址,來自動(dòng)獲取Github上的最新代碼,自動(dòng)執(zhí)行Shell來調(diào)用Docker進(jìn)行代碼到鏡像的部署和啟動(dòng)工作。

最重要的是Docker的安裝和基礎(chǔ)鏡像的搭建。由于Centos7中帶的yum源中,docker版本已經(jīng)是比較新的1.12,可以直接通過yum install docker.io來安裝。安裝完成之后,需要為持續(xù)集成部署的Web服務(wù)提供一個(gè)基礎(chǔ)的網(wǎng)站服務(wù)器環(huán)境鏡像,之后的Jenkins工作可以直接基于此已有的基礎(chǔ)鏡像來進(jìn)行。
由于僅僅是探究Docker和Jenkins的結(jié)合,這里僅僅使用靜態(tài)頁面的更新來進(jìn)行測試,因此基礎(chǔ)環(huán)境不使用Tomcat和Java的JDK,而是選擇一個(gè)nginx的環(huán)境。

通過docker search nginx命令來查找hub上已經(jīng)存在的nginx環(huán)境鏡像,選定一個(gè)nginx環(huán)境鏡像,下載此已有的nginx環(huán)境鏡像,在此基礎(chǔ)上進(jìn)行修改,可以較快速地得到可以用于部署Web的環(huán)境。

在Git工具、Docker以及Jenkins都已經(jīng)安裝完成并且準(zhǔn)備就緒后,可以開始集成和整合。首先需要在Jenkins中創(chuàng)建一個(gè)工程,并且將其命名為test。在這里,接下里的配置文件中可以通過設(shè)置hook以及定時(shí)器來定時(shí)檢測指定的Github項(xiàng)目的更新變化,進(jìn)行觸發(fā)拉取動(dòng)作,如圖14中的第一個(gè)和最后一個(gè)選項(xiàng)。在這里,因?yàn)閮H僅是測試,不開啟自動(dòng)拉取,使用執(zhí)行構(gòu)建。

配置的最后,是可以在項(xiàng)目拉取完成和構(gòu)建后,執(zhí)行的shell命令配置。而這段shell的配置,是在這里探究Jenkins和Docker集成進(jìn)行Web自動(dòng)部署的關(guān)鍵之處。
在nginx鏡像中,使用的nginx的html默認(rèn)目錄在/usr/share/nginx/html下。Jenkins的默認(rèn)代碼下載在/root/.jenkins/workspace/下,因此在每次Jenkins從Github上獲得更新代碼后,直接執(zhí)行shell腳本,將下載的Web的代碼的路徑映射到nginx鏡像中的html默認(rèn)目錄中即可。并且在每次執(zhí)行shell時(shí),都先刪除docker中上一次已經(jīng)運(yùn)行的實(shí)例容器,進(jìn)行新的目錄內(nèi)容映射后,再次創(chuàng)建新的容器。

因此最后形成的完整shell代碼如圖14,保存后配置生效。

最后進(jìn)行Web應(yīng)用的自動(dòng)部署測試。在Github新建一個(gè)項(xiàng)目,內(nèi)容只有一個(gè)test.html,內(nèi)容是“jenkins測試”。在Jenkins的test工程配置中添加此git地址,并且保存配置。


配置保存后執(zhí)行構(gòu)建,構(gòu)建完成后訪問頁面,得到內(nèi)容為“jenkins測試”,如圖17。

開發(fā)本地修改test.html的內(nèi)容為“測試持續(xù)集成”后,使用git push向github更新代碼,并且再次在Jenkins上構(gòu)建,再次訪問服務(wù)器后,網(wǎng)頁內(nèi)容已經(jīng)更換。查看Jenkins輸出日志和頁面結(jié)果如圖21、圖22。




通過上述Jenkins和Docker配合Git實(shí)現(xiàn)Web應(yīng)用的快速部署更新,可以看到其效率可以大幅提高。開發(fā)者只需要向Git項(xiàng)目地址提交代碼,Jenkins執(zhí)行構(gòu)建即可自動(dòng)完成部署等操作,并且如果在Jenkins中配置了Hook鉤子和定時(shí)器抓取的設(shè)置,身子可以節(jié)省手動(dòng)Jenkins的構(gòu)建過程,給開發(fā)者的開發(fā)和Web應(yīng)用服務(wù)的部署帶來了極大的便利。
參考文獻(xiàn):
尹高. 基于Docker的服務(wù)器運(yùn)維平臺(tái)的設(shè)計(jì)與實(shí)現(xiàn)[D]. 華中科技大學(xué), 2016.
邊俊峰. 基于Docker的資源調(diào)度及應(yīng)用容器集群管理系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[D]. 山東大學(xué), 2017.
鐘良侃. Docker技術(shù)在Web服務(wù)系統(tǒng)中的應(yīng)用研究[J]. 電腦知識與技術(shù), 2016, 12(26):123-126.
張力文. 基于Jenkins的項(xiàng)目持續(xù)集成方案研究與實(shí)現(xiàn)[D]. 西南交通大學(xué), 2017.