1. 程式人生 > >搜狗BizCloud:基於Kubernetes的私有云實踐_Kubernetes中文社群

搜狗BizCloud:基於Kubernetes的私有云實踐_Kubernetes中文社群

【編者的話】隨著搜狗業務的快速增長,需要更有效地控制成本,提升研發效率,我們基於Docker和Kubernetes構建了一站式私有云管理平臺——BizCloud,此平臺涵蓋服務管理、彈性伸縮、灰度釋出、自動運維、持續整合等功能。本文將簡要介紹BizCloud的設計思路、架構及服務發現、授權、灰度釋出等核心功能的實現。

BizCloud簡介

我們基礎環境非常複雜,目前有多個版本作業系統共存,應用也常常存在著多個版本同時測試或部署,在多版本並行測試過程中,經常出現環境借用的情況,因作業系統和基礎軟體不一致的問題,會出現線下測試沒問題,但上線後出問題;其次,線上的實體機在業務低峰時使用率較低,存在較大的提升空間;服務上下線也涉及到一系列機器的申請回收流程,需要手工執行,系統的彈性伸縮能力不足。這種種問題都是我們設計私有云的原因,也就是要做到保持環境一致、提升資源利用率,並提升彈性計算能力。

為了解決上述問題,我們使用目前非常流行的容器技術Docker和容器編排工具Kubernetes,研發了商業雲平臺BizCloud。但Docker和Kubernenets只提供了一個基礎功能:容器執行和容器編排,如何能快速地學會使用,併為大家所接受才是關鍵。

在自研BizCloud過程中,一個重點就是要對接、打通現存的系統和流程,儘量保持使用者操作習慣,服務在容器化的過程中,儘可能不需要調整,這樣系統才易於推廣落地;另一方面,我們要支援服務一鍵自動部署(QA特別需要這樣的功能),服務出現故障後,如系統宕機或服務掛掉後,服務能自動遷移,而且我們需要支援灰度釋出,儘量實現運維的自動化。

商業平臺系統的整體架構如下圖所示。共分為三層,IaaS層、PaaS層、SaaS層:在IaaS層,我們使用Docker+Kubernetes封裝了部門的基礎資源,提供容器化服務;PaaS層提供了很多基礎服務和基礎框架,並且也實現了一些自動化工具,包括剛才提到過的統一服務管理中心,統一配置中心,專案管理系統、SOA服務框架等,貫穿了應用開發、測試、運維整個生命週期的一體化平臺,其中的紅色部分,包括服務管理、編譯中心、商業雲平臺都是為BizCloud而新開發的模組;第三層SaaS主要是一些商業平臺業務系統。本文的分享也主要集中在PaaS層的研發實踐上。

關鍵功能解析

對於一個服務而言,不管是部署還是故障遷移,都有很重要的兩個功能:在服務啟動之前,要申請服務所需資源的許可權,如資料庫許可權,開通iptables等,也就是服務授權;而服務啟動之後,要暴露服務給使用方,現在服務部署到某個機器上了,需要將請求傳送到這臺機器上,這個過程是服務發現。以往這兩個工作主要是人工執行,在BizCloud中,這兩個過程需要自動化執行。

自動化執行這個過程需要解決3個問題:1) when,什麼時候執行;2)who,誰來執行;3)how,怎麼執行。為實現服務版本的平滑過渡,BizCloud也提供了灰度釋出功能,以降低上線風險;灰度釋出不是一個獨立的系統,但和系統的架構是緊密相連的。下面我們分別介紹服務發現,服務授權和灰度釋出的實現要點。

服務發現

首先是when,即服務發現和服務授權的發起時間,我們知道在Kubernetes服務裡,服務狀態的變化和Pod的變化是緊密相連的,因此,我們引入了一個模組k8s-monitor,用來監控並判斷髮起動作。

k8s-monitor是BizCloud的監控器,其主要功能是監控Kubernetes叢集中的Pods的狀態事件:ADD、MODIFY、DELETE,監控到事件後,k8s-monitor計算是否需要進行服務發現或服務授權等相關處理,如果需要,則通知下游系統進行處理。除了常規的事件監控之外,k8s-monitor還會定期與服務管理模組同步資料,清理服務管理模組上可能存在的髒資料。

使用k8s-monitor這樣一個單獨的模組,好處是顯而易見的:將相關許可權集中管理起來,避免雲平臺入侵應用,如果沒有這樣一個模組,每個應用都需要增加自己的的服務授權和服務發現的功能,對模組入侵較大;其次,這個模組非常容易擴充套件,其他服務也可以訂閱這個模組的資料,實現自己的處理邏輯。

通常一個典型的服務都有兩層:一個使用者接入層,通常是用Nginx接入使用者流量,Nginx將流量分發到後面的Web伺服器上;第二層SOA層,這裡Web服務通過SOA呼叫後端服務,後端服務也可繼續呼叫其他服務,最終將使用者請求返回。在做服務發現時,需要完成這兩種型別的服務發現。

首先,對於接入層,如圖所示,如果Pod1因故障掛掉,Kubernetes重新排程了PodN之後,k8s-monitor監控到(至少)2個事件:Pod1 DEL,PodN ADD,k8s-monitor將事件通知到服務管理中心。Nginx會實時從服務管理中心獲取服務對應關係,動態載入Nginx配置,將已經掛掉的Pod1從Nginx中摘除,新增加的PodN暴露給外部。

而SOA服務的角色分為兩種,一種是consumer,一種是provider。consumer和provider之間的負載均衡、白名單控制是通過SOA的註冊中心來統一管理。像圖裡展示的,如果Pod1因故障掛掉,Kubernetes重新排程了PodN之後,k8s-monitor將監控到的事件Pod1 DEL,PodN ADD通知到SOA註冊中心,SOA註冊中心會將對應的變化更新到ZK上,ZK會觸發事件通知服務的consumer獲取最新的服務provider。

授權

由於商業平臺的特殊性,對許可權控制非常嚴格,許可權控制的重要性在於:1)防止測試流量打到線上; 2)防止惡意訪問等。以前模式往往是人工檢驗進行授權,但在雲平臺上,這種方式不再適用,Kubernetes也沒有直接提供授權的功能,而且授權是和系統架構緊密相關的。

為滿足BizCloud的需求,對服務授權進行了改造,當時改造面臨了一些挑戰:首先服務依賴關係從何獲取;其次,容器可能隨時啟動、銷燬,服務IP會隨容器變動;再次,我們需要同時支援DB授權、IP白名單授權、SOA等不同粒度的授權。

服務授權的發起仍然依賴於k8s-monitor,與服務發現類似,k8s-monitor將監控到的事件Pod1 DEL,PodN ADD,包括一些其他服務基本資訊、IP等通知到授權模組,授權模組開始執行授權工作。

剛才說明了授權的時間,但具體給誰來授權呢?如下圖所示,每一個服務都有自己的服務配置資訊,這裡展示一個服務,該服務依賴了很多資源,包Redis、資料庫(1個主庫、2個從庫)等資源。將這些配置檔案上傳到配置中心後,配置中心會將這些配置解析,然後根據這些依賴關係計算出依賴圖,如右圖所示。新啟動的服務可以從配置中心獲取自己的資源依賴關係,要申請的資源。

對於不同型別的授權,我們有不同的處理方式,每種授權對應的粒度也不同:1)DB授權,授權資訊包括ip+port+user,通過資料庫執行機來執行,將授權資訊寫入資料庫許可權表;2)SOA授權,這裡授權資訊包括服務例項+ip+port,該類授權通過SOA註冊中心執行,最終生成服務訪問白名單;3)iptable授權,授權資訊包括ip+port,這類授權通過salt-stack執行,最終會寫入系統的iptables檔案。

灰度釋出

我們的灰度釋出的週期一般比較長,為了保證灰度的一致性,我們會將上下游依賴的服務分組,一個正常組,一個灰度組。在具體執行時,我們會多建一個灰度的Deployment,這樣每個服務有2組Deployment,一個正常Deployment、一個灰度Deployment,然後根據灰度比例動態調節正常Deployment和灰度Deployment的例項數,從而實現灰度釋出。在流量接入方面,我們已經實現了基於使用者ID的灰度,在BizCloud上,我們的灰度分流仍然基於使用者ID。

灰度釋出時的服務發現同樣包括接入層和SOA層兩部分:對於接入層,我們使用了OpenResty,並引入了ngx_dynamic_upstream模組,這樣可以通過HTTP API方式動態調整服務的Upstream;在SOA層的灰度釋出中,我們對consumer-provider劃分為了可以動態更新的兩個組:正常組和灰度組,k8s-monitor將變更傳送到SOA註冊中心後,SOA註冊中心還是通過ZK通知Consumer取最新的provider分組,從而實現灰度分流。

配套工具

為了更方便地使用BizCloud,我們提供了多個配套工具。

WebShell

首先是WebShell。通過WebShell,我們可以從Web瀏覽器以類似SSH的方式登入並操作Docker容器,方便開發運維等檢視、除錯系統。

9.png

Webshell主要有3個元件:1)Web瀏覽器負責介面呈現;2)Docker Controller是Docker容器應用的控制中心,作為橋樑,負責訊息的轉發;3)Docker Daemon提供HTTP API介面給外部系統呼叫以訪問容器內部。

Web瀏覽器執行JS指令碼,通過Web Socket與Docker Controller建立通訊鏈路。Docker Controller通過Docker HTTP API與Docker Daemon建立通訊鏈路。這裡使用到Docker HTTP API的介面,利用返回的資料流承載Docker Controller和Docker Daemon之間的互動資料。鏈路建立後,使用者就可以在Web瀏覽器輸入字元與Docker容器互動。

模板生成

我們還提供了模組自動生成的功能,這樣開發只需要關注自己的服務即可,不需要重複編寫釋出等一系列Kubernetes部署檔案。對於一個服務,服務部署模板是提供了一類模板的集合,包括Deployment、Namespace、ConfigMaps,這些模板都是可引數化的。在具體部署服務時,也就是例項化一個服務,我們先查詢服務例項的部署環境具體的部署引數,然後將這些引數注入到模板中,生成具體的模板檔案,然後釋出。

相關係統

雲平臺其他模組在這裡做了一個簡單的展示,在左上角展示了一個應用正在執行的容器,並可以點選控制檯登入到容器內部;右上角是統一配置中心,可以檢視、操作引用對應的配置;左下角是統一服務管理平臺,上面羅列了現在線上存在的一些服務資訊;右下角是統一部署中心,在上面可以檢視服務部署的情況,包括服務授權資訊、服務發現資訊等等。

小結

在本次分享中,我們對搜狗商業平臺部的私有云BizCloud的來龍去脈做了一個簡要介紹,然後介紹了在實現商業雲平臺中的關鍵機制,包括授權、服務發現、灰度釋出的實現,也介紹了一些相關配套工具如WebShell等。使用BizCloud後, 對於dev而言流程基本不變,QA在搭建測試環境時,能一鍵部署相關服務,方便了很多,但對ops,在BizCloud上配置好應用的資源需求後,即可部署系統,一鍵實現服務擴縮容(包括橫向擴充套件,增加或減少服務例項數,也可以橫向擴充套件,增加服務的CPU和記憶體數),自動進行服務發現和授權,避免了大量重複性手工操作。

目前我們正在進行一些有狀態服務的容器化工作,如Redis、MySQL的容器化。因為我們對資料的準確性和穩定性要求非常高,所以將資料庫的容器化是非常謹慎的,我們希望隨著容器技術不斷髮展,在未來也能順利實現基礎資源的容器化。更智慧的排程:我們希望能實現一個資源負載可預測的排程演算法,能結合應用的CPU、記憶體、磁碟、網路IO、DISKIO、DBIO等歷史資料指標進行綜合計算,給出多維度下的基於時間片、優先順序的準確實時的負載預測,來執行更智慧的排程。

以上內容根據2017年09月26日晚DockOne社群微信群分享內容整理。 分享人劉林,搜狗高階工程師,畢業於中國人民大學,有多年的後臺服務開發經驗,現供職於搜狗商業平臺研發部,負責私有云的研發工作。DockOne每週都會組織定向的技術分享,歡迎感興趣的同學加微信:liyingjiesa,進群參與,您有想聽的話題或者想分享的話題都可以給我們留言。