歡迎光臨
每天分享高質量文章

58集團雲平臺架構實踐與演進

 

在17年底,我們分享了《高可用Docker容器雲在58集團的實踐》這篇文章,對整個容器雲基礎環境搭建與應用選型進行了詳細介紹,本文是在該文章基礎之上的進階篇,是針對具體業務場景的落地解決方案。如果對基礎環境選型比較感興趣,可以檢視上篇文章,在本文的最後會附上相關文章的連結。對於上篇文章討論過的內容,本文將不再進行詳細討論。後續每個月,雲團隊都會選擇平臺中某一具體領域的相關工作進行詳細討論與分享,歡迎大家關註。大家想瞭解哪方面的實現方案與細節,可進行相應留言。

 

背景

 

透過容器化技術,58雲端計算平臺主要解決以下幾個問題:
  1. 資源利用率低:透過雲化技術可以將資源利用率提升至原有的3-4倍,甚至更高。

  2. 服務擴容效率低:將傳統擴容的時間從小時級別降低為分鐘級別。

  3. 上線流程不規範:基於同一的映象模板,約束整個上線過程。

為瞭解決上述問題,雲團隊透過技術選型與反覆論證最終決定基於Docker與Kubernetes體系構建整個容器雲環境。
雲端計算平臺的發展歷程如下:

 

整體架構

 

58雲端計算平臺的整體架構如下:

所有容器雲的架構都是相似的,這裡不做贅述,具體可檢視上篇文章。
雲端計算平臺承載了集團90%以上的業務流量,作為核心的服務管理與上線系統,它並不是獨立運作的,為了保證整個上線流程的一致性與流暢度,滿足業務日常管理與維護的通用需求,雲平臺與集團內部多個核心系統與元件進行了相應的對接與聯動。

在專案管理方面,雲平臺與程式碼管理系統、專案管理等系統進行了內部對接,實現了程式碼從編譯到生成映象,再到環境部署的完全自動化。
在運維方面,雲平臺與CMDB、服務樹、監控系統等多個運維繫統進行了打通與整合,保證整個運維體系的完整性與使用者體驗的一致性。
在基礎元件方面,集團內部的服務治理體系與常用的中介軟體系統都針對雲平臺進行了相應的改造,以適配雲平臺的工作樣式,同時雲平臺也集成了現有的資料收集元件,保證資料流與使用者習慣在雲化前後是一致的。
雲平臺的使用方面,平臺定義了四套環境,四套環境基於唯一的映象倉庫,這使得同一個程式碼版本可以在不同的環境之間進行流轉,在保證程式碼唯一性的同時也使得相關環境的變更不會傳遞到下一個環境。

 

架構演進

 

構建一個適配多種業務場景的容器雲有很多細節需要考慮,雲團隊做了很多工作,由於篇幅關係,這裡主要和大家分享58雲端計算平臺在“網路架構”和“服務發現”兩個核心元件上的架構實踐與演進。
網路架構
在網路架構方面,透過對比常用的六種容器組網模型,雲端計算平臺選擇“bridge+vlan”的方式作為基礎網路模型。

原生bridge網路模型存在兩個明顯的缺點:IP利用率低、缺少網路限速。
為瞭解決IP地址利用率低的問題,雲平臺基於docker的CNM介面開發了網路外掛,支援多個宿主間共享同一個容器網段,也支援IP地址在不同的宿主間復用。

這種網路樣式下,分配給業務實體的IP地址是隨機的,實體每次重啟IP地址都可能會發生變更。在推進業務雲化的早期,這種樣式被業務所接受,但是隨著雲化行程的不斷深入,業務方面提出了更高的要求:固定IP。
業務需求來源於真實的案例:有些服務要求IP不能發生變化,特別是某些依賴於第三方外部介面的服務。同時集團內部很多系統都是以IP固定為前提,如果IP隨機分配,這些現有系統將不可用或很難用,極大的影響使用者體驗。如果IP固定的需求不能被滿足,業務雲化將很難推進下去。所以在18年4月份,雲平臺對網路架構進行了升級,支援了固定IP樣式。網路架構的升級很好的保證了業務雲化的行程。

固定IP的網路架構基於Kubernetes的CNI介面實現,增加了IP控制器模組,業務每次擴縮容時,都會與IP控制器互動,進行IP的變更。在業務正常升級流程中,歸屬於業務的IP將不會發生變化。依託於騰訊機房的網路支撐,平臺將容器網段的路由規則下發到交換機,實現了容器的全網漂移,而不僅僅侷限於固定的交換機。(如果你想深入快速學習Kubernetes,可以報名參加我們組織的為期3天的Kubernetes實戰培訓,一線資深講師帶你從0開始上手Kubernetes。)
針對網路限速的需求,雲平臺結合容器網路虛擬化的特性,基於自研監控與tc工具實現了容器網路限速的能力。

標準的tc工具只支援單向限速,即出口流量限速。單方向限速無法滿足業務的實際需求。在深入研究容器網路虛擬化的原理後,我們發現,容器在做虛擬化時,會建立一個網絡卡對,他們是對等的網路裝置,在宿主機上體現為veth,在容器內部體現為eth0。基於這個特性,我們實現了雙向限速:即對兩塊網絡卡同時做出口流量限速。由於是對等網絡卡,所以對veth做出口流量限速就相當於對eth0做入口流量限速。
在網路限速的基礎上,雲平臺又進行了多維度的完善,分別支援動態限速、秒級限速與彈性限速等網路應用場景,極大的實現頻寬復用。
服務發現
服務發現是容器雲平臺中非常核心的服務元件,是流量的入口,也是服務對外暴露的介面。雲平臺中IP動態分配,節點彈性伸縮,需要有一套自動變更負載均衡器的方式。對於後端服務,集團有成熟的服務治理框架與體系,在雲化過程中,中介軟體團隊對服務治理體系進行了改造使其可以適配不斷變化的雲環境。對於前端服務,集團是基於Nginx做負載均衡,並且沒有一套支援IP自動變更的架構。為了實現前端服務的雲化,雲平臺團隊與運維團隊共同設計了全新的服務發現架構。
在調研階段,雲團隊也調研了Kubernetes自帶的服務發現機制,這一機制無法提供複雜的負載均衡策略,並且無法滿足業務在特殊場景下需要對部分節點摘除流量的需求,所以最終我們否定了這一方案。

這是業界典型的服務發現架構。服務端和負載均衡器透過Consul進行解耦。服務註冊在Consul中,負載均衡器透過Watch Consul中目錄的變化來實時感知節點變更。在雲化的早期,為了滿足快速上線的需求,雲平臺對集團內部的Java Web框架進行了修改,使得其以心跳的方式自動註冊到Consul中。這很好的解決了負載均衡器自動感知業務變更的問題以及雲化過程中的流量灰度問題。
這一架構也引入了新的問題:除錯問題與多語言擴充套件問題。由於是Java框架代理業務註冊到Consul中,這使得活躍節點無法被下掉流量從而進行除錯,但實際場景中很多故障除錯需要下掉流量後才能進行。對Java語言的支援是透過修改框架來完成的,而集團中還有很多其他型別語言,比如PHP、Node.js和Go等。對每種接入語言或框架都需要以修改程式碼的方式才能接入到雲平臺中來,開發成本高並且對業務不友好。Consul被直接暴露給服務方,也增加了Consul的安全風險。
基於此,在18年4月,雲平臺對整個服務發現架構進行了升級。

新的服務發現架構中,業務與Consul中間增加了Proxy代理層,代理層透過Watch Kubernetes事件實時感知業務節點資訊的變化,配合健康檢查功能可以保證業務節點在變更時流量無損。基於代理層,任意語言的程式不需要做任何修改,僅透過簡單配置即可接入到雲平臺。服務的註冊與發現託管到雲平臺,Consul元件對業務透明,開發人員使用更友好。

 

復盤與反思

 

回顧這兩年來的容器雲架構演進過程與業務雲化歷程,復盤遇到的棘手問題及其解決方案,與大家共同探討。
在整個雲平臺的設計之初,我們有如下的設計考量:

容器雲都會面臨一個問題:對於業務來說,是容器還是虛擬機器?虛擬機器是業務習慣的使用樣式,業務更容易接受。容器是以服務為核心,服務存在即存在,服務關閉即銷毀,不再是虛擬機器以機器為核心的樣式。思慮再三,最終決定以容器的樣式來定位,全新的平臺提供全新的服務樣式與體驗。
雖然是以容器為核心,但容器中可執行單行程也可執行多行程。我們規範容器中只執行一個業務行程,防止由於執行多行程而導致業務之間相互幹擾情況的發生,這類問題很難進行排查與定位。
去Agent化:在傳統物理機樣式下,一臺物理機上可能會有多個Agent:運維管控Agent、監控Agent、業務自定義Agent等。雲化後面臨一個現實的問題:我們需要在每個容器中都安裝這些Agent麼?如果每個容器中都整合這些Agent,對雲平臺來說是簡單的,這沒有任何工作量。但是一臺物理機上可能會執行上百個容器,這些Agent數量也會大量膨脹,帶來系統負載的增加的問題。基於此,雲平臺投入大量的精力來實現容器的無Agent化,即在所有功能正常執行的前提下,Agent只執行在宿主上,不會執行在容器中。
業務雲化過程中雲團隊遇到了很多問題案例,並形成自己獨特的解決方案。這裡選擇了幾個有代表性的案例,與大家進行分享。

服務啟動耗CPU過高是雲化早期時遇到的棘手問題。這個問題產生的原因很多:Java的語言特性導致JVM是在執行中逐步進行最佳化的;內部的很多開發框架都是在流量過來時才初始化連結;某些業務資源也是在流量過來時才進行初始化。當流量分發過來時,多種資源同時初始化導致服務需要大量的CPU資源,超過了平臺為其分配的CPU配額,服務出現大量超時與拋棄。這一問題的簡單解法是多分配CPU資源,但從長遠角度來看這會導致資源利用無法有效把控,也會影響彈性排程的效果。最終,我們從兩個維度解決這一問題:在呼叫方增加預熱策略,流量逐步分發過來,CPU資源使用更平滑;在服務方增加預熱方法,預設初始化連結等資源,同時引導使用者進行自定義的初始化。
在容器監控維度方面,由於預設的監控資料是基於隨機取樣的分鐘級資料,導致當服務出現短期秒級的CPU波動時,監控系統無法捕獲,從而影響問題的排查與定位。針對這一問題,雲平臺對監控維度進行了深化,增加了容器級別秒級監控,實時採集每分鐘的最大值上報,便於問題的排查與跟蹤。

由於Cgroups只對CPU和記憶體資源進行了隔離與限速,並沒有對系統負載進行隔離,如果容器中執行行程或執行緒數過多,會導致宿主機整體的負載波動,進而對上面的所有服務都會造成影響。
雲平臺增加了兩個維度的控制策略:容器級別的最大執行緒數控制,防止由於單個容器執行緒數過多會對宿主造成影響。宿主級別的過載保護,當宿主上的負載過高時,過載保護策略會自動觸發宿主上的容器進行漂移,直至負載降至合理的範圍。
雲平臺必須關閉swap交換分割槽,這是一個深刻的經驗教訓。在雲化的早期,雲平臺的交換分割槽沒有關閉,部分服務經常出現由於使用交換分割槽而導致的耗時隨機抖動,這類問題很難排查,耗費了大量的精力。
58雲端計算平臺核心軟體版本變遷過程如下:

 

後記

 

容器雲在58集團的實踐與探索過程中,雲團隊做了很多技術選型與最佳化工作,也進行了很多技術方案的架構演進工作,究其根本原因是58集團是發展了十多年的網際網路公司,它有自己獨特的業務場景和成熟的開發體系與基礎元件,容器雲在集團內部起步較晚,內部系統很難為雲平臺做適配,只能雲平臺透過不斷演進來適配不停發展的業務場景。這也是在較有規模的網際網路公司做基礎架構與創業公司的區別和挑戰所在。所幸在團隊的共同努力下,我們用1年多的時間完成了集團流量服務的雲化工作。目前,集團內部還有很多服務需要雲化,未來的挑戰更大。
作者:姚遠,58集團雲端計算平臺技術負責人,架構師;多年網際網路開發和架構經驗,長期從事並關註服務高併發與高效能等方面工作,在58集團先後負責過訊息匯流排、呼叫鏈跟蹤系統等中介軟體系統的設計與架構工作;當前主要負責雲端計算平臺的架構與設計、推進業務雲化等工作。
贊(0)

分享創造快樂