桌面云極大地提升了IT運維效率,顯著(zhù)降低了用戶(hù)故障率,是未來(lái)IT的一大發(fā)展趨勢。那么攜程是如何把這兩者高效結合部署于攜程呼叫中心的?
本文將主要分享攜程呼叫中心廣泛使用的桌面云系統,介紹這套基于OpenStack的云桌面系統架構以及在開(kāi)發(fā)過(guò)程中碰到的一些OpenStack相關(guān)問(wèn)題,并分享云桌面系統運維、監控、自動(dòng)化測試等。
一、為什么要使用虛擬云桌面
1、背景
攜程呼叫中心,即服務(wù)聯(lián)絡(luò )中心,是攜程的核心部門(mén)之一,現有幾萬(wàn)員工。他們全年7x24小時(shí)為全球攜程用戶(hù)提供服務(wù)。以前呼叫中心桌面使用臺式PC,隨著(zhù)業(yè)務(wù)規模擴大,PC維護量倍增,需要投入大量人力、物力、財力來(lái)報障系統穩定運行。為此,攜程正式引入虛擬云桌面。

虛擬云桌面是什么?如圖所示,用戶(hù)桌面PC機換成了一個(gè)云桌面瘦客戶(hù)端(ThinClient,TC)。所有的CPU、內存、硬盤(pán)都在云端。云端跑滿(mǎn)虛擬機,用戶(hù)桌面通過(guò)瘦客戶(hù)端連入虛擬機使用Windows。其中,虛擬機采用QEMU加KVM實(shí)現,云環(huán)境用OpenStack進(jìn)行管理,遠程桌面協(xié)議是第三方高度定制、修改過(guò)的spice協(xié)議。
2、云桌面的優(yōu)勢
第一,運維成本。PC部署以及系統軟件安裝耗時(shí)較長(cháng),云桌面后臺5分鐘一臺自動(dòng)交付可供用戶(hù)使用的虛擬機;PC擴大部署投入巨大,云桌面只需要購買(mǎi)少量服務(wù)器接入云系統,快速擴大部署。
第二,故障處理效率。PC有問(wèn)題,有可能需技術(shù)人員到用戶(hù)現場(chǎng)開(kāi)箱檢查,故障排查耗時(shí)較長(cháng),嚴重點(diǎn)的硬件問(wèn)題如需更換配件,等待周期更長(cháng)。云桌面故障標準是5分鐘處理完畢。對于5分鐘無(wú)法解決的問(wèn)題,只需后臺更換虛擬機解決。
第三,運維管理。PC分散在用戶(hù)桌面,運維需要用戶(hù)配合(比如保持開(kāi)機)。云桌面提供了運維系統,只需設定好時(shí)間、安裝任務(wù)參數,系統會(huì )全自動(dòng)進(jìn)行安裝維護。同時(shí),瘦客戶(hù)端輕量,無(wú)任何用戶(hù)數據,對用戶(hù)也帶來(lái)極大便利。典型的如用戶(hù)位置遷移,云桌面無(wú)需搬移,只需用戶(hù)到新位置登錄即可。
最后,云桌面整體低碳、環(huán)保。瘦客戶(hù)端功率跟普通節能燈相近,比PC低一個(gè)數量級。
3、攜程云桌面現狀
攜程云桌面現已部署上海、南通、如皋、合肥、信陽(yáng)、穆棱六個(gè)呼叫中心。幾百臺計算節點(diǎn)、近萬(wàn)坐席,而且規模還在不斷擴大中,新的呼叫中心也在計劃中。
同時(shí),云桌面平臺故障率、瘦客戶(hù)端故障率也遠低于PC故障率。下圖是攜程運維部門(mén)的故障率統計圖。

二、如何實(shí)現虛擬云桌面
1、云桌面原架構

攜程云桌面后臺云平臺在實(shí)踐中進(jìn)行了多次迭代,原有架構如上圖所示。該架構特點(diǎn)是,直接在OpenStack Nova進(jìn)行定制開(kāi)發(fā),添加了分配虛擬的接口,實(shí)現瘦客戶(hù)端直接訪(fǎng)問(wèn)OpenStack獲取虛擬機信息。
這個(gè)架構下,云桌面平臺可以直接訪(fǎng)問(wèn)全部的虛擬機信息,直接進(jìn)行全部的虛擬機操作,數據也集中存在OpenStack數據庫,部署方便。用戶(hù)權限通過(guò)OpenStack Keystone直接管控,管理界面使用OpenStack Horizon并添加云桌面管理頁(yè)面。

典型的分配虛擬機用例中,瘦客戶(hù)端通過(guò)OpenStack Keystone進(jìn)行認證、獲取Token,然后訪(fǎng)問(wèn)Nova請求虛擬機。如上圖所示,瘦客戶(hù)端會(huì )通過(guò)Keystone進(jìn)行認證,Keystone確認用戶(hù)存在后向域LDAP進(jìn)行密碼校驗,確認用戶(hù)合法后返回Token;瘦客戶(hù)端再通過(guò)Token向Nova申請虛擬機。
Nova根據瘦客戶(hù)端設置的坐席信息,首先查找這個(gè)坐席是否已分配虛擬機。如有直接返回對應虛擬機。如無(wú),從后臺空閑虛擬機中進(jìn)行分配并更新數據庫分配,返回遠程桌面協(xié)議連接信息。
2、原架構局限性
隨著(zhù)業(yè)務(wù)增長(cháng),原架構出現一些局限性,首先,業(yè)務(wù)與OpenStack呈強綁定關(guān)系,導致OpenStack升級涉及業(yè)務(wù)重寫(xiě);修改業(yè)務(wù)邏輯需要對整個(gè)云平臺做回歸測試。
其次,用戶(hù)必須要是Keystone用戶(hù),用戶(hù)管理必須使用Keystone模型。導致Keystone與LDAP之間要定期同步進(jìn)行,有時(shí)還需手工同步特殊用戶(hù)。
管理層面,因為Horizon的面向云資源管理的,但業(yè)務(wù)主要面向運維的。這部分差異,導致我們開(kāi)發(fā)新的Portal來(lái)彌補,管理人員需要通過(guò)兩套系統來(lái)進(jìn)行運維。
整體方案上,云桌面遠程桌面協(xié)議由第三方提供,如果第三方方案不支持OpenStack,就無(wú)法在攜程云桌面系統使用。
最后,用戶(hù)部門(mén)有各種需求,直接在OpenStack內進(jìn)行開(kāi)發(fā)難度大,上線(xiàn)時(shí)間長(cháng),開(kāi)發(fā)人員很難實(shí)現技術(shù)引領(lǐng)業(yè)務(wù)發(fā)展。
3、新架構
經(jīng)過(guò)架構調整,新架構實(shí)現了OpenStack與我們的業(yè)務(wù)解耦,同時(shí)適應用戶(hù)部門(mén)的業(yè)務(wù)發(fā)展方向,方便功能快速迭代上線(xiàn)。

從圖中可以看出,云桌面業(yè)務(wù)邏輯從OpenStack中獨立出來(lái),成為了VMPool,Allocator;管理層獨立開(kāi)發(fā)一套面向IT運維的Portal系統,取代Horizon;云平臺可直接原生的OpenStack。
其中VMPool負責維護某種規格虛擬機的可用數量,避免需要的時(shí)候沒(méi)有虛擬機可用,讓用戶(hù)等待。Allocator滿(mǎn)足符合條件的用戶(hù)請求,返回用戶(hù)對應的虛擬機或者從VMPool分配虛擬機分配用戶(hù)。

對于用戶(hù)分配虛擬機的典型用例,與原有架構改動(dòng)較大。首先,業(yè)務(wù)層瘦客戶(hù)端將直接訪(fǎng)問(wèn)業(yè)務(wù)層的API。API層會(huì )直接通過(guò)LDAP進(jìn)行用戶(hù)認證,并獲取用戶(hù)OU、組別等信息。
接著(zhù),業(yè)務(wù)層將進(jìn)行用戶(hù)規則匹配。每個(gè)Allocator通過(guò)用戶(hù)組、OU、tag等進(jìn)行規則匹配,以確定該用戶(hù)是否由自己進(jìn)行服務(wù)。如不滿(mǎn)足Allocator所定義的規則,將按Allocator的優(yōu)先等級,繼續選取下一個(gè)Allocator進(jìn)行匹配,直到匹配或者默認規則為止。
匹配后,如果是有綁定關(guān)系的分配規則,比如用戶(hù)綁定或者坐席綁定、TC綁定,那Allocator將直接從數據庫返回已有的綁定;如果無(wú)綁定關(guān)系,Allocator就會(huì )從對應的VMPool分配一臺虛擬給,返回給用戶(hù)。
最后,對用戶(hù)部門(mén)來(lái)說(shuō),看到的是用戶(hù)屬于一個(gè)組,這個(gè)組對應特定的虛擬機。只需調整用戶(hù)屬性,即可實(shí)現用戶(hù)分配特定的虛擬機,充分滿(mǎn)足他們的各種需求。
三、大規模部署中遇到各種坎
1、軟件版本選取
在搭建OpenStack前,必須進(jìn)行需求分析,確定所需的需求。然后根據需求選取滿(mǎn)足條件的OpenStack及相關(guān)組件的版本,以避免后期出現各種系統及虛擬機問(wèn)題。
我們根據攜程呼叫中心的業(yè)務(wù)需要,選好了幾個(gè)版本的KVM、QEMU,以及OpenVSwitch,在選取能適配它們的幾個(gè)可用kernel、Libvirt版本,并剔除了不穩定版本或者有已知問(wèn)題的版本,將這些組件組成合理的組合,進(jìn)行7x24小時(shí)用戶(hù)模擬自動(dòng)測試,找到最穩定、合適的并滿(mǎn)足需求的,作生產(chǎn)上線(xiàn)使用。
2、資源超分
超分與應用場(chǎng)景強關(guān)聯(lián)。一定要首先確定需求,是CPU密集、內存密集、IO密集還是存儲密集。在做了充足的用戶(hù)調查后,我們準備了大量用戶(hù)模擬自動(dòng)化腳本,進(jìn)行自動(dòng)化測試,以選取最合理超分值。
從我們的測試結果看,瓶頸主要是內存。內存超分過(guò)度會(huì )導致主機直接OOM(Out Of Memory)宕機。Windows及Windows應用吃?xún)却姹容^嚴重,特別是像Chrome這些程序,優(yōu)先占用內存先。雖然我們使用KSM(Kernel Samepage Merging,相同內存頁(yè)合并功能),省了一些內存,但最終上線(xiàn)也只能達到1:1.2的超分。
對于IO,在Windows啟動(dòng)階段比較明顯。大量Windows同時(shí)啟動(dòng)時(shí)會(huì )造成啟動(dòng)風(fēng)暴情,在我們的極端條件測試中出現過(guò)啟動(dòng)Windows需要40分鐘,硬盤(pán)IO100%使用,每個(gè)讀寫(xiě)請求平均0.2秒響應。所以,在大規模部署時(shí),對虛擬機并發(fā)開(kāi)機數一定要有一定限制。同時(shí),硬盤(pán)一定要多塊做RAID,以提供更高的IO吞吐量。
最后是CPU。CPU過(guò)度超分會(huì )嚴重影響用戶(hù)體驗。但是一般不會(huì )造成宿主機宕機。在我們的測試條件下,超分到1:2用戶(hù)體驗開(kāi)始下降,所以實(shí)際上線(xiàn)超分不多。
最終我們現在生產(chǎn)環(huán)境,是以?xún)却鏋闃藴蔬M(jìn)行超分,硬盤(pán)、CPU控制在可接受范圍。
3、網(wǎng)絡(luò )細節
多DNSMasq實(shí)例問(wèn)題
我們虛擬機的IP地址通過(guò)DHCP獲取。DHCP服務(wù)端我們使用的DNSMasq比較老,只是簡(jiǎn)單的實(shí)現了多實(shí)例運行,但并未真正實(shí)現綁定到虛擬接口。
在生產(chǎn)環(huán)境,我們觀(guān)察到VM都能獲取IP,但是在續租IP的時(shí)候大量失敗。經(jīng)抓包分析,虛擬機在第一次請求IP時(shí),由于自身無(wú)IP地址,使用的是廣播方式進(jìn)行DHCP請求;在續租時(shí),由于本身有IP地址,也已明確DHCP服務(wù)端地址,所以采用IP點(diǎn)對點(diǎn)單播請求。
服務(wù)端,多個(gè)DNSMasq實(shí)例運行的情況下,如果是廣播包,所有DNSMasq都收到消息,所有廣播請求能正確回復。在單播情況下,只有最后啟動(dòng)的DNSMasq能收到請求,最終導致虛擬機得不到正確的DHCP續租響應。最終我們通過(guò)升級DNSMasq解決。
宿主機重啟導致虛擬機網(wǎng)絡(luò )不通
在物理機重啟后,有時(shí)會(huì )出現VM網(wǎng)絡(luò )不通。經(jīng)過(guò)調查,我們分析出根本原因是libvirt,ovs的啟動(dòng)、關(guān)閉順序。
在正常情況下,libvrit退出時(shí)會(huì )刪除它管理的OpenVSwitch Port以及它創(chuàng )建的對應的Tap虛擬網(wǎng)卡。libvirt啟動(dòng)時(shí)會(huì )創(chuàng )建需要的Tap網(wǎng)卡,并請求OpenVSwitch創(chuàng )建對應的Port建立虛擬連接。
邏輯上,OpenVSwitch Port相當于交換機網(wǎng)口。Tap網(wǎng)卡,相當于PC的網(wǎng)卡。他們之間需要連線(xiàn)網(wǎng)絡(luò )才能正常通信。
如果關(guān)機時(shí),OpenVSwitch比Libvirt先停止,Libvirt將不能成功刪除它管理的OpenVSwitch Port;開(kāi)機時(shí),如果OpenVSwitch先啟動(dòng),它將建試圖重建之前存在的port。但因為L(cháng)ibvirt還未啟動(dòng),OpenVSwitch Port對應的Tap網(wǎng)卡還未創(chuàng )建(即虛擬網(wǎng)口對應的虛擬網(wǎng)卡不存在),OpenVSwitch重建Port最終失敗并且Port將被銷(xiāo)毀。
由于Port信息對OpenVSwitch來(lái)說(shuō)是用戶(hù)配置信息,OpenVSwitch并不會(huì )從數據庫中清理掉對應的Port記錄。所以等到Libvirt啟動(dòng)調用OpenVSwitch創(chuàng )建Port時(shí),OpenVSwitch發(fā)現數據庫里面已經(jīng)存在這些Port,所以并未真正觸發(fā)Port重建,最后造成VM網(wǎng)絡(luò )不通。
最終我們通過(guò)開(kāi)、關(guān)機順序調整實(shí)現問(wèn)題修復。
RabbitMQ長(cháng)連接
RabbitMQ是OpenStack使用的一種消息交交互組件。OpenStack在某些時(shí)候,會(huì )出現無(wú)法創(chuàng )建虛擬機的情況。通過(guò)日志分析我們發(fā)現計算節點(diǎn)沒(méi)有收到對應的創(chuàng )建請求消息。然后抓包分析進(jìn)一步發(fā)現,TCP數據包被防火墻攔截、丟棄。原來(lái)防火墻對TCP會(huì )話(huà)有數量限制,會(huì )定期丟棄長(cháng)久無(wú)數據交互的TCP會(huì )話(huà)。
在了解根本原因后,一方面通過(guò)定期自動(dòng)冒煙測試保證網(wǎng)絡(luò )不空閑,一方面想解決方案。從應用層面上,我們調研到RabbitMQ已經(jīng)有心跳機制,但要升級。由于升級影響范圍太廣,最終沒(méi)有進(jìn)行。
接著(zhù)我們對網(wǎng)絡(luò )層面進(jìn)行了調查,發(fā)現TCP本身有Keepalive保活機制,同時(shí)RabbitMQ代碼本身也有TCP保活,但默認不開(kāi)啟。最后我們通過(guò)啟用RabbitMQTCP保活機制,設置一個(gè)合理的保活間隔解決問(wèn)題。
四、系統穩定背后的黑科技
1、運維工具
運維是云桌面的一大難題,為此我們專(zhuān)門(mén)設計了運維系統,通過(guò)兩套SaltStack系統實(shí)現了對瘦客戶(hù)端與虛擬機的管理;通過(guò)Portal系統實(shí)現對整個(gè)系統的管理。
具體功能上,運維上,實(shí)現了對虛擬機、宿主機的可視化監控、管理,并能對虛擬機實(shí)現遠程管理;對IT管理人員,實(shí)現了自動(dòng)化的軟件安裝、文件下發(fā)、密碼修改、數據找回,、發(fā)送通知等功能;對資產(chǎn)管理員,實(shí)現了TC狀態(tài)監控,TC異常情況及時(shí)發(fā)現。還有其它大量工作仍在開(kāi)發(fā)進(jìn)行中。
2、監控告警
監控方面,除了常規的服務(wù)器、操作系統層面的監控,我們實(shí)現了大量業(yè)務(wù)層監控。比如通過(guò)監控已經(jīng)連接云桌面的瘦客戶(hù)端用戶(hù)輸入事件,實(shí)現實(shí)時(shí)活躍用戶(hù)監控,使得我們能實(shí)時(shí)監控系統負載、用戶(hù)數量。通過(guò)對比部門(mén)排班,第一時(shí)間發(fā)現用戶(hù)數異常。
同時(shí),對OpenStack的各種告警、ERROR的也添加了監控,確保云平臺的穩定。對虛擬機網(wǎng)絡(luò )、CPU等也進(jìn)行了相應監控,確保虛擬機對于用戶(hù)的高可用性。
3、自動(dòng)化測試
通過(guò)在瘦客戶(hù)端實(shí)現用戶(hù)輸入輸出模擬,我們實(shí)現了全自動(dòng)的測試環(huán)境。我們搭建了專(zhuān)門(mén)的云桌面測試實(shí)驗室,數十臺盒子進(jìn)行7x24小時(shí)自動(dòng)測試,全力驗證系統各項變更,支持業(yè)務(wù)各種研究探索,保障系統穩定性。
同時(shí),通過(guò)傳統的CI框架,我們搭建了代碼的單元測試、集成測試環(huán)境,已經(jīng)大量的線(xiàn)上測試用例,不僅有力的保障了軟件質(zhì)量,還能定期對線(xiàn)上系統進(jìn)行體檢,第一時(shí)間發(fā)現系統異常。