OpenStack是當(dāng)前最主流、最熱門的云平臺(tái),攜程OpenStack環(huán)境除了應(yīng)用在攜程網(wǎng)站,還廣泛應(yīng)用于攜程呼叫中心的桌面云系統(tǒng)。作為業(yè)界最領(lǐng)先的呼叫中心之一,攜程服務(wù)聯(lián)絡(luò)中心幾萬(wàn)員工365x24小時(shí)提供全球化服務(wù),讓說(shuō)走就走的親們毫無(wú)后顧之憂。
桌面云極大地提升了IT運(yùn)維效率,顯著降低了用戶故障率,是未來(lái)IT的一大發(fā)展趨勢(shì)。那么攜程是如何把這兩者高效結(jié)合部署于攜程呼叫中心的?
本文將主要分享攜程呼叫中心廣泛使用的桌面云系統(tǒng),介紹這套基于OpenStack的云桌面系統(tǒng)架構(gòu)以及在開發(fā)過程中碰到的一些OpenStack相關(guān)問題,并分享云桌面系統(tǒng)運(yùn)維、監(jiān)控、自動(dòng)化測(cè)試等。
一、為什么要使用虛擬云桌面
1、背景
攜程呼叫中心,即服務(wù)聯(lián)絡(luò)中心,是攜程的核心部門之一,現(xiàn)有幾萬(wàn)員工。他們?nèi)?x24小時(shí)為全球攜程用戶提供服務(wù)。以前呼叫中心桌面使用臺(tái)式PC,隨著業(yè)務(wù)規(guī)模擴(kuò)大,PC維護(hù)量倍增,需要投入大量人力、物力、財(cái)力來(lái)報(bào)障系統(tǒng)穩(wěn)定運(yùn)行。為此,攜程正式引入虛擬云桌面。
虛擬云桌面是什么?如圖所示,用戶桌面PC機(jī)換成了一個(gè)云桌面瘦客戶端(ThinClient,TC)。所有的CPU、內(nèi)存、硬盤都在云端。云端跑滿虛擬機(jī),用戶桌面通過瘦客戶端連入虛擬機(jī)使用Windows。其中,虛擬機(jī)采用QEMU加KVM實(shí)現(xiàn),云環(huán)境用OpenStack進(jìn)行管理,遠(yuǎn)程桌面協(xié)議是第三方高度定制、修改過的spice協(xié)議。
2、云桌面的優(yōu)勢(shì)
第一,運(yùn)維成本。PC部署以及系統(tǒng)軟件安裝耗時(shí)較長(zhǎng),云桌面后臺(tái)5分鐘一臺(tái)自動(dòng)交付可供用戶使用的虛擬機(jī);PC擴(kuò)大部署投入巨大,云桌面只需要購(gòu)買少量服務(wù)器接入云系統(tǒng),快速擴(kuò)大部署。
第二,故障處理效率。PC有問題,有可能需技術(shù)人員到用戶現(xiàn)場(chǎng)開箱檢查,故障排查耗時(shí)較長(zhǎng),嚴(yán)重點(diǎn)的硬件問題如需更換配件,等待周期更長(zhǎng)。云桌面故障標(biāo)準(zhǔn)是5分鐘處理完畢。對(duì)于5分鐘無(wú)法解決的問題,只需后臺(tái)更換虛擬機(jī)解決。
第三,運(yùn)維管理。PC分散在用戶桌面,運(yùn)維需要用戶配合(比如保持開機(jī))。云桌面提供了運(yùn)維系統(tǒng),只需設(shè)定好時(shí)間、安裝任務(wù)參數(shù),系統(tǒng)會(huì)全自動(dòng)進(jìn)行安裝維護(hù)。同時(shí),瘦客戶端輕量,無(wú)任何用戶數(shù)據(jù),對(duì)用戶也帶來(lái)極大便利。典型的如用戶位置遷移,云桌面無(wú)需搬移,只需用戶到新位置登錄即可。
最后,云桌面整體低碳、環(huán)保。瘦客戶端功率跟普通節(jié)能燈相近,比PC低一個(gè)數(shù)量級(jí)。
3、攜程云桌面現(xiàn)狀
攜程云桌面現(xiàn)已部署上海、南通、如皋、合肥、信陽(yáng)、穆棱六個(gè)呼叫中心。幾百臺(tái)計(jì)算節(jié)點(diǎn)、近萬(wàn)坐席,而且規(guī)模還在不斷擴(kuò)大中,新的呼叫中心也在計(jì)劃中。
同時(shí),云桌面平臺(tái)故障率、瘦客戶端故障率也遠(yuǎn)低于PC故障率。下圖是攜程運(yùn)維部門的故障率統(tǒng)計(jì)圖。
二、如何實(shí)現(xiàn)虛擬云桌面
1、云桌面原架構(gòu)
攜程云桌面后臺(tái)云平臺(tái)在實(shí)踐中進(jìn)行了多次迭代,原有架構(gòu)如上圖所示。該架構(gòu)特點(diǎn)是,直接在OpenStack Nova進(jìn)行定制開發(fā),添加了分配虛擬的接口,實(shí)現(xiàn)瘦客戶端直接訪問OpenStack獲取虛擬機(jī)信息。
這個(gè)架構(gòu)下,云桌面平臺(tái)可以直接訪問全部的虛擬機(jī)信息,直接進(jìn)行全部的虛擬機(jī)操作,數(shù)據(jù)也集中存在OpenStack數(shù)據(jù)庫(kù),部署方便。用戶權(quán)限通過OpenStack Keystone直接管控,管理界面使用OpenStack Horizon并添加云桌面管理頁(yè)面。
典型的分配虛擬機(jī)用例中,瘦客戶端通過OpenStack Keystone進(jìn)行認(rèn)證、獲取Token,然后訪問Nova請(qǐng)求虛擬機(jī)。如上圖所示,瘦客戶端會(huì)通過Keystone進(jìn)行認(rèn)證,Keystone確認(rèn)用戶存在后向域LDAP進(jìn)行密碼校驗(yàn),確認(rèn)用戶合法后返回Token;瘦客戶端再通過Token向Nova申請(qǐng)?zhí)摂M機(jī)。
Nova根據(jù)瘦客戶端設(shè)置的坐席信息,首先查找這個(gè)坐席是否已分配虛擬機(jī)。如有直接返回對(duì)應(yīng)虛擬機(jī)。如無(wú),從后臺(tái)空閑虛擬機(jī)中進(jìn)行分配并更新數(shù)據(jù)庫(kù)分配,返回遠(yuǎn)程桌面協(xié)議連接信息。
2、原架構(gòu)局限性
隨著業(yè)務(wù)增長(zhǎng),原架構(gòu)出現(xiàn)一些局限性,首先,業(yè)務(wù)與OpenStack呈強(qiáng)綁定關(guān)系,導(dǎo)致OpenStack升級(jí)涉及業(yè)務(wù)重寫;修改業(yè)務(wù)邏輯需要對(duì)整個(gè)云平臺(tái)做回歸測(cè)試。
其次,用戶必須要是Keystone用戶,用戶管理必須使用Keystone模型。導(dǎo)致Keystone與LDAP之間要定期同步進(jìn)行,有時(shí)還需手工同步特殊用戶。
管理層面,因?yàn)镠orizon的面向云資源管理的,但業(yè)務(wù)主要面向運(yùn)維的。這部分差異,導(dǎo)致我們開發(fā)新的Portal來(lái)彌補(bǔ),管理人員需要通過兩套系統(tǒng)來(lái)進(jìn)行運(yùn)維。
整體方案上,云桌面遠(yuǎn)程桌面協(xié)議由第三方提供,如果第三方方案不支持OpenStack,就無(wú)法在攜程云桌面系統(tǒng)使用。
最后,用戶部門有各種需求,直接在OpenStack內(nèi)進(jìn)行開發(fā)難度大,上線時(shí)間長(zhǎng),開發(fā)人員很難實(shí)現(xiàn)技術(shù)引領(lǐng)業(yè)務(wù)發(fā)展。
3、新架構(gòu)
經(jīng)過架構(gòu)調(diào)整,新架構(gòu)實(shí)現(xiàn)了OpenStack與我們的業(yè)務(wù)解耦,同時(shí)適應(yīng)用戶部門的業(yè)務(wù)發(fā)展方向,方便功能快速迭代上線。
從圖中可以看出,云桌面業(yè)務(wù)邏輯從OpenStack中獨(dú)立出來(lái),成為了VMPool,Allocator;管理層獨(dú)立開發(fā)一套面向IT運(yùn)維的Portal系統(tǒng),取代Horizon;云平臺(tái)可直接原生的OpenStack。
其中VMPool負(fù)責(zé)維護(hù)某種規(guī)格虛擬機(jī)的可用數(shù)量,避免需要的時(shí)候沒有虛擬機(jī)可用,讓用戶等待。Allocator滿足符合條件的用戶請(qǐng)求,返回用戶對(duì)應(yīng)的虛擬機(jī)或者從VMPool分配虛擬機(jī)分配用戶。
對(duì)于用戶分配虛擬機(jī)的典型用例,與原有架構(gòu)改動(dòng)較大。首先,業(yè)務(wù)層瘦客戶端將直接訪問業(yè)務(wù)層的API。API層會(huì)直接通過LDAP進(jìn)行用戶認(rèn)證,并獲取用戶OU、組別等信息。
接著,業(yè)務(wù)層將進(jìn)行用戶規(guī)則匹配。每個(gè)Allocator通過用戶組、OU、tag等進(jìn)行規(guī)則匹配,以確定該用戶是否由自己進(jìn)行服務(wù)。如不滿足Allocator所定義的規(guī)則,將按Allocator的優(yōu)先等級(jí),繼續(xù)選取下一個(gè)Allocator進(jìn)行匹配,直到匹配或者默認(rèn)規(guī)則為止。
匹配后,如果是有綁定關(guān)系的分配規(guī)則,比如用戶綁定或者坐席綁定、TC綁定,那Allocator將直接從數(shù)據(jù)庫(kù)返回已有的綁定;如果無(wú)綁定關(guān)系,Allocator就會(huì)從對(duì)應(yīng)的VMPool分配一臺(tái)虛擬給,返回給用戶。
最后,對(duì)用戶部門來(lái)說(shuō),看到的是用戶屬于一個(gè)組,這個(gè)組對(duì)應(yīng)特定的虛擬機(jī)。只需調(diào)整用戶屬性,即可實(shí)現(xiàn)用戶分配特定的虛擬機(jī),充分滿足他們的各種需求。
三、大規(guī)模部署中遇到各種坎
1、軟件版本選取
在搭建OpenStack前,必須進(jìn)行需求分析,確定所需的需求。然后根據(jù)需求選取滿足條件的OpenStack及相關(guān)組件的版本,以避免后期出現(xiàn)各種系統(tǒng)及虛擬機(jī)問題。
我們根據(jù)攜程呼叫中心的業(yè)務(wù)需要,選好了幾個(gè)版本的KVM、QEMU,以及OpenVSwitch,在選取能適配它們的幾個(gè)可用kernel、Libvirt版本,并剔除了不穩(wěn)定版本或者有已知問題的版本,將這些組件組成合理的組合,進(jìn)行7x24小時(shí)用戶模擬自動(dòng)測(cè)試,找到最穩(wěn)定、合適的并滿足需求的,作生產(chǎn)上線使用。
2、資源超分
超分與應(yīng)用場(chǎng)景強(qiáng)關(guān)聯(lián)。一定要首先確定需求,是CPU密集、內(nèi)存密集、IO密集還是存儲(chǔ)密集。在做了充足的用戶調(diào)查后,我們準(zhǔn)備了大量用戶模擬自動(dòng)化腳本,進(jìn)行自動(dòng)化測(cè)試,以選取最合理超分值。
從我們的測(cè)試結(jié)果看,瓶頸主要是內(nèi)存。內(nèi)存超分過度會(huì)導(dǎo)致主機(jī)直接OOM(Out Of Memory)宕機(jī)。Windows及Windows應(yīng)用吃內(nèi)存比較嚴(yán)重,特別是像Chrome這些程序,優(yōu)先占用內(nèi)存先。雖然我們使用KSM(Kernel Samepage Merging,相同內(nèi)存頁(yè)合并功能),省了一些內(nèi)存,但最終上線也只能達(dá)到1:1.2的超分。
對(duì)于IO,在Windows啟動(dòng)階段比較明顯。大量Windows同時(shí)啟動(dòng)時(shí)會(huì)造成啟動(dòng)風(fēng)暴情,在我們的極端條件測(cè)試中出現(xiàn)過啟動(dòng)Windows需要40分鐘,硬盤IO100%使用,每個(gè)讀寫請(qǐng)求平均0.2秒響應(yīng)。所以,在大規(guī)模部署時(shí),對(duì)虛擬機(jī)并發(fā)開機(jī)數(shù)一定要有一定限制。同時(shí),硬盤一定要多塊做RAID,以提供更高的IO吞吐量。
最后是CPU。CPU過度超分會(huì)嚴(yán)重影響用戶體驗(yàn)。但是一般不會(huì)造成宿主機(jī)宕機(jī)。在我們的測(cè)試條件下,超分到1:2用戶體驗(yàn)開始下降,所以實(shí)際上線超分不多。
最終我們現(xiàn)在生產(chǎn)環(huán)境,是以內(nèi)存為標(biāo)準(zhǔn)進(jìn)行超分,硬盤、CPU控制在可接受范圍。
3、網(wǎng)絡(luò)細(xì)節(jié)
多DNSMasq實(shí)例問題
我們虛擬機(jī)的IP地址通過DHCP獲取。DHCP服務(wù)端我們使用的DNSMasq比較老,只是簡(jiǎn)單的實(shí)現(xiàn)了多實(shí)例運(yùn)行,但并未真正實(shí)現(xiàn)綁定到虛擬接口。
在生產(chǎn)環(huán)境,我們觀察到VM都能獲取IP,但是在續(xù)租IP的時(shí)候大量失敗。經(jīng)抓包分析,虛擬機(jī)在第一次請(qǐng)求IP時(shí),由于自身無(wú)IP地址,使用的是廣播方式進(jìn)行DHCP請(qǐng)求;在續(xù)租時(shí),由于本身有IP地址,也已明確DHCP服務(wù)端地址,所以采用IP點(diǎn)對(duì)點(diǎn)單播請(qǐng)求。
服務(wù)端,多個(gè)DNSMasq實(shí)例運(yùn)行的情況下,如果是廣播包,所有DNSMasq都收到消息,所有廣播請(qǐng)求能正確回復(fù)。在單播情況下,只有最后啟動(dòng)的DNSMasq能收到請(qǐng)求,最終導(dǎo)致虛擬機(jī)得不到正確的DHCP續(xù)租響應(yīng)。最終我們通過升級(jí)DNSMasq解決。
宿主機(jī)重啟導(dǎo)致虛擬機(jī)網(wǎng)絡(luò)不通
在物理機(jī)重啟后,有時(shí)會(huì)出現(xiàn)VM網(wǎng)絡(luò)不通。經(jīng)過調(diào)查,我們分析出根本原因是libvirt,ovs的啟動(dòng)、關(guān)閉順序。
在正常情況下,libvrit退出時(shí)會(huì)刪除它管理的OpenVSwitch Port以及它創(chuàng)建的對(duì)應(yīng)的Tap虛擬網(wǎng)卡。libvirt啟動(dòng)時(shí)會(huì)創(chuàng)建需要的Tap網(wǎng)卡,并請(qǐng)求OpenVSwitch創(chuàng)建對(duì)應(yīng)的Port建立虛擬連接。
邏輯上,OpenVSwitch Port相當(dāng)于交換機(jī)網(wǎng)口。Tap網(wǎng)卡,相當(dāng)于PC的網(wǎng)卡。他們之間需要連線網(wǎng)絡(luò)才能正常通信。
如果關(guān)機(jī)時(shí),OpenVSwitch比Libvirt先停止,Libvirt將不能成功刪除它管理的OpenVSwitch Port;開機(jī)時(shí),如果OpenVSwitch先啟動(dòng),它將建試圖重建之前存在的port。但因?yàn)長(zhǎng)ibvirt還未啟動(dòng),OpenVSwitch Port對(duì)應(yīng)的Tap網(wǎng)卡還未創(chuàng)建(即虛擬網(wǎng)口對(duì)應(yīng)的虛擬網(wǎng)卡不存在),OpenVSwitch重建Port最終失敗并且Port將被銷毀。
由于Port信息對(duì)OpenVSwitch來(lái)說(shuō)是用戶配置信息,OpenVSwitch并不會(huì)從數(shù)據(jù)庫(kù)中清理掉對(duì)應(yīng)的Port記錄。所以等到Libvirt啟動(dòng)調(diào)用OpenVSwitch創(chuàng)建Port時(shí),OpenVSwitch發(fā)現(xiàn)數(shù)據(jù)庫(kù)里面已經(jīng)存在這些Port,所以并未真正觸發(fā)Port重建,最后造成VM網(wǎng)絡(luò)不通。
最終我們通過開、關(guān)機(jī)順序調(diào)整實(shí)現(xiàn)問題修復(fù)。
RabbitMQ長(zhǎng)連接
RabbitMQ是OpenStack使用的一種消息交交互組件。OpenStack在某些時(shí)候,會(huì)出現(xiàn)無(wú)法創(chuàng)建虛擬機(jī)的情況。通過日志分析我們發(fā)現(xiàn)計(jì)算節(jié)點(diǎn)沒有收到對(duì)應(yīng)的創(chuàng)建請(qǐng)求消息。然后抓包分析進(jìn)一步發(fā)現(xiàn),TCP數(shù)據(jù)包被防火墻攔截、丟棄。原來(lái)防火墻對(duì)TCP會(huì)話有數(shù)量限制,會(huì)定期丟棄長(zhǎng)久無(wú)數(shù)據(jù)交互的TCP會(huì)話。
在了解根本原因后,一方面通過定期自動(dòng)冒煙測(cè)試保證網(wǎng)絡(luò)不空閑,一方面想解決方案。從應(yīng)用層面上,我們調(diào)研到RabbitMQ已經(jīng)有心跳機(jī)制,但要升級(jí)。由于升級(jí)影響范圍太廣,最終沒有進(jìn)行。
接著我們對(duì)網(wǎng)絡(luò)層面進(jìn)行了調(diào)查,發(fā)現(xiàn)TCP本身有Keepalive?;顧C(jī)制,同時(shí)RabbitMQ代碼本身也有TCP?;?,但默認(rèn)不開啟。最后我們通過啟用RabbitMQTCP?;顧C(jī)制,設(shè)置一個(gè)合理的?;铋g隔解決問題。
四、系統(tǒng)穩(wěn)定背后的黑科技
1、運(yùn)維工具
運(yùn)維是云桌面的一大難題,為此我們專門設(shè)計(jì)了運(yùn)維系統(tǒng),通過兩套SaltStack系統(tǒng)實(shí)現(xiàn)了對(duì)瘦客戶端與虛擬機(jī)的管理;通過Portal系統(tǒng)實(shí)現(xiàn)對(duì)整個(gè)系統(tǒng)的管理。
具體功能上,運(yùn)維上,實(shí)現(xiàn)了對(duì)虛擬機(jī)、宿主機(jī)的可視化監(jiān)控、管理,并能對(duì)虛擬機(jī)實(shí)現(xiàn)遠(yuǎn)程管理;對(duì)IT管理人員,實(shí)現(xiàn)了自動(dòng)化的軟件安裝、文件下發(fā)、密碼修改、數(shù)據(jù)找回,、發(fā)送通知等功能;對(duì)資產(chǎn)管理員,實(shí)現(xiàn)了TC狀態(tài)監(jiān)控,TC異常情況及時(shí)發(fā)現(xiàn)。還有其它大量工作仍在開發(fā)進(jìn)行中。
2、監(jiān)控告警
監(jiān)控方面,除了常規(guī)的服務(wù)器、操作系統(tǒng)層面的監(jiān)控,我們實(shí)現(xiàn)了大量業(yè)務(wù)層監(jiān)控。比如通過監(jiān)控已經(jīng)連接云桌面的瘦客戶端用戶輸入事件,實(shí)現(xiàn)實(shí)時(shí)活躍用戶監(jiān)控,使得我們能實(shí)時(shí)監(jiān)控系統(tǒng)負(fù)載、用戶數(shù)量。通過對(duì)比部門排班,第一時(shí)間發(fā)現(xiàn)用戶數(shù)異常。
同時(shí),對(duì)OpenStack的各種告警、ERROR的也添加了監(jiān)控,確保云平臺(tái)的穩(wěn)定。對(duì)虛擬機(jī)網(wǎng)絡(luò)、CPU等也進(jìn)行了相應(yīng)監(jiān)控,確保虛擬機(jī)對(duì)于用戶的高可用性。
3、自動(dòng)化測(cè)試
通過在瘦客戶端實(shí)現(xiàn)用戶輸入輸出模擬,我們實(shí)現(xiàn)了全自動(dòng)的測(cè)試環(huán)境。我們搭建了專門的云桌面測(cè)試實(shí)驗(yàn)室,數(shù)十臺(tái)盒子進(jìn)行7x24小時(shí)自動(dòng)測(cè)試,全力驗(yàn)證系統(tǒng)各項(xiàng)變更,支持業(yè)務(wù)各種研究探索,保障系統(tǒng)穩(wěn)定性。
同時(shí),通過傳統(tǒng)的CI框架,我們搭建了代碼的單元測(cè)試、集成測(cè)試環(huán)境,已經(jīng)大量的線上測(cè)試用例,不僅有力的保障了軟件質(zhì)量,還能定期對(duì)線上系統(tǒng)進(jìn)行體檢,第一時(shí)間發(fā)現(xiàn)系統(tǒng)異常。