文/盛樂標 游偉倩 張予倩 周慶林
Kubernetes 自2015年正式推出之后,受到了眾多軟件開發(fā)和運維人員的關注。Kubernetes構(gòu)建于Google公司多年生成環(huán)境經(jīng)驗基礎之上,是用于自動部署、擴展和管理容器化應用程序的開源系統(tǒng)。隨著微服務架構(gòu)和容器技術(shù)的流行,在生產(chǎn)環(huán)境中部署Kubernetes集群的需求也逐漸顯現(xiàn)。然而,傳統(tǒng)的Kubernetes集群部署,只部署單臺Kubernetes API服務器,這種部署方式存在天生的缺陷,容易出現(xiàn)因Kubernetes API服務器單點故障導致整個Kubernetes集群不能正常服務。借鑒高性能計算集群的高可用和負載均衡設計,本文將主要介紹Kubernetes集群部署的高可用和負載均衡策略。
云計算、容器技術(shù)和微服務架構(gòu)的發(fā)展,在很大程度上推動了Kubernetes的迅速崛起。容器技術(shù)實現(xiàn)了軟件交付的標準化,而微服務架構(gòu)實現(xiàn)了對軟件功能的解耦。微服務與容器技術(shù)的結(jié)合,不亞于一場軟件技術(shù)革命,微服務架構(gòu)的優(yōu)點被進一步放大,軟件的敏捷性和適應性得到了有效的提升,此時,健壯靈活的容器編排系統(tǒng)便成為新的軟件模式大范圍推廣與應用的基礎。Kubernetes便是在這種背景之下誕生的。由于Kubernetes更側(cè)重業(yè)務層的資源調(diào)度和眾多的知名廠商支持,其一經(jīng)推出,便獲得了廣泛關注,成為Github上最活躍的幾個開源項目之一,迅速趕超另外兩款容器編排系統(tǒng)Swarm和Mesos。
圖1:HAProxy四層負載均衡NAT模式原理圖
因為Kubernetes集群需要通過Master節(jié)點提供Kubernetes API服務,進行資源的調(diào)度,因此在生產(chǎn)環(huán)境中部署時,必須要避免Master節(jié)點的單點設計,建設高可用的Kubernetes Master節(jié)點群,并通過負載均衡分流各個Master節(jié)點的壓力。
在業(yè)務比較繁重的生產(chǎn)環(huán)境,如果一臺服務器承受過多的壓力,這臺服務器很可能因為資源消耗過多而導致服務器宕機。因此,在生產(chǎn)環(huán)境中應當讓每臺服務器承受的負載在合理的范圍內(nèi),當一臺服務器無法滿足業(yè)務需求時,就需要使用多臺服務器分攤這些負載,并將這些服務器當作一個整體對外提供服務。將一臺服務器的負載分攤到多臺服務器上的技術(shù),就是負載均衡技術(shù)。實現(xiàn)負載均衡既有硬件方案和也有軟件方案。硬件方案需要購買特定的負載均衡設備,成本較高,不在本文的探討范圍之內(nèi),本文的負載均衡主要涉及的是軟件方案。在軟件方案中,實現(xiàn)負載均衡的軟件主要有LVS,HAProxy,NGINX等,本文的負載均衡使用HAProxy的軟件方案。HAProxy可以實現(xiàn)四層和七層的負載均衡,并具有多種負載均衡模式。圖1是HAProxy四層負載均衡NAT模式的原理圖,本文中Kubernetes集群的負載均衡設計即采用此模式。
假設后端服務器全部位于內(nèi)網(wǎng),而負載均衡服務器則擁有公網(wǎng)IP地址VIP,同時為了與內(nèi)網(wǎng)工作的后端服務器通訊,它還具有一個內(nèi)網(wǎng)IP(LIP),后端服務器n的IP地址則表示為RIPn。當客戶端(IP地址為CIP)向負載均衡服務器發(fā)送請求時,請求報文到達負載均衡服務器,報文中的目標IP(即VIP)被修改為其中一臺后端服務器的IP(具體將報文轉(zhuǎn)發(fā)給哪一臺真實服務器則取決于所選擇的負載均衡算法,最常見的便是輪詢算法),例如工作服務器1的IP地址RIP1,此后報文經(jīng)由Postrouting鏈路直接發(fā)往后端服務器1,后端服務器1接收到報文,處理后進行響應,將響應報文發(fā)回負載均衡服務器,負載均衡器將源地址RIP修改為VIP并返回給客戶端。若后端服務器的網(wǎng)關地址不是負載服務器的地址LIP,為保證后端服務器的報文能夠正常傳遞給負載均衡服務器,某些負載均衡策略還會對報文的源IP進行修改。
Kubernetes集群的高可用和負載均衡,主要是指Kubernetes API服務器的高可用和負載均衡,而部署在集群上的各種應用的高可用與負載均衡則由Kubernetes負責處理。前面我們介紹了HAProxy基于四層網(wǎng)絡的NAT模式,但Kubernetes集群如果像圖1那樣只部署一臺負載均衡服務器,雖然解決了Kubernetes集群負載均衡的問題,但是負載均衡服務器本身卻也帶來了新的問題:如果負載均衡服務器發(fā)生單點故障怎么辦?這時我們就需要借助另外的手段來實現(xiàn)負載均衡服務器的高可用。本文中負載均衡服務器的高可用通過Keepalived來實現(xiàn)。整套Kubernetes高可用負載均衡集群的架構(gòu)示意圖見圖2。
圖2:Kubernetes高可用集群總體框架圖
Etcd服務器、API服務器、應用節(jié)點是Kubernetes集群的基本組成部分,這部分內(nèi)容已經(jīng)有專文描述[,本文中不再展開。為了實現(xiàn)Kubernetes集群的高可用和負載均衡 ,我們在Kubernetes API之前增加了兩臺HAProxy負載均衡服務器,增加負載均衡服務器是避免其單點故障的手段,但是多臺負載均衡服務器便會產(chǎn)生多個訪問IP,如何讓外部客戶端通過一個唯一的IP訪問Kubernetes集群,這便是Keepalived需要處理的事。圖2中,我們在兩臺負載均衡服務器上均部署了Keepalived,通過Keepalived的虛擬IP(Virtual IP,VIP)統(tǒng)一對外提供服務。
在兩臺負載均衡服務器中安裝好HAProxy軟件以后,需要在haproxy.cfg文件中進行相關配置,配置文件中相關內(nèi)容如下:
上面的配置文件表示將任何訪問本機6443端口(Kubernetes API服務端口)的TCP流量轉(zhuǎn)發(fā)到三臺Kubernetes API服務器(master01,master02,master03),并且執(zhí)行端口健康檢查,rise 3表示成功完成三次端口檢查則認為該節(jié)點工作正常,fall 3表示三次端口檢查失敗則認為該節(jié)點不可用。balance roundrobin表示采用輪詢負載均衡算法。另外,1080端口被用來顯示HAProxy的統(tǒng)計信息,在后面Keepalived的部署中,我們也將會使用http://localhost:1080/stats進行健康檢查。
圖3:Kubernetes高可用負載均衡集群網(wǎng)絡拓撲圖
Keepalived是以虛擬路由冗余協(xié)議(Virtual Router Redundancy Protocol,VRRP)為 基 礎實現(xiàn)高可用的。它將一組服務器組成一個服務器組,在這組服務器里有一個MASTER節(jié)點,該MASTER節(jié)點獲得Keepalived的虛擬IP(Virtual IP,VIP),其它均為BACKUP節(jié)點,不能獲得VIP。MASTER節(jié)點會在同網(wǎng)段內(nèi)發(fā)送VRRP組播,當BACKUP服務器收不到VRRP包時則認為MASTER節(jié)點宕機,在BACKUP節(jié)點中根據(jù)它們的優(yōu)先級選出一個新的MASTER節(jié)點,取得原MASTER節(jié)點的VIP繼續(xù)對外提供服務。
本文中,Keepalived也需要在兩臺負載均衡服務器上同時部署,安裝完 Keepalived軟件后,需要進行相關配置。配置文件keepalived.conf示例如下:
Master節(jié)點需要在vrrp_instance VI_1的state中配置MASTER,優(yōu)先級101,另外一臺state配置為BACKUP,優(yōu)先級100(低于MASTER節(jié)點的優(yōu)先級)。訪問該VIP的流量都會被Keepalived定向到Keepalived Master節(jié)點。因為Keepalived要與HAProxy結(jié)合使用,我們使用了檢查haproxy健康狀態(tài)的腳本check_haproxy.sh,腳本的詳細內(nèi)容如下:
部署完HAProxy和Keepalived后,我們需要將Kubernetes應用節(jié)點(Workers)對Kubernetes API服務器的訪問定向到Keepalived的虛擬IP上,在Kubernetes Master節(jié)點執(zhí)行如下命令:
另外,我們還需要將Kubernetes應用節(jié)點(Workers)kubelet配置文件中的server信息更改為Keepalived虛擬IP。在應用節(jié)點執(zhí)行如下命令:
經(jīng)過HAProxy和Keepalived的協(xié)同部署,我們已經(jīng)實現(xiàn)了Kubernetes集群的高可用和負載均衡。集群的網(wǎng)絡拓撲(省去Kubernetes API服務器與應用服務器之間的網(wǎng)絡部分)詳見圖3。測試結(jié)果表明,當Kubernetes應用服務器需要向Kubernetes API服務發(fā)送請求時,報文將首先尋找Keepalived的虛擬IP,而Keepalived的虛擬IP對應于其中一臺負載均衡服務器(Keepalived Master節(jié)點),請求報文被發(fā)送至該節(jié)點,該節(jié)點的HAProxy根據(jù)負載均衡算法將該報文轉(zhuǎn)發(fā)至其中一臺Kubernetes API服務器,處理后發(fā)送響應報文給應用服務器。在整個報文發(fā)送的過程中,單點故障被有效避免,同時負載均衡也將用于分流三臺Kubernetes API服務器的壓力。本文中的兩臺負載均衡服務器上的HAProxy服務實際上是主從服務模式,一臺負載均衡服務器正常工作,另一臺則是作為備份服務器。如果負載均衡服務器的壓力增大,可以將其設計成主主模式,同時提供負載均衡服務。主主模式可以通過應用兩個Keepalived虛擬IP的方式實現(xiàn),這里不再展開敘述。
這里還需要強調(diào)的是,2.3所述的HAProxy配置主要實現(xiàn)的是Kubernetes API服務器的負載均衡,如果應用節(jié)點上有對外服務的微服務或Web應用,并且該應用也需要進行負載均衡,也可以參考所述方法進設置。如果是http的負載均衡,也可以選擇使用七層負載均衡方式。
Kubernetes推出以后得到了快速的發(fā)展,加上微服務架構(gòu)的逐漸流行,部署具有高可用、負載均衡特性Kubernetes集群的需求越來越多。本文設計了一套簡單、高效的高可用負載均衡Kubernetes集群。利用該設計原則,我們可以很方便地將集群進行水平擴展,滿足一般的微服務應用場景。在本文的基礎上,我們?nèi)匀豢梢酝ㄟ^使用LVS、優(yōu)化負載均衡算法等獲得更高性能的Kubernetes集群,進一步發(fā)揮微服務架構(gòu)的優(yōu)勢。