翁湦元,單杏花,閻志遠(yuǎn),王雪峰
(中國鐵道科學(xué)研究院集團(tuán)有限公司 電子計(jì)算技術(shù)研究所,北京 100081)
隨著鐵路信息技術(shù)的不斷發(fā)展,旅客在對(duì)鐵路出行滿意度要求不斷提高的同時(shí),對(duì)客運(yùn)延伸服務(wù)也提出了更高的要求。隨著多樣化旅客出行服務(wù)需求的不斷提出,鐵旅App服務(wù)平臺(tái)也在不斷添加新的業(yè)務(wù)模塊,以便為旅客提供更好、更豐富的服務(wù)[1]。
不斷增多的應(yīng)用服務(wù)數(shù)量帶來了平臺(tái)的運(yùn)維和升級(jí)問題。由于鐵旅App服務(wù)平臺(tái)采用微服務(wù)體系開發(fā),組件眾多且相互依賴,每次業(yè)務(wù)調(diào)整與升級(jí)均會(huì)涉及多個(gè)模塊的同時(shí)調(diào)整,導(dǎo)致業(yè)務(wù)升級(jí)緩慢,無法滿足快速迭代升級(jí)的要求,升級(jí)部署成功率低。平臺(tái)運(yùn)維方面,以手工操作結(jié)合輔助腳本的方式為主,出錯(cuò)率高,平臺(tái)穩(wěn)定性差。平臺(tái)各業(yè)務(wù)功能主要通過人工巡檢的方式進(jìn)行日常維護(hù),難以及時(shí)發(fā)現(xiàn)平臺(tái)故障,且故障修復(fù)周期長,增加了運(yùn)維人員的工作量和人力成本。綜上,較長的升級(jí)研發(fā)周期,較高的平臺(tái)故障率以及較高的人工運(yùn)維成本制約了平臺(tái)服務(wù)的深入開展,亟需探索提高平臺(tái)研發(fā)靈活性、穩(wěn)定性,降低運(yùn)維成本的方法。
國內(nèi)外在云平臺(tái)建設(shè)方面取得了很多重要成果,現(xiàn)階段平臺(tái)建設(shè)領(lǐng)域的容器技術(shù)和容器編排工具是各大公司的研發(fā)主流。本文根據(jù)鐵旅App自身業(yè)務(wù)需求和特點(diǎn),結(jié)合Kubernetes等開源工具搭建私有容器云平臺(tái),將原業(yè)務(wù)系統(tǒng)進(jìn)行容器化改造后遷移至云平臺(tái),以達(dá)到提高平臺(tái)靈活性、穩(wěn)定性,降低運(yùn)維成本的目的。
Docker是一個(gè)開源的應(yīng)用容器引擎,通過將應(yīng)用與相關(guān)的依賴項(xiàng)(環(huán)境、程序、文件)打包成鏡像文件,可以將其方便地部署于任何支持Docker運(yùn)行環(huán)境的主機(jī)中,最大限度地消除開發(fā)環(huán)境與部署環(huán)境的差異,結(jié)合Docker鏡像倉庫,研發(fā)人員可以便捷地管理鏡像與交付版本[2]。同時(shí),Docker與微服務(wù)架構(gòu)有著天然的契合度,因此可做為構(gòu)建容器云服務(wù)平臺(tái)的基礎(chǔ)。
對(duì)于大型企業(yè)而言,隨著系統(tǒng)平臺(tái)規(guī)模的不斷擴(kuò)大,應(yīng)用服務(wù)數(shù)量和服務(wù)器數(shù)量也逐漸增加,運(yùn)維成本不斷提高,單純依靠Docker已無法滿足系統(tǒng)運(yùn)維需求。Kubernetes是Google的開源容器集群管理解決方案,在提供強(qiáng)大的集群管理、故障檢測與自動(dòng)修復(fù)能力的同時(shí),也提供便捷的服務(wù)升級(jí)解決方案,同時(shí)支持服務(wù)的發(fā)現(xiàn)調(diào)度和彈性伸縮等特性。鑒于Kubernetes有Google強(qiáng)大的開源支撐和眾多成功應(yīng)用的案例,基于Kubernetes構(gòu)建容器云服務(wù)平臺(tái)是大型企業(yè)構(gòu)建生產(chǎn)環(huán)境容器云服務(wù)平臺(tái)的較優(yōu)選擇之一[3]。
容器云平臺(tái)部署于物理服務(wù)器之上,總體結(jié)構(gòu)由資源層、平臺(tái)層、應(yīng)用層3部分組成,如圖1所示。
圖1 容器云平臺(tái)總體架構(gòu)圖
資源層位于平臺(tái)底層,為平臺(tái)提供基本存儲(chǔ)和資源管理能力,包含用于代碼版本管理的SVN,用于構(gòu)建Maven和Docker鏡像倉庫的Nexus,以及文件存儲(chǔ)服務(wù)。
平臺(tái)層包括容器云平臺(tái)的核心組件,如:集群監(jiān)控程序,用于提供容器鏡像基本運(yùn)行能力的Docker工具,為Docker統(tǒng)一編排與調(diào)度能力的Kubernetes,用于將項(xiàng)目構(gòu)建為容器鏡像并上傳至Nexus倉庫中的Jenkins。
應(yīng)用層最接近用戶,用于部署為用戶開發(fā)的業(yè)務(wù)應(yīng)用,以及定制化的集群控制軟件等。
容器云平臺(tái)從項(xiàng)目全生命周期支持和自動(dòng)化運(yùn)維支持2個(gè)方面為開發(fā)人員提供服務(wù)。項(xiàng)目全生命周期支持包括代碼管理、持續(xù)構(gòu)建[4]、環(huán)境隔離、統(tǒng)一部署等多個(gè)功能,覆蓋項(xiàng)目啟動(dòng)研發(fā)至部署上線全生命周期;自動(dòng)化運(yùn)維支持包括平臺(tái)監(jiān)控工具、故障自動(dòng)恢復(fù)和水平擴(kuò)容支持等功能,為運(yùn)維人員提供了高效便捷的自動(dòng)化工具。
2.2.1 項(xiàng)目全生命周期支持
容器云平臺(tái)圍繞項(xiàng)目全生命周期為研發(fā)人員提供如下服務(wù)。
(1)代碼管理
云平臺(tái)內(nèi)使用SVN作為代碼版本管理與協(xié)同開發(fā)的基礎(chǔ),項(xiàng)目研發(fā)人員統(tǒng)一將代碼提交至SVN進(jìn)行代碼存儲(chǔ)。該功能是項(xiàng)目構(gòu)建的基礎(chǔ)。
(2)持續(xù)構(gòu)建
云平臺(tái)內(nèi)使用Jenkins作為持續(xù)構(gòu)建工具,通過定制的定時(shí)觸發(fā)和手動(dòng)觸發(fā)機(jī)制,從SVN代碼倉庫中提取最新的項(xiàng)目源碼進(jìn)行構(gòu)建、打包并推送至鏡像倉庫進(jìn)行存儲(chǔ),以便后續(xù)使用。
(3)環(huán)境隔離
云平臺(tái)利用Kubernetes命名空間資源隔離的特性為研發(fā)人員提供研發(fā)、預(yù)發(fā)布和生產(chǎn)環(huán)境,3個(gè)環(huán)境彼此隔離部署,使研發(fā)人員可以更安全地測試新業(yè)務(wù)而不影響線上正在運(yùn)行的既有服務(wù)。
(4)統(tǒng)一部署工具
云平臺(tái)提供統(tǒng)一的項(xiàng)目發(fā)布工具,保持了平臺(tái)內(nèi)項(xiàng)目結(jié)構(gòu)的一致性,同時(shí)也將研發(fā)人員從Kubernetes工具繁瑣的操作流程中解放出來,降低了對(duì)研發(fā)人員的技術(shù)要求。統(tǒng)一的項(xiàng)目發(fā)布工具記錄了用戶的每一步操作,使得平臺(tái)應(yīng)用更新有跡可循,為潛在的業(yè)務(wù)升級(jí)故障風(fēng)險(xiǎn)提供了修復(fù)參考,統(tǒng)一部署界面如圖2所示。
2.2.2 自動(dòng)化運(yùn)維支持
(1)平臺(tái)監(jiān)控工具
云平臺(tái)監(jiān)控工具提供平臺(tái)運(yùn)行狀態(tài)、物理節(jié)點(diǎn)、應(yīng)用狀態(tài)、服務(wù)調(diào)用負(fù)載等全方位監(jiān)控指標(biāo),為運(yùn)維人員提供統(tǒng)一的監(jiān)控視圖,同時(shí)對(duì)平臺(tái)產(chǎn)生的異常提供釘釘自動(dòng)報(bào)警功能,顯著縮短了故障的發(fā)現(xiàn)時(shí)間,降低了人工巡檢成本。平臺(tái)監(jiān)控的物理節(jié)點(diǎn)及應(yīng)用層監(jiān)控截圖如圖3所示。
圖2 統(tǒng)一部署管理界面截圖
圖3 物理節(jié)點(diǎn)及應(yīng)用層監(jiān)控截圖
(2)故障自動(dòng)恢復(fù)
云平臺(tái)依賴鏡像倉庫保存了應(yīng)用的所有歷史版本,在出現(xiàn)應(yīng)用升級(jí)故障時(shí),可以及時(shí)回滾為舊版應(yīng)用。
(3)水平擴(kuò)容支持
通過容器封裝的應(yīng)用服務(wù)可以很方便地以增加副本的形式進(jìn)行水平擴(kuò)容,運(yùn)維人員僅需根據(jù)負(fù)載需求設(shè)置副本數(shù)量即可。
在云平臺(tái)的日常運(yùn)行中,不可避免會(huì)碰到節(jié)點(diǎn)失效的情況,比如,由于內(nèi)核安全漏洞、基礎(chǔ)軟件缺陷或硬件驅(qū)動(dòng)Bug,甚至潛在的硬件故障和計(jì)劃性停機(jī)維護(hù)等導(dǎo)致需要在宿主機(jī)上進(jìn)行重啟操作。容器云平臺(tái)需要采取必要的技術(shù)方案來降低節(jié)點(diǎn)重啟帶來的影響,保證容器云平臺(tái)的高可靠性。以下對(duì)部分關(guān)鍵技術(shù)方案進(jìn)行說明。
2.3.1 可靠的文件、數(shù)據(jù)存儲(chǔ)系統(tǒng)
容器云平臺(tái)中對(duì)重要文件采用CEPH分布式文件系統(tǒng)進(jìn)行存儲(chǔ),以提供更高的可靠性和擴(kuò)展性;對(duì)用戶數(shù)據(jù)采用主備方式建立數(shù)據(jù)庫集群;同時(shí),采用ETCD集群為平臺(tái)提供高性能、高可靠性、高一致性的配置數(shù)據(jù)管理服務(wù)[5]。
2.3.2 Kubernetes集群高可用部署
容器云平臺(tái)中所有的用戶應(yīng)用均運(yùn)行于Kubernetes環(huán)境之下,因此Kubernetes是容器云平臺(tái)的核心組件,對(duì)其可靠性有極高要求。鑒于Kubernetes中Master和ETCD存儲(chǔ)組件的重要性[6],在設(shè)計(jì)云平臺(tái)部署架構(gòu)時(shí),通過Active-Active的Master多節(jié)點(diǎn)模式和ETCD服務(wù)集群方式來保障Kubernetes集群的穩(wěn)定性,使得僅當(dāng)所有Master節(jié)點(diǎn)同時(shí)故障的情況下,才會(huì)影響平臺(tái)運(yùn)行,任意單節(jié)點(diǎn)宕機(jī)均不會(huì)影響集群的正常運(yùn)行。Kubernetes高可用集群結(jié)構(gòu)如圖4所示。
圖4 Kubernetes高可用集群結(jié)構(gòu)圖
2.3.3 應(yīng)用高可用部署
平臺(tái)用戶所部署的應(yīng)用均以容器的形式運(yùn)行于Kubernetes環(huán)境下,Kubernetes通過Replication Controller/Replica Set[7]服務(wù)提供應(yīng)用副本的冗余性。用戶將需要部署的應(yīng)用打包為容器鏡像,以Deployment的形式部署于Kubernetes環(huán)境之下,通過合理設(shè)置Kubernetes應(yīng)用健康檢測探針和應(yīng)用部署的副本數(shù)量即可保證應(yīng)用的可靠運(yùn)行。在出現(xiàn)節(jié)點(diǎn)故障或由于應(yīng)用本身的原因?qū)е鲁绦虮紳r(shí),Kubernetes可自動(dòng)重啟應(yīng)用或新建應(yīng)用副本,最終確保可用副本數(shù)量符合用戶設(shè)置。
2.3.4 多級(jí)監(jiān)控與自動(dòng)報(bào)警
容器云平臺(tái)分別從系統(tǒng)、平臺(tái)、應(yīng)用3個(gè)層面對(duì)平臺(tái)健康狀況進(jìn)行全方位監(jiān)控[8]。
(1)系統(tǒng)層面,在所有機(jī)器上部署Zabbix監(jiān)控客戶端,實(shí)時(shí)采集并上報(bào)宿主機(jī)和系統(tǒng)的關(guān)鍵指標(biāo),一旦發(fā)現(xiàn)故障則通過Zabbix觸發(fā)器將報(bào)警信息發(fā)送給運(yùn)維人員,以便及時(shí)排除故障。
(2)平臺(tái)層面,通過自主研發(fā)的Kubernetes管理監(jiān)控服務(wù),調(diào)用Kubernetes的ApiServer定時(shí)查詢Kubernetes集群的關(guān)鍵指標(biāo),如節(jié)點(diǎn)運(yùn)行狀態(tài)、網(wǎng)絡(luò)通信狀態(tài)、Kubernetes關(guān)鍵組件運(yùn)行狀態(tài)等[9]。一旦發(fā)現(xiàn)Kubernetes集群內(nèi)部組件出現(xiàn)異常,立即通知平臺(tái)運(yùn)維人員。
(3)應(yīng)用層面,該層面的監(jiān)控利用Kubernetes的健康狀態(tài)檢測探針機(jī)制,定期檢測應(yīng)用運(yùn)行狀態(tài),當(dāng)應(yīng)用運(yùn)行狀態(tài)發(fā)生異常時(shí),自動(dòng)重啟故障副本并通知運(yùn)維人員。
影響系統(tǒng)穩(wěn)定性的諸多原因中,人為因素也是很重要的一部分,因此需要盡可能避免人為因素造成的系統(tǒng)異常。結(jié)合容器云平臺(tái)特性,本文制定了一套開發(fā)、測試與部署的操作標(biāo)準(zhǔn)和流程[10]。
(1)研發(fā)人員應(yīng)以小步增量的方式進(jìn)行研發(fā),保持較短的構(gòu)建和測試過程,維持較高的測試版本更新頻率;
(2)所有項(xiàng)目代碼、配置、說明文檔均上傳SVN進(jìn)行版本管理,避免線下溝通和口頭溝通;
(3)設(shè)定版本里程碑,保證生產(chǎn)環(huán)境升級(jí)的有序性和計(jì)劃性,新增服務(wù)或升級(jí)服務(wù)在生產(chǎn)上線前必須通過開發(fā)環(huán)境測試和預(yù)發(fā)布環(huán)境灰度測試;
(4)通過權(quán)限設(shè)置禁止研發(fā)人員繞過統(tǒng)一部署平臺(tái)進(jìn)行越權(quán)操作;
(5)研發(fā)人員必須依賴平臺(tái)內(nèi)代碼倉庫和組件私服以保證平臺(tái)范圍內(nèi)的關(guān)鍵代碼和組件的統(tǒng)一版本管理;
(6)編寫編碼規(guī)范手冊(cè)、集群操作手冊(cè)等相關(guān)文件,對(duì)平臺(tái)使用人員進(jìn)行引導(dǎo)。
(1)利用Kubernetes的命名空間機(jī)制將平臺(tái)計(jì)算資源劃分為開發(fā)環(huán)境、預(yù)發(fā)布環(huán)境和生產(chǎn)環(huán)境3個(gè)相互獨(dú)立的子空間,實(shí)現(xiàn)不同環(huán)境的資源隔離,確保生產(chǎn)環(huán)境的安全與穩(wěn)定;
(2)研發(fā)人員將代碼托管至SVN服務(wù),在有效的版本控制機(jī)制下實(shí)現(xiàn)合作開發(fā);
(3)Jenkins組件負(fù)責(zé)定期提取SVN上的代碼,并按照項(xiàng)目配置構(gòu)建應(yīng)用鏡像,上傳至Nexus鏡像倉庫并打上相應(yīng)的版本標(biāo)簽;
(4)在開發(fā)與測試階段,研發(fā)人員與測試人員均在開發(fā)環(huán)境下對(duì)正處于開發(fā)過程中的程序進(jìn)行部署、升級(jí)、測試和調(diào)整,研發(fā)人員通過自主研發(fā)的Kubernetes管理服務(wù)統(tǒng)一進(jìn)行應(yīng)用的部署與升級(jí)操作。
(5)新版發(fā)布階段,運(yùn)維人員首先在預(yù)發(fā)布環(huán)境下部署最新版本的生產(chǎn)程序,并適當(dāng)引入少量生產(chǎn)環(huán)境的流量進(jìn)行灰度測試。
(6)當(dāng)灰度測試通過后將新版本程序正式部署于生產(chǎn)環(huán)境,并最終完成程序的研發(fā)迭代過程。
系統(tǒng)研發(fā)的迭代流程如圖5所示。
圖5 研發(fā)流程示意圖
容器云平臺(tái)設(shè)計(jì)與搭建完畢后,將鐵旅App服務(wù)的業(yè)務(wù)系統(tǒng)進(jìn)行遷移測試,得到如下實(shí)施效果。
(1)應(yīng)用部署效率提高
不同于原來手動(dòng)拷貝副本并重啟應(yīng)用的升級(jí)方式,在容器云平臺(tái)內(nèi)部署應(yīng)用僅需在管理界面選擇自動(dòng)構(gòu)建好的應(yīng)用鏡像并填入所需的副本數(shù)量即可,其余工作全部由Kubernetes自動(dòng)完成。顯著降低部署難度,提升成功率,使原本3~5天1次的升級(jí)頻率提升為1天多次,且不影響服務(wù)的穩(wěn)定性。更高的部署效率令后臺(tái)可以更迅速地響應(yīng)產(chǎn)品需求,更快地推出更新、更完善的服務(wù)。
(2)服務(wù)故障率下降
借助容器云平臺(tái)的高可用架構(gòu)設(shè)計(jì),可以實(shí)現(xiàn)有效冗余和故障自動(dòng)恢復(fù),不再發(fā)生由于機(jī)器故障導(dǎo)致后臺(tái)無可用服務(wù)實(shí)例的情況,后臺(tái)服務(wù)整體穩(wěn)定性得到顯著提升。
(3)系統(tǒng)監(jiān)控能力提升
得益于容器云平臺(tái)的多級(jí)監(jiān)控機(jī)制,運(yùn)維人員可以實(shí)現(xiàn)對(duì)系統(tǒng)、平臺(tái)、應(yīng)用的全方位監(jiān)控,監(jiān)控可以細(xì)化至每一個(gè)節(jié)點(diǎn)和應(yīng)用實(shí)例。監(jiān)控指標(biāo)更加豐富,同時(shí)借助消息推送渠道,使軟硬件故障通知更為及時(shí),響應(yīng)更加迅速。
(4)人員成本下降
容器云平臺(tái)將運(yùn)維人員從大量繁瑣的手動(dòng)操作步驟中解放出來,減少了大量原本需要手動(dòng)記錄的部署信息,有效減少了運(yùn)維人員的工作量。
容器云平臺(tái)基于Kubernetes技術(shù)將研發(fā)與運(yùn)維人員從繁瑣的手工操作中解放出來,同時(shí),為系統(tǒng)后臺(tái)提供了高可靠性、失敗冗余和容災(zāi)恢復(fù)等性能。容器云平臺(tái)在鐵旅App業(yè)務(wù)系統(tǒng)服務(wù)后臺(tái)的改造實(shí)踐中取得了良好效果。對(duì)于在大規(guī)模并發(fā)訪問和業(yè)務(wù)負(fù)載波動(dòng)劇烈的情況下,如何應(yīng)用Kubernetes技術(shù)做到彈性自動(dòng)擴(kuò)容和動(dòng)態(tài)分配系統(tǒng)資源仍待進(jìn)一步研究。