田 源,李 樊,汪曉臣,趙偉慧,黃志威
(1. 中國(guó)鐵道科學(xué)研究院集團(tuán)有限公司 電子計(jì)算技術(shù)研究所, 北京 100081;2. 軌道交通系統(tǒng)測(cè)試國(guó)家工程實(shí)驗(yàn)室, 北京 100081)
乘客信息系統(tǒng)(PIS)采用中心-車站-車載的多層級(jí)架構(gòu),由控制中心統(tǒng)一管理各級(jí)設(shè)備[1]。目前的軟件部署采用單機(jī)拷貝安裝方式,面對(duì)數(shù)量龐大的設(shè)備集群,需要逐個(gè)設(shè)備安裝調(diào)試。部署過(guò)程中容易暴露出諸多弊端,如軟件運(yùn)行環(huán)境配置導(dǎo)致的未知錯(cuò)誤;單機(jī)拷貝和配置的安裝方式耗費(fèi)人力;軟件版本升級(jí)或同步容易出錯(cuò);應(yīng)用與數(shù)據(jù)的耦合性較緊;硬件設(shè)備更換后,軟件需重新部署等。
目前,Docker技術(shù)在越來(lái)越多的場(chǎng)景中得到了應(yīng)用。張兆晨等人[2]設(shè)計(jì)了一種持續(xù)集成系統(tǒng),利用Docker的鏡像封裝和輕量級(jí)特性,取代了傳統(tǒng)持續(xù)集成系統(tǒng)的虛擬機(jī)架構(gòu),提升了開(kāi)發(fā)效率,降低了系統(tǒng)占用資源;鄒保平等人[3]通過(guò)與傳統(tǒng)虛擬機(jī)比較的方式,驗(yàn)證了Docker容器化部署應(yīng)用的敏捷性;姚煒等人[4]在傳統(tǒng)開(kāi)發(fā)平臺(tái)中引入Docker技術(shù),簡(jiǎn)化了從開(kāi)發(fā)到部署的繁雜配置,有效提升了項(xiàng)目的發(fā)布速度。綜上所述,基于Docker的容器化部署方案適用于開(kāi)發(fā)與發(fā)布緊密結(jié)合、安裝配置繁雜的軟件部署場(chǎng)景。Docker技術(shù)的引入,將有效解決當(dāng)下乘客信息系統(tǒng)中軟件部署的諸多難點(diǎn)。
在乘客信息系統(tǒng)中,傳統(tǒng)的應(yīng)用軟件部署方式是通過(guò)存儲(chǔ)介質(zhì)或網(wǎng)絡(luò)傳輸?shù)姆绞?,拷貝軟件安裝包至目標(biāo)機(jī)。然后在操作系統(tǒng)中配置軟件運(yùn)行所需的依賴環(huán)境,安裝軟件并進(jìn)行配置,執(zhí)行二進(jìn)制文件或腳本來(lái)運(yùn)行程序,提供軟件服務(wù)。乘客信息系統(tǒng)中,車站設(shè)備數(shù)量多達(dá)上百臺(tái),分布距離較遠(yuǎn),逐個(gè)設(shè)備部署、安裝、調(diào)試的工作量非常巨大,后期對(duì)于軟件的部署架構(gòu)調(diào)整和版本維護(hù)都不友好。
容器是輕量級(jí)的操作系統(tǒng)級(jí)虛擬化。它可以實(shí)現(xiàn)在一個(gè)資源隔離的進(jìn)程中運(yùn)行應(yīng)用及其依賴項(xiàng)[5]。應(yīng)用程序與其所依賴的環(huán)境,可以被封裝成鏡像,并可以復(fù)用。應(yīng)用需要被部署到目標(biāo)機(jī)時(shí),僅需在目標(biāo)機(jī)上獲取鏡像,將其實(shí)例化為容器進(jìn)程,運(yùn)行即可。當(dāng)軟件或依賴環(huán)境產(chǎn)生變化,只需更新鏡像即可。如此,將操作系統(tǒng)與應(yīng)用程序相關(guān)的環(huán)境獨(dú)立開(kāi),可降低部署難度,提升軟件的可維護(hù)性,保證線路軟件部署質(zhì)量的統(tǒng)一性。容器技術(shù)具有以下優(yōu)勢(shì):
(1)敏捷環(huán)境:容器的啟動(dòng)速度快,更新便捷。
(2)高效生產(chǎn):開(kāi)發(fā)人員不用擔(dān)心生產(chǎn)環(huán)境下特殊的運(yùn)行環(huán)境,實(shí)現(xiàn)一處調(diào)試,處處運(yùn)行的高質(zhì)量軟件發(fā)布效果。
(3)版本控制:容器必須由鏡像生成,鏡像的版本唯一決定了運(yùn)行容器的一致性。
(4)輕便:鏡像文件占用空間小,且僅包含應(yīng)用程序和關(guān)鍵依賴,方便軟件歸檔和版本分發(fā)。
Linux 容器( LXC,Linux Container)是一個(gè)在單一 Linux 主機(jī)上提供多個(gè)隔離的Linux 環(huán)境的操作系統(tǒng)級(jí)虛擬技術(shù)[6]。Docker是一個(gè)基于LXC 的高級(jí)容器引擎[7]。Docker的沙箱機(jī)制有效的隔離各個(gè)用戶實(shí)例,多容器共享系統(tǒng)內(nèi)核的特性使得Docker實(shí)例輕量化,便于部署[8]。
Docker服務(wù)部署在宿主機(jī)操作系統(tǒng)之上。如圖1所示,Docker將應(yīng)用及其依賴環(huán)境封裝在容器中運(yùn)行。容器是操作系統(tǒng)為不同的用戶或進(jìn)程分配的具有一定相互獨(dú)立空間(包括內(nèi)存分頁(yè)空間、CPU時(shí)鐘分配、硬盤空間、進(jìn)程空間、運(yùn)行庫(kù)等、IP地址)。
本文在傳統(tǒng)乘客信息系統(tǒng)的架構(gòu)之上,引入Docker虛擬化技術(shù)。軟件供應(yīng)商將既有應(yīng)用軟件進(jìn)行鏡像封裝,依據(jù)Docker私有倉(cāng)庫(kù)(Registry)規(guī)范,搭建一套應(yīng)用軟件管理系統(tǒng)。
圖 1 Docker技術(shù)架構(gòu)
該系統(tǒng)接入中心機(jī)房的核心交換機(jī),負(fù)責(zé)管理乘客信息系統(tǒng)全部的應(yīng)用鏡像,并向各層級(jí)設(shè)備群提供鏡像下載服務(wù),如圖2所示。
圖 2 基于Docker的乘客信息系統(tǒng)部署架構(gòu)
應(yīng)用軟件管理系統(tǒng)由軟件倉(cāng)庫(kù)管理工作站和軟件倉(cāng)庫(kù)服務(wù)器組成。軟件供應(yīng)商提供初始的Docker鏡像。鏡像文件經(jīng)管理工作站,推送至軟件倉(cāng)庫(kù)服務(wù)器。軟件倉(cāng)庫(kù)服務(wù)器宜采用主備集群策略,保證倉(cāng)庫(kù)鏡像存儲(chǔ)的高可靠性。結(jié)合Docker輕量、敏捷的技術(shù)特性,設(shè)備可在較短時(shí)間內(nèi)完成部署任務(wù),或從故障狀態(tài)中快速的恢復(fù)。同時(shí),該架構(gòu)提供了云端應(yīng)用級(jí)的容災(zāi)方案。
控制中心服務(wù)器集群、車站子系統(tǒng)設(shè)備群和車載子系統(tǒng)設(shè)備群的各設(shè)備需預(yù)置Docker環(huán)境,通過(guò)pull或run方式下載或更新軟件鏡像,如圖3所示。
圖 3 軟件鏡像部署與運(yùn)行流程
虛線(1)所示是pull指令的數(shù)據(jù)傳遞流程。部署人員在操作系統(tǒng)中使用CLI指令向Docker守護(hù)進(jìn)程發(fā)送拉取鏡像A的指令,守護(hù)進(jìn)程從軟件倉(cāng)庫(kù)服務(wù)器獲取對(duì)應(yīng)的鏡像A。
實(shí)線(2)所示是鏡像的實(shí)例化過(guò)程。運(yùn)行指令傳遞給Docker守護(hù)進(jìn)程后,守護(hù)進(jìn)程會(huì)將鏡像A在本地實(shí)例化為容器A-1,并返回一個(gè)用于訪問(wèn)容器的虛擬會(huì)話。容器A-1在宿主機(jī)后臺(tái)運(yùn)行,通過(guò)端口映射向外部提供應(yīng)用服務(wù)。
通過(guò)上述流程,基于Docker的私有倉(cāng)庫(kù)和應(yīng)用容器化技術(shù),系統(tǒng)實(shí)現(xiàn)了應(yīng)用軟件從云端備份到本地運(yùn)行的無(wú)縫結(jié)合。
鏡像是一個(gè)用于創(chuàng)建Docker容器的只讀模板。鏡像的制作方式有2種。
(1)容器提交(docker commit)
選擇合適的基礎(chǔ)鏡像,啟動(dòng)一個(gè)可交換的容器。進(jìn)入其中,安裝需要的依賴環(huán)境和軟件包。然后,退出容器。使用docker commit指令,將容器中的全部修改提交,形成一份新的鏡像。
(2)鏡像構(gòu)建(docker build)
建立鏡像首先需要?jiǎng)?chuàng)建一個(gè)Dockerfile文件。根據(jù)語(yǔ)法,在Dockerfile文件中定義了創(chuàng)建和運(yùn)行鏡像的必要指令。Dockerfile中的每一條指令都會(huì)在鏡像中創(chuàng)建一個(gè)獨(dú)立層,當(dāng)Dockerfile內(nèi)容發(fā)生變更需要重新構(gòu)建時(shí),只有變更的地方會(huì)被重建,因此,與其他虛擬化技術(shù)相比,Docker鏡像顯得更加輕量、小巧和快速。
上述兩種鏡像的生成方式優(yōu)缺點(diǎn)對(duì)比如表1所示。乘客信息系統(tǒng)的應(yīng)用軟件多為定制化較強(qiáng)的專用軟件,軟件依賴環(huán)境特殊,版本控制嚴(yán)格。在應(yīng)用軟件的鏡像制作中,針對(duì)不同軟件類型,應(yīng)制作不同的鏡像。
考慮到應(yīng)用軟件依賴環(huán)境的多元化,對(duì)于依賴環(huán)境定制程度不高的應(yīng)用軟件類型,可以通過(guò)Dockerfile構(gòu)建鏡像。Dockerfile模板可擴(kuò)展后服務(wù)于多個(gè)鏡像構(gòu)建,易于版本迭代和鏡像維護(hù)。
表 1 兩種Docker鏡像制作方式比較
對(duì)于依賴環(huán)境定制程度高的應(yīng)用軟件類型,宜在既有容器逐步調(diào)試依賴環(huán)境,生成穩(wěn)定可用的鏡像。當(dāng)軟件版本或依賴環(huán)境需要變更時(shí),在前一鏡像版本的基礎(chǔ)上,進(jìn)入容器修改,通過(guò)鏡像迭代完成版本升級(jí)和軟件維護(hù)。
容器是鏡像的實(shí)例。通過(guò)Docker API或CLI(Command Line Interface),可以創(chuàng)建、啟動(dòng)、停止、移動(dòng)或刪除一個(gè)容器。默認(rèn)情況下,一個(gè)容器與其他容器、宿主機(jī)之間是相互隔離的。由于Docker引對(duì)卷掛載和端口映射的良好支持,容器可以通過(guò)外部存儲(chǔ)的掛載(-v參數(shù)),或映射網(wǎng)絡(luò)端口(-p參數(shù)),與宿主機(jī)或外部設(shè)備進(jìn)行通信。
3.2.1 端口映射
在乘客信息系統(tǒng)中,應(yīng)用軟件的實(shí)現(xiàn)都建立在網(wǎng)絡(luò)通信技術(shù)的基礎(chǔ)上。應(yīng)用軟件容器化后,如何將容器內(nèi)端口映射至宿主機(jī)是首要任務(wù)。
Docker容器運(yùn)行時(shí),通過(guò)-p參數(shù),可以將容器內(nèi)的網(wǎng)絡(luò)端口映射至宿主機(jī)端口,實(shí)現(xiàn)網(wǎng)絡(luò)通信的功能。對(duì)于多網(wǎng)卡宿主機(jī),可以通過(guò)指定宿主機(jī)IP的方式,將容器內(nèi)端口映射至指定網(wǎng)卡的端口。下述指令實(shí)現(xiàn)了將nginx容器的80端口映射至宿主機(jī)配置IP為192.168.1.10網(wǎng)卡的8090端口。
docker run -p 192.168.1.10:8090:80 -d nginx:latest
3.2.2 數(shù)據(jù)持久化
Dokcer鏡像是一堆只讀層的集合。容器實(shí)例化過(guò)程,是在只讀鏡像層基礎(chǔ)上,建立一層可讀寫(xiě)的容器層。以鏡像為模板,創(chuàng)建的容器層可以通過(guò)提交指令轉(zhuǎn)換為只讀層,形成新的鏡像。若不提交,在容器退出后,docker服務(wù)進(jìn)程會(huì)將容器層移除。
綜上所述,由鏡像創(chuàng)建出的容器,其運(yùn)行過(guò)程中的狀態(tài)不會(huì)持久保存。所以,在實(shí)現(xiàn)例如數(shù)據(jù)庫(kù)等應(yīng)用的容器化時(shí),除了端口映射,還需要保證數(shù)據(jù)的持久化。通過(guò)-v參數(shù),將容器中的/var/lib/mysql文件夾映射至宿主機(jī)本地文件夾。
docker run -d -p 3306:3306 -v /usr/local/mysql/data:/var/lib/mysql mysql:latest
3.2.3 圖像傳輸
乘客信息系統(tǒng)的終端設(shè)備需要提供媒體和信息服務(wù),媒體播放應(yīng)用程序需要圖形化界面顯示圖形和文字信息。Docker容器中應(yīng)用的圖形化顯示,可以利用X11服務(wù)實(shí)現(xiàn)。容器運(yùn)行命令中使用-v參數(shù),可以掛載容器的X11的unix套接字到宿主機(jī),同時(shí)通過(guò)-e參數(shù),更改宿主機(jī)的DISPLAY環(huán)境變量,控制圖形輸出至宿主機(jī)。
docker run -e DISPLAY=unix$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix myGuiApp
在Docker容器與宿主機(jī)間,X11通信數(shù)據(jù)流如圖4所示。
圖 4 容器應(yīng)用圖像傳輸流程示意圖
應(yīng)用軟件管理系統(tǒng)由軟件倉(cāng)庫(kù)服務(wù)器和軟件倉(cāng)庫(kù)管理工作站組成。軟件倉(cāng)庫(kù)是應(yīng)用軟件的Docker鏡像的集合,位于控制中心,向中心服務(wù)器、車站服務(wù)器和車站播控提供鏡像下載服務(wù)。為了實(shí)現(xiàn)倉(cāng)庫(kù)存儲(chǔ)鏡像數(shù)據(jù)的持久化,需要將倉(cāng)庫(kù)存儲(chǔ)掛載至宿主機(jī),即軟件倉(cāng)庫(kù)服務(wù)器的本地目錄。
軟件倉(cāng)庫(kù)的界面化管理平臺(tái)基于開(kāi)源軟件實(shí)現(xiàn),平臺(tái)采用B/S架構(gòu)。運(yùn)維人員通過(guò)軟件倉(cāng)庫(kù)管理工作站,可以實(shí)現(xiàn)鏡像上傳、鏡像更新、鏡像標(biāo)簽編輯,鏡像移除、鏡像備份等操作,避免了在工作站環(huán)境下安裝Docker環(huán)境和CLI訪問(wèn)倉(cāng)庫(kù)的繁雜步驟。
本文提出了一種基于容器技術(shù)的軟件部署方案。通過(guò)容器化設(shè)計(jì)降低了應(yīng)用程序與運(yùn)行環(huán)境的耦合性,簡(jiǎn)化了系統(tǒng)安裝與部署流程,保證了軟件運(yùn)行的可靠性,有助于降低人力成本和維護(hù)難度。但是本文提出的軟件容器化部署方案,僅從操作系統(tǒng)層面實(shí)現(xiàn)了資源節(jié)約,未來(lái)可進(jìn)一步研究基于硬件資源平臺(tái)的虛擬化方案,對(duì)系統(tǒng)級(jí)的云平臺(tái)構(gòu)建提出設(shè)計(jì)方案。