此文已由做者劉超受權網易雲社區發佈。數據庫
歡迎訪問網易雲社區,瞭解更多網易技術產品運營經驗後端
4、Kubernetes 自己就是微服務架構緩存
基於上面這十個設計要點,咱們再回來看 Kubernetes,會發現越看越順眼。網絡
首先 Kubernetes 自己就是微服務的架構,雖然看起來複雜,可是容易定製化,容易橫向擴展。架構
如圖黑色的部分是 Kubernetes 原生的部分,而藍色的部分是網易云爲了支撐大規模高併發應用而作的定製化部分。併發
Kubernetes 的 API Server 更像網關,提供統一的鑑權和訪問接口。負載均衡
衆所周知,Kubernetes 的租戶管理相對比較弱,尤爲是對於公有云場景,複雜的租戶關係的管理,咱們只要定製化 API Server,對接 Keystone,就能夠管理複雜的租戶關係,而不用管其餘的組件。less
在 Kubernetes 中幾乎全部的組件都是無狀態化的,狀態都保存在統一的 etcd 裏面,這使得擴展性很是好,組件之間異步完成本身的任務,將結果放在 etcd 裏面,互相不耦合。運維
例如圖中 pod 的建立過程,客戶端的建立僅僅是在 etcd 中生成一個記錄,而其餘的組件監聽到這個事件後,也相應異步的作本身的事情,並將處理的結果一樣放在 etcd 中,一樣並非哪個組件遠程調用 kubelet,命令它進行容器的建立,而是發現 etcd 中,pod 被綁定到了本身這裏,方纔拉起。異步
爲了在公有云中實現租戶的隔離性,咱們的策略是不一樣的租戶,不共享節點,這就須要 Kubernetes 對於 IaaS 層有所感知,於是須要實現本身的 Controller,Kubernetes 的設計使得咱們能夠獨立建立本身的 Controller,而不是直接改代碼。
API-Server 做爲接入層,是有本身的緩存機制的,防止全部的請求壓力直接到後端數據庫上。可是當仍然沒法承載高併發請求時,瓶頸依然在後端的 etcd 存儲上,這和電商應用一摸同樣。固然可以想到的方式也是對 etcd 進行分庫分表,不一樣的租戶保存在不一樣的 etcd 集羣中。
有了 API Server 作 API 網關,後端的服務進行定製化,對於 client 和 kubelet 是透明的。
如圖是定製化的容器建立流程,因爲大促和非大促期間,節點的數目相差比較大,於是不能採用事先所有建立好節點的方式,這樣會形成資源的浪費,於是中間添加了網易雲本身的模塊 Controller 和 IaaS 的管理層,使得當建立容器資源不足的時候,動態調用 IaaS 的接口,動態的建立資源。這一切對於客戶端和 kubelet 無感知。
爲了解決超過 3 萬個節點的規模問題,網易雲鬚要對各個模塊進行優化,因爲每一個子模塊僅僅完成本身的功能,Scheduler 只管調度,Proxy 只管轉發,而非耦合在一塊兒,於是每一個組件均可以進行獨立的優化,這符合微服務中的獨立功能,獨立優化,互不影響。並且 Kubernetes 的全部組件都是 Go 開發的,更加容易一些。因此 Kubernetes 上手慢,可是一旦須要定製化,會發現更加容易。
5、Kubernetes 更加適合微服務和 DevOps 的設計
好了,說了 K8S 自己,接下來講說 K8S 的理念設計,爲何這麼適合微服務。
前面微服務設計的十大模式,其中一個就是區分無狀態和有狀態,在 K8S 中,無狀態對應 deployment,有狀態對應 StatefulSet。
deployment 主要經過副本數,解決橫向擴展的問題。
而 StatefulSet 經過一致的網絡 ID,一致的存儲,順序的升級,擴展,回滾等機制,保證有狀態應用,很好地利用本身的高可用機制。由於大多數集羣的高可用機制,都是能夠容忍一個節點暫時掛掉的,可是不能容忍大多數節點同時掛掉。並且高可用機制雖然能夠保證一個節點掛掉後回來,有必定的修復機制,可是須要知道剛纔掛掉的究竟是哪一個節點,StatefulSet 的機制可讓容器裏面的腳本有足夠的信息,處理這些狀況,實現哪怕是有狀態,也能儘快修復。
在微服務中,比較推薦使用雲平臺的 PaaS,例如數據庫,消息總線,緩存等。可是配置也是很是複雜的,由於不一樣的環境須要鏈接不一樣的 PaaS 服務。
K8S 裏面的 headless service 是能夠很好地解決這個問題的,只要給外部服務建立一個 headless service,指向相應的 PaaS 服務,而且將服務名配置到應用中。因爲生產和測試環境分紅 Namespace,雖然配置了相同的服務名,可是不會錯誤訪問,簡化了配置。
微服務少不了服務發現,除了應用層可使用 SpringCloud 或者 Dubbo 進行服務發現,在容器平臺層固然是用 Service了,能夠實現負載均衡,自修復,自動關聯。
服務編排,原本 K8S 就是編排的標準,能夠將 yml 文件放到代碼倉庫中進行管理,而經過 deployment 的副本數,能夠實現彈性伸縮。
對於配置中心,K8S 提供了 configMap,能夠在容器啓動的時候,將配置注入到環境變量或者 Volume 裏面。可是惟一的缺點是,注入到環境變量中的配置不能動態改變了,好在 Volume 裏面的能夠,只要容器中的進程有 reload 機制,就能夠實現配置的動態下發了。
統一日誌和監控每每須要在 Node 上部署 Agent,來對日誌和指標進行收集,固然每一個 Node 上都有,daemonset 的設計,使得更容易實現。
固然目前最最火的 Service Mesh,能夠實現更加精細化的服務治理,進行熔斷,路由,降級等策略。Service Mesh 的實現每每經過 sidecar 的方式,攔截服務的流量,進行治理。這也得力於 Pod 的理念,一個 Pod 能夠有多個容器,若是當初的設計沒有 Pod,直接啓動的就是容器,會很是的不方便。
因此 K8S 的各類設計,看起來很是冗餘和複雜,入門門檻比較高,可是一旦想實現真正的微服務,K8S 能夠給你各類可能的組合方式。實踐過微服務的人,每每會對這一點深有體會。
6、Kubernetes 常見的使用方式
下面咱們來看一下,微服務化的不一樣階段,Kubernetes 的使用方式。
第一階段:使用公有云虛擬機
也即沒有微服務化的階段,基本上一個進程就能搞定,兩個進程作高可用,不須要使用容器,虛擬機就很是好。
第二階段:容器做爲持續集成工具
當微服務開始拆分了,如何保證拆分後功能的一致性,須要持續集成做爲保證,如前面的論述,容器是很是好的持續集成工具,是解決 CI/CD 中 D 的,因此一開始用 host 網絡就能夠,這樣能夠保證部署方式和原來兼容。
若是想用私有云進行部署,直接部署在物理機上,在性能要求沒有很高,可是又要和其餘物理機很好的通訊的狀況下,能夠用 bridge 打平網絡的方式比較好。經過建立網橋,將物理網卡,容器網卡都鏈接到一個網橋上,能夠實現全部的容器和物理機在一樣的一個二層網絡裏面。
若是性能要求比較高,例如要部署相似緩存,則可使用 sr-iov 網卡。
若是想實現租戶的簡單隔離,則每每使用各類 Overlay 的網絡模式,這是最經常使用的部署方式。圖中的數據來自網絡。Flannel,Calico 都是很是好的網絡插件,雖然 Flannel 一開始使用用戶態的模式性能很差,後來使用內核態,性能大大改善,使用 gw 模式後,和 Calico 性能至關。
網易雲採用了 Kubernetes 和 IaaS 深度融合的方式,相似 AWS 的 Fargate 的模式,一方面可使得原來使用虛擬機的用戶平滑地遷移到容器,另外一方面能夠實現公有云的租戶隔離。
如圖是融合的網易雲容器服務的架構,這個管理 OpenStack 和 Kubernetes 的管理平臺,也是用的微服務架構,有 API 網關,熔斷限流功能,拆分紅不一樣的服務,部署在 K8S 上的,因此到處是微服務。
網易雲輕舟微服務是圍繞應用和微服務打造的一站式 PaaS 平臺,幫助用戶快速實現易接入、易運維的微服務解決方案。
相關閱讀:爲何 kubernetes 自然適合微服務 (1)
爲何 kubernetes 自然適合微服務 (2)
爲何 kubernetes 自然適合微服務 (3)
文章來源: 網易雲社區