天天看點

BizCloud:基于Kubernetes的私有雲實踐

BizCloud:基于Kubernetes的私有雲實踐

随着搜狗業務的快速增長,需要更有效地控制成本,提升研發效率,我們基于Docker和Kubernetes建構了一站式私有雲管理平台——BizCloud,此平台涵蓋服務管理、彈性伸縮、灰階釋出、自動運維、持續內建等功能。本文将簡要介紹BizCloud的設計思路、架構及服務發現、授權、灰階釋出等核心功能的實作。

BizCloud:基于Kubernetes的私有雲實踐

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

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

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

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

BizCloud:基于Kubernetes的私有雲實踐
BizCloud:基于Kubernetes的私有雲實踐

對于一個服務而言,不管是部署還是故障遷移,都有很重要的兩個功能:在服務啟動之前,要申請服務所需資源的權限,如資料庫權限,開通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這樣一個單獨的子產品,好處是顯而易見的:将相關權限集中管理起來,避免雲平台***應用,如果沒有這樣一個子產品,每個應用都需要增加自己的的服務授權和服務發現的功能,對子產品***較大;其次,這個子產品非常容易擴充,其他服務也可以訂閱這個子產品的資料,實作自己的處理邏輯。

BizCloud:基于Kubernetes的私有雲實踐

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

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

BizCloud:基于Kubernetes的私有雲實踐

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

BizCloud:基于Kubernetes的私有雲實踐

授權

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

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

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

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

BizCloud:基于Kubernetes的私有雲實踐

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

BizCloud:基于Kubernetes的私有雲實踐

灰階釋出

我們的灰階釋出的周期一般比較長,為了保證灰階的一緻性,我們會将上下遊依賴的服務分組,一個正常組,一個灰階組。在具體執行時,我們會多建一個灰階的Deployment,這樣每個服務有2組Deployment,一個正常Deployment、一個灰階Deployment,然後根據灰階比例動态調節正常Deployment和灰階Deployment的執行個體數,進而實作灰階釋出。在流量接入方面,我們已經實作了基于使用者ID的灰階,在BizCloud上,我們的灰階分流仍然基于使用者ID。

BizCloud:基于Kubernetes的私有雲實踐

灰階釋出時的服務發現同樣包括接入層和SOA層兩部分:對于接入層,我們使用了OpenResty,并引入了ngx_dynamic_upstream子產品,這樣可以通過HTTP API方式動态調整服務的Upstream;在SOA層的灰階釋出中,我們對consumer-provider劃分為了可以動态更新的兩個組:正常組和灰階組,k8s-monitor将變更發送到SOA注冊中心後,SOA注冊中心還是通過ZK通知Consumer取最新的provider分組,進而實作灰階分流。

BizCloud:基于Kubernetes的私有雲實踐

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

WebShell

首先是WebShell。通過WebShell,我們可以從Web浏覽器以類似SSH的方式登入并操作Docker容器,友善開發運維等檢視、調試系統。

Webshell主要有3個元件:1)Web浏覽器負責界面呈現;2)Docker Controller是Docker容器應用的控制中心,作為橋梁,負責消息的轉發;3)Docker Daemon提供HTTP API接口給外部系統調用以通路容器内部。

BizCloud:基于Kubernetes的私有雲實踐

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:基于Kubernetes的私有雲實踐

相關系統

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

BizCloud:基于Kubernetes的私有雲實踐
BizCloud:基于Kubernetes的私有雲實踐

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

目前我們正在進行一些有狀态服務的容器化工作,如Redis、MySQL的容器化。因為我們對資料的準确性和穩定性要求非常高,是以将資料庫的容器化是非常謹慎的,我們希望随着容器技術不斷發展,在未來也能順利實作基礎資源的容器化。更智能的排程:我們希望能實作一個資源負載可預測的排程算法,能結合應用的CPU、記憶體、磁盤、網絡IO、DISKIO、DBIO等曆史資料名額進行綜合計算,給出多元度下的基于時間片、優先級的準确實時的負載預測,來執行更智能的排程。

Jav