微服務化的不一樣階段 Kubernetes 的不一樣玩法


本文由 網易雲 發佈。數據庫

做爲容器集羣管理技術競爭的大贏家,Kubernetes已經和微服務緊密聯繫,採用Kubernetes的企業每每都開始了微服務架構的探索。然而不一樣企業不一樣階段的微服務實踐面臨的問題千差萬別,註定要在技術路線上產生分叉。如何選擇適合本身的技術,是每個踐行微服務的團隊面臨的第一個問題。網易雲是Kubernetes的第一批重度用戶,在不一樣業務場景下解決了不少挑戰,在本文中,網易雲首席解決方案架構師劉超梳理了基於Kubernetes構建微服務體系的進階之路。緩存

高速增加階段,微服務化的必要性

一個產品的發展,一般可分爲冷啓動階段、高速增加階段和成熟階段。網絡

產品冷啓動階段,需求是以最簡單的架構驗證業務。以網易考拉海購(如下簡稱「網易考拉」)爲例,最初的架構設計目標就是快速啓動,驗證產品方向,該架構包括在線、緩存、線下和管理服務四個方面,即通常電商平臺加上跨境電商必備的進銷存系統,採用了Oracle數據庫、OpenStack管理的虛擬機(VM),並無諸如高併發之類的考慮。架構

產品高速增加階段,業務規模逐漸擴大,產品複雜度也隨着增長,企業須要解決快速迭代、高可靠和高可用等問題,一個天然的選擇是服務化的拆分,把一個單體架構拆分紅一些較小的模塊,並遵循康威定律,用5-9個小團隊來適應架構的變化。仍以網易考拉爲例,網易考拉在高速增加階段也慢慢演化出各類新的模塊,好比單獨的支付模塊、貨倉模塊、第三方商家模塊、推送模塊等,並基於Dubbo框架打造服務發現功能來支持各模塊之間的相互調用。併發

服務化主要解決了變動的問題。在整個架構演進的過程當中,各個模塊都面臨爆炸性的增加,好比海淘、自營、第三方商家的供應鏈,Web、APP、H5的呈現,限時購、秒殺、預售的活動頁,以及倉庫與物流系統、支付系統的對接等,緊耦合則牽一髮而動全身,工程臃腫,影響迭代速度,分別獨立上線更有利於適應業務發展的需求。網易考拉在高速增加階段首先按照主頁、活動頁、優惠券、支付等維度縱向拆分,以後又不斷演進成爲100多個相互關聯的模塊,變動頻率由天天2次增加到天天1000屢次,產品質量提高52%。負載均衡

容器化的優點與挑戰

拆分紅大量小模塊以後,虛擬機與服務化架構的配合就出現了不少新的挑戰,因而有了容器化的需求。框架

劉超解釋說,拆分以前首先要解決「合」的問題,即須要保證功能仍是原來的功能,代碼質量仍是原來的代碼質量,不會引入新的bug。他認爲,微服務化須要從一開始就要作好持續集成,而容器是很好的持續集成的工具,完成從代碼提交到自動測試、自動發佈的工做。容器化會帶來開發流程的變化,把環境交付過程從運維人員提早到開發人員手上。less

在架構複雜的狀況下,好比100多個模塊,再加上各類副本,全部環境都由一個運維團隊來完成,不只工做量繁重,並且還容易出錯,但這是使用虛擬機的模式。而若是寫一個Dockerflie放到代碼倉庫,由開發人員來考慮開發完成以後應用部署的配置環境、權限等問題,包括測試環境的部署、聯調環境的部署、生產環境的部署,問題就很好解決了。這就是容器化帶來的流程變化。運維

然而,這種轉變涉及到開發人員是否願意學習容器技術。劉超推薦的解決辦法,是使用鏡像分層的形式,即最內部的環境包括操做系統及系統工具的鏡像由運維人員來作,中間層環境的鏡像由核心開發人員完成,普通開發人員只需把jar或者war扔到相應的路徑下便可,這就極大下降企業組織容器化的障礙。分佈式

場景一:Kubernetes + Docker + VM + Host Network

第一種場景,就是用Kubernetes管理虛擬機,容器的網絡、存儲會面臨各類各樣的選型。企業若是對容器的網絡、存儲瞭解不足,能夠把容器當成一個持續集成的工具,把一個容器嵌入到一個虛擬機裏面,至關於用容器鏡像代替腳本部署。這種作法須要解決兩個問題:一是IP保持的問題,二是盤保持的問題。由於原先採用虛擬機的時候,是基於有狀態的設計,認爲IP、Volume都是保持不變的。當容器僅僅做爲持續集成的工具,團隊的這個習慣可能改不了。

一個方案是本身實現一個有狀態容器的方式,實現IP的保持,當一個節點掛了,從新啓動的虛擬機和容器仍然可使用原先分配的IP,二是把Docker容器的鏡像一層層地Mount到外面的Volume裏面,當一個節點掛了,Docker全部的鏡像和Volume其實還掛載在外面的Ceph上,數據並未丟失。這和使用VM很類似,既能夠Docker化支持微服務化,也不須要改變用戶習慣。使用Kubernetes壓力相對比較大的團隊,能夠經過這種方式切入。

場景二:Kubernetes + Docker + PM + Bridge Network

第二種場景,企業沒有使用虛擬機,有一部分應用部署在PM上(注:本文中PM特指物理機),同時想把一部分應用遷移到容器裏。此時,無論物理機是否嵌套虛擬機,直接建立一個Bridge Network,把物理網卡也打進去,當Docker的網卡和Bridge連起來的時候,整個網絡就是平的,容器和容器旁邊的物理機都使用同一個指定的網段。網絡打平以後,使用Dubbo的團隊也能夠比較順暢地把一部分物理機上部署的應用逐漸遷移到容器裏,而若是沒有Bridge
Network,中間過負載均衡(LB)或者NAT時會很彆扭,由於Kubernetes層的維護人員一般很難勸說Dubbo層開發人員改變應用開發的方式。

使用Bridge
Network,Kubernetes網絡配置很簡單,使用CNI的方式便可。若是有定製化以適應應用層的需求,能夠參考Docker run的手動配置方式,開發本身的CNI插件。大體流程是先建立網橋(若是不存在),獲取Namespace,配置veth pair並放到Namespace裏,而後獲取IP地址,獲取網絡和路由。

場景三:Kubernetes + Docker + PM + SR-IOV Network

Bridge的方式,可以知足通常的Java應用部署的需求,但一些須要更高性能的應用,須要高吞吐量、高併發、高PPS,好比電商大促狀況下的緩存,這時候能夠採用SR-IOV代替Bridge來解決問題,帶寬比較大但PPS上不去(大包或大量小包)的狀況,SR-IOV均可以解決,可是須要購買SR-IOV網卡,成本比較高。

高可用設計要點

無狀態。作好持續集成以後,第一件事情應該是把應用分爲有狀態(Stateful)和無狀態(Stateless)兩個部分,而且使大部分應用是無狀態的,這樣能夠更好地適應彈性伸縮。即使Kubernetes已經能夠支持有狀態應用的部署,劉超仍是建議在應用層儘可能實現無狀態,使得有狀態應用匯集在少數的集羣裏面。有狀態最重要的是數據庫和緩存,一般內存數據放在緩存,須要持久化的數據放在數據庫裏。

分佈式數據庫。數據庫的高可用,網易雲採用的是DDB(分佈式數據庫)方案,基於MySQL的多臺主備及負載均衡作分庫分表,網易雲RDS基於本身的MySQL內核優化,可以實現主備切換不丟數據,可以很好地支持容器化,有狀態容器掛掉以後,從新啓動一個容器,只要作好前序重置和冪等,就不會有業務問題。因此網易雲RDS的主備切換也從虛擬機向容器過渡。

緩存。高併發應用須要每一層都有緩存,把客戶需求儘量地攔在前面,吞吐量就大不少。但緩存不像數據庫同樣有持久化機制,其高可用、跨機房就須要作雙寫,由於緩存保持在內存中,掛了就沒有了,修復難度很大。其餘的組件,好比ZooKeeper、Kafka、消息隊列、HBase,都有各自的高可用機制。因此,一個發展中的應用應當被分紅很顯著的兩個部分,一部分是無狀態的,另外一部分有狀態的就放到自己具備高可用機制的組件裏面。

成熟階段架構

產品成熟階段要解決的問題,主要是如何經過服務治理、系統運維自動化提高可靠性和可用性,如何高效完成大項目的複雜協做,如何梳理功能、深化用戶體驗。以正在進行全面服務化的網易考拉爲例,2017年雙11期間其工程數量相對平時增長了20多倍,應用、存儲集羣規模膨脹了5倍,挑戰之大沒必要多說。劉超對成熟階段架構設計強調了兩點:

不可變基礎設施:使用Kubernetes容器技術不能沿襲虛擬機時代的操做方式,而是應當採用不可變基礎設施,即全部的改變,都應該在Git的改變裏面有所體現,修改環境就是修改Dockerfile,修改配置文件也是代碼層次的改變,整個環境的部署,當代碼merge的時候,會觸發經過容器自動部署的腳本,這能很好地保持環境的一致性。大規模節點下,若是是手動部署,出錯很容易,排查卻很難。因此,不可變基礎設施很是重要。

IaC(基礎設施即代碼)部署與擴容:網易雲在Kubernetes的編排以外封裝了另外一個編排,也是在倉庫裏面維護的,任何的修改,好比要升級5個應用,這5個應用的版本號都在這裏面都配置好,代碼commit以後就觸發自動部署,若是發現問題,很容易回滾,只需把代碼revert回來,後續流程會自動觸發。若是依賴於寫Yaml文件來作,頻繁升級且版本號控制很差時,就很容易回滾失誤。

場景四:Kubernetes+Docker+PM+Overlay Network

成熟階段一般使用Kubernetes+Docker+PM+Overlay Network的模式,企業一旦開始用Overlay Network,基本上都會使用物理機,不然使用虛擬機會出現兩層Overlay。這時候Flannel、Calico、Romana或者Weave等不少的選型均可以,Flannel的性能已經愈來愈好。

場景五:Kubernetes和IaaS層深度融合

網易雲的方式,是Kubernetes與IaaS深度融合實現動態擴展資源,目前集羣調度規模支持30000+節點。這個規模下,首先要解決的是動態資源建立優化,這樣才符合資源精細利用、成本最優化的設計。同時,不論虛擬機的建立仍是容器的建立,對應用都是透明的,也就是說,應用只須要明確一個模塊要變成3個節點仍是5個節點,不須要管Docker是否是要變成多少個節點、這些節點要放在哪裏、虛擬機和物理機是否有資源之類的問題,後續的動做都是聯動的。

動態資源建立的實現,網易雲改造了Kubernetes建立流程,主要是監聽Pod建立的事件,由Resource Controller判斷有沒有足夠的Volume資源、Network資源,Schedule判斷有沒有足夠的Node資源,有則直接綁定,無則動態申請以後再綁定,而後由Kubernetes下發。添加資源的時候,只有應用層和機房兩層,機房只須要把物理機添加到IaaS層,不須要管上面是否有Kubernetes,虛擬機的建立所有是動態的,應用層只管應用層的事情,中間都是透明的。

其次是網絡優化。網易雲大部分容器是運行在虛擬機上的,同時也提供採用SR-IOV網卡的裸機容器,用於須要更高性能的緩存、分佈式數據庫等。大部分的應用能夠橫向擴展,仍是在IaaS裏面。可是網易雲但願容器裏面的網卡,讓最外層虛擬機上的OVS也能夠看到,即只有一層Overlay,虛擬機裏面有一個Bridge,但若是不須要,也能夠直接打到外面的OVS上,另外還有一個管理網絡,跨租戶也是同一個Kubernetes來管理。只有一層Overlay意味着沒有二次的虛擬化,同時原來部署在虛擬機裏面的應用遷移到容器中,虛擬機和容器的網絡都是經過OVS來管理,採用Dubbo作服務發現會很是平滑,這是針對業務層壓力的解決方案。其實OpenStack有一個CNI插件,也採用了相似的作法,和Neutron聯動,把VIF打在外面的OVS上。

小結

本文結合網易雲服務內外部客戶的Kubernetes實踐經驗,總結了產品高速增加期和成熟期使用Kubernetes容器技術實現微服務架構的五種應用場景,針對不一樣的挑戰提出了易於執行的解決方案,並介紹了網易雲的獨門優化方法,但願對讀者有所啓發。


瞭解網易雲:

網易雲官網:www.163yun.com/

新用戶大禮包:www.163yun.com/gift

網易雲社區:sq.163yun.com/

相關文章
相關標籤/搜索