李從凡 梁燕飛 廣東利通科技投資有限公司智能交通研究院
ETC車道系統(tǒng)是高速公路深化收費(fèi)公路制度改革、取消省界站后車輛通行高速公路費(fèi)用收取的主要手段,而整個(gè)收費(fèi)過(guò)程,是由ETC車道軟件自動(dòng)完成。由于高速公路收費(fèi)站在地理位置上分布較為分散,且ETC車道數(shù)量龐大,傳統(tǒng)的ETC車道軟件為單體程序,每當(dāng)版本升級(jí)時(shí),往往需要運(yùn)維人員到達(dá)現(xiàn)場(chǎng)關(guān)閉車道后進(jìn)行部署,費(fèi)時(shí)費(fèi)力;而且為了減少對(duì)車輛通行的干擾,只能選擇車流量小時(shí)逐條更新,效率較低;遇到版本升級(jí)頻繁時(shí),給運(yùn)維工作造成巨大的壓力。ETC車道軟件版本升級(jí)工作成本高且周期長(zhǎng),是日常運(yùn)維的一大痛點(diǎn)。
在理想的情況下,用戶希望ETC車道軟件時(shí)時(shí)刻刻都是可用的,為了滿足不斷變化的新業(yè)務(wù),需要不斷升級(jí)更新應(yīng)用程序,有時(shí)可能需要頻繁的發(fā)布版本。為達(dá)到此目的,本文通過(guò)使用微服務(wù)技術(shù)對(duì)ETC車道軟件進(jìn)行重構(gòu),并采用K8S特有的滾動(dòng)更新技術(shù),實(shí)現(xiàn)“零停機(jī)”、用戶“零感知”的可持續(xù)部署ETC車道軟件。
K8S是Kubernetes 的簡(jiǎn)稱,它是用來(lái)管理容器集群的平臺(tái)。既然是管理集群,那么就存在被管理節(jié)點(diǎn),針對(duì)每個(gè) K8S集群都由一個(gè) Master負(fù)責(zé)管理和控制集群節(jié)點(diǎn)。
我們通過(guò) Master 對(duì)每個(gè)節(jié)點(diǎn) Node 發(fā)送命令。簡(jiǎn)單來(lái)說(shuō),Master 就是管理者,Node就是被管理者。Node 可以是一臺(tái)機(jī)器或者一臺(tái)虛擬機(jī)。在 Node 上面可以運(yùn)行多個(gè)Pod,Pod 是 K8S管理的最小單位,同時(shí)每個(gè) Pod 可以包含多個(gè)容器(Docker)。
通過(guò)下面的 K8S架構(gòu)簡(jiǎn)圖可以看到Master 和 Node 之間的關(guān)系:(見圖1)
圖1 K8S架構(gòu)簡(jiǎn)圖
k8s通過(guò)部署(Deployment)來(lái)創(chuàng)建副本應(yīng)用程序,部署自動(dòng)創(chuàng)建副本集(ReplicaSet),副本集可以精確地控制每次替換的Pod數(shù)量。具體來(lái)說(shuō),k8s每次使用一個(gè)新的副本控制器(replication controller)來(lái)替換已存在的副本控制器,從而始終使用一個(gè)新的Pod模板來(lái)替換舊的pod模板。在整個(gè)滾動(dòng)過(guò)程期間,保證始終有可用的副本在運(yùn)行,從而平滑的發(fā)布新版本。
為了配合k8s實(shí)現(xiàn)滾動(dòng)更新,ETC車道軟件采用微服務(wù)技術(shù)進(jìn)行設(shè)計(jì),使其適應(yīng)具備容器化部署的能力,具體的架構(gòu)圖如圖2所示。
由圖2可以看出,ETC車道系統(tǒng)可分為4個(gè)部分,其中ETC業(yè)務(wù)模塊實(shí)現(xiàn)了收費(fèi)業(yè)務(wù),是整個(gè)系統(tǒng)里面的變化部分,也是每次版本升級(jí)的關(guān)鍵,它以Pod的形式存在于車道節(jié)點(diǎn)中,采用k8s的滾動(dòng)更新機(jī)制進(jìn)行升級(jí),其他模塊為輔助作用,設(shè)計(jì)理念如下:
圖2 ETC車道軟件架構(gòu)圖
由于ETC車道系統(tǒng)外設(shè)眾多,使用串口通信協(xié)議或者PCI卡進(jìn)行通信,而容器環(huán)境作為一臺(tái)虛擬主機(jī),難以訪問(wèn)宿主機(jī)的硬件資源,一般通過(guò)網(wǎng)絡(luò)協(xié)議與外部進(jìn)行通信,因此需要構(gòu)建一個(gè)“硬件控制模塊”的單體程序完成串口協(xié)議等到網(wǎng)絡(luò)協(xié)議的轉(zhuǎn)換,起到外設(shè)與ETC業(yè)務(wù)模塊的橋梁作用。
要實(shí)現(xiàn)滾動(dòng)更新機(jī)制,實(shí)現(xiàn)無(wú)縫升級(jí),微服務(wù)必須是無(wú)狀態(tài)的。
ETC業(yè)務(wù)模塊負(fù)責(zé)ETC車輛的整個(gè)交易流程,在某通行車輛的交易過(guò)程中,必須臨時(shí)保存交易信息,這和微服務(wù)的無(wú)狀態(tài)要求是相矛盾的。
我們引入Redis內(nèi)存數(shù)據(jù)庫(kù)作為交易狀態(tài)的臨時(shí)存儲(chǔ)手段,因而ETC業(yè)務(wù)模塊可以滿足無(wú)狀態(tài)的要求,在新舊Pod的切換過(guò)程中,交易仍能持續(xù)進(jìn)行,而且Redis提供持久化機(jī)制,就算重啟計(jì)算機(jī)也不會(huì)丟失狀態(tài),交易仍能繼續(xù)進(jìn)行。
如圖3所示,高速公路的收費(fèi)站為局域網(wǎng),可以訪問(wèn)部中心和省中心服務(wù)器,為了保證集群的可靠性,K8S集群應(yīng)以收費(fèi)站為單位建立,而在省中心用Harbor搭建鏡像倉(cāng)庫(kù),供全省所有收費(fèi)站拉取鏡像使用。
圖3 集群設(shè)計(jì)圖
具體的升級(jí)過(guò)程為:
1)先將“ETC業(yè)務(wù)模塊”鏡像上傳到鏡像倉(cāng)庫(kù)
2)然后在K8S Master節(jié)點(diǎn)執(zhí)行升級(jí)命令
3)最后K8S集群自動(dòng)完成各個(gè)ETC Node節(jié)點(diǎn)的自動(dòng)升級(jí)。
K8s的目標(biāo)是在滾動(dòng)更新的過(guò)程中最大程度地減少服務(wù)的中斷,其工作過(guò)程如下:
1)k8s創(chuàng)建新的Pod,讓其處于活動(dòng)狀態(tài)并準(zhǔn)備就緒
2)k8s將會(huì)停止舊的 Pod,從而將 Pod的狀態(tài)更新為“Terminating”
3)k8s將舊的Pod從 Endpoints 對(duì)象中移除
4)k8s發(fā)送一個(gè) SIGTERM 信號(hào)給舊Pod 的主進(jìn)程。
5)SIGTERM 信號(hào)就會(huì)讓舊Pod容器以正常的方式關(guān)閉,并且不接受任何新的連接。
6)舊Pod 從 Endpoints 對(duì)象中被移除后,負(fù)載均衡器就會(huì)將流量路由到其他(新的)Pod 中去。
但由于負(fù)載均衡器檢測(cè)Endpoints對(duì)象的變化,并更新其配置是個(gè)異步的過(guò)程,可能在這個(gè)間隔里舊的Pod已經(jīng)被關(guān)閉了,所以就可能導(dǎo)致很少的請(qǐng)求會(huì)被路由到終止的Pod 上去。
為了解決這個(gè)問(wèn)題,實(shí)現(xiàn)“零停機(jī)”,我們?cè)诰帉慏eployment腳本時(shí)可以加入:
preStop:
exec:
command:["/bin/bash","-c","sleep 20"]
這樣,舊的Pod從Endpoints 對(duì)象中被移除后,還能繼續(xù)提供20秒的服務(wù),保證了無(wú)縫切換。
從2020年3月開始,我們先后在廣東省多個(gè)路段進(jìn)行現(xiàn)場(chǎng)試運(yùn)行和優(yōu)化,經(jīng)省中心校驗(yàn),系統(tǒng)流水正確,流水上傳和參數(shù)下發(fā)正常穩(wěn)定,路段后臺(tái)管理系統(tǒng)流水和圖片查詢統(tǒng)計(jì)正常,交易時(shí)間<300ms,已具備ETC標(biāo)準(zhǔn)車道(出入口)連續(xù)24小時(shí)不間斷過(guò)車交易能力。經(jīng)過(guò)總結(jié),我們認(rèn)為具備以下實(shí)施效果:
(1)應(yīng)用部署效率提高
利用K8S集群的滾動(dòng)更新技術(shù),每當(dāng)ETC車道軟件進(jìn)行版本升級(jí)時(shí),只需遠(yuǎn)程操作站級(jí)Master節(jié)點(diǎn),即可完成更新,更新過(guò)程不影響ETC車道正常過(guò)車,在實(shí)際使用過(guò)程中,更新一個(gè)站的30條ETC車道,耗時(shí)不到1分鐘。
(2)車道故障率下降
當(dāng)K8S集群內(nèi)的Pod出現(xiàn)故障時(shí),集群會(huì)將Pod自動(dòng)重啟,而redis中仍保存著交易狀態(tài),車道系統(tǒng)從故障中自動(dòng)恢復(fù),整體穩(wěn)定性得到顯著提升。
(3)系統(tǒng)監(jiān)控能力提升
得益于K8S集群的多級(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)人員成本下降
運(yùn)維人員直接在K8S的Master節(jié)點(diǎn)發(fā)出更新指令,K8S自動(dòng)完成整個(gè)更新過(guò)程,運(yùn)維人員在非硬件故障情況下無(wú)須到達(dá)現(xiàn)場(chǎng),有效減少了運(yùn)維人員的工作量。
基于Kubernetes 的可持續(xù)部署技術(shù)將研發(fā)與運(yùn)維人員從煩瑣的手工操作中解放出來(lái),同時(shí),系統(tǒng)后臺(tái)具備了高可靠性、失敗冗余和容災(zāi)恢復(fù)等特點(diǎn),在高速公路ETC車道的改造實(shí)踐中具有較大的發(fā)展空間。由于當(dāng)前系統(tǒng)每個(gè)ETC Node部署在車道工控機(jī)內(nèi),當(dāng)車道工控機(jī)出現(xiàn)硬件故障時(shí),ETC車道交易也將中斷,如何能利用K8S集群的高可用技術(shù),達(dá)到車道工控機(jī)出現(xiàn)硬件故障時(shí),ETC車道系統(tǒng)仍能正常交易,是我們下一步的研究方向。