部署微服務的時候,Spring Cloud 和 Kubernetes 哪個更好?
當我們需要部署微服務的時候,哪個更好?Spring Cloud還是Kubernetes?答案是都可以,只是各自有其優勢。
Spring Cloud 和 Kubernetes 都宣稱自己是開發和執行微服務的最佳環境,但是它們的本質非常不一樣,所追求的目標也不同。本文我們分析一下兩個平臺是如何在其擅長的、實現基於微服務的架構(MSA)上起到作用的,並判斷如何利用兩者的強項,來幫助我們在微服務旅程上獲得成功。背景故事最近我讀了A. Lukyanchikov寫的一篇非常精彩的文章[1],講的是用 Spring Cloud 和 Docker 來構建微服務架構。如果你還沒讀過,你應該讀一下,因為它給出了一個關於如何利用 Spring Cloud 來建立一個簡單的基於微服務的系統的綜合視角。為了構建一個能擴充套件到數千個服務的可擴充套件且有彈性的微服務系統,它就必須有一套擁有廣泛的構建時和執行時能力的工具集來幫助管理和控制。使用 Spring Cloud,既能實現功能型服務(比如統計服務,賬號服務以及通知服務),又能實現基礎架構服務(比如日誌分析,配置伺服器,服務發現,認證服務等)。描述這樣一個使用 Spring Cloud 構造的微服務架構(MSA)圖如下所示:
該圖包含了執行時視角,但是它不包含打包,持續整合,擴充套件性,高可用,自愈等在MSA世界中同樣重要的功能。本文假設大部分 Java開 發者都熟悉 Spring Cloud,我們來做個對比,看看 Kubernetes 是如何提出這些額外的概念,以關聯到 Spring Cloud 的。
微服務概念我們不會針對兩者一個一個概念的比對,而是根據更廣闊的微服務概念,來看看 Spring Cloud 和 Kubernetes 分別是如何實現他們的。今天有關 MSA 的一個好事是,它是一個有著易於理解的優缺點評估的架構風格。微服務能加強模組邊界,各模組可以有獨立的部署和技術差異。但是同時也帶來了代價,需要開發分散式系統以及明顯增加操作成本。一個關鍵的成功因素是聚焦於使用一套能幫助你實現儘可能多的 MSA 概念的工具。能使得啟動過程迅速且容易是很重要的,但是通向產品化的旅程是很漫長的,你需要達到這樣的高度[2]才能到達那裡。
如上圖所示,我們可以看到 MSA 中必須實現的那些最普遍的技術概念(我們將不會關注非技術概念,比如組織結構,文化等)。
技術匹配Sping Cloud 和 Kubernetes 這兩個平臺非常不一樣,並且它們之間也沒有直接的等價特性。如果我們將每個 MSA 概念匹配到這兩個平臺使用的實現這些概念的技術/專案,我們能得出下表。
Spring Cloud and Kubernetes technologies從上表中能快速得出的結論是:
Spring Cloud 有一個豐富的集合,完備整合了 Java 庫,以實現各種執行時概念,作為應用棧的一部分。因此,這些微服務自身有庫和執行時代理,來做客戶端的服務發現,負載均衡,配置更新,度量跟蹤等。各種模式,比如單叢集服務和批量任務,也是由 JVM 來管理的。
Kubernetes 相容多種語言,目標不止 Java 平臺,並且以一種通用方式為所有語言實現了分散式的計算挑戰。它提供了平臺級以及應用棧之外的服務,比如配置管理,服務發現,負載均衡,追蹤,度量,單例,排程任務。應用不需要任何庫或者代理來實現客戶端邏輯,且可用任何語言來寫。
在某些領域,兩個平臺都依賴相似的第三方工具。比如,ELK和EFK棧,追蹤庫等。某些庫,比如 Hystric 和 Spring Boot,在兩個環境上都非常有用。有些領域兩個平臺是互補的,整合到一起能創造出一個更強大的解決方案(KubeFlix[3] 和Spring Cloud Kubernetes[4] 就是這樣的例子)。
微服務需求
為了畫出每個專案的範圍,這裡有張表列出了幾乎是端到端的MSA需求,從最底層的硬體,到最上層的 DevOps 和自服務經驗,並且列出瞭如何關聯到 Spring Cloud 和 Kubernetes 平臺。
Microservices requirements在某些場景下,兩個專案使用不同的方法達成了相同的需求,在某些領域,一個專案可能會強於另一個。但是在某些情況下,兩個專案是互補的,可以組合起來達成高階的微服務經驗。例如,Spring Boot 提供了 Maven 外掛來構建單個 JAR 應用包。這樣就可以結合 Docker 和 Kubernetes 的宣告式部署和排程能力,使得執行微服務變得輕而易舉。同樣的,Spring Cloud 有個內嵌的應用庫,可以利用 Hystric(自帶隔離和熔斷模式)和Ribbon(用來負載均衡)來建立有彈性的,容錯的微服務。但是光靠這個還不夠,當這個能力和 Kubernetes 的健康檢查,程序重啟,以及自動伸縮能力結合在一起時,微服務才能成為一個反脆弱系統。
優點和缺點因為兩個平臺不能直接用每個特性來比較,我們也不打算針對每個平臺都深入每個特性,因此這裡就以總結性方式來說明一下兩個平臺的優缺點。Spring Cloud
Spring Cloud 給開發者提供了一個工具,能在分散式系統中快速構建例如配置管理,服務發現,熔斷,路由等通用模式。這是基於 Netflix 的 OSS 庫,它們是用 Java 寫的,面向Java開發者。
優勢
由 Spring 平臺自身來提供統一的程式設計模型,加上 Spring Boot 的快速建立應用的能力,可以給開發者大量的微服務開發經驗。例如,只要極少量的標籤,你就可以建立一個配置伺服器,再加一些標籤,你就可以得到一個客戶端庫來配置你的服務。
有大量的覆蓋了大多數執行時概念的庫可供選擇。因為所有的庫都是用Java寫的,它能提供更多的特性,更強的控制,以及更好的一致性選項。
不同的 Spring Cloud 庫都可以很好的整合在一起。例如,Feign 客戶端也可以使用 Hystrix 作為熔斷器,以及 Ribbon 作為請求負載均衡器。每一個都是標籤驅動的,這樣對 Java 開發者來說就很容易開發。
缺點
Spring Cloud 其中一個最主要的優點也是它的缺點,即它只針對 Java。MSA 的強烈的目標是具備互換技術棧,庫,必要的時候甚至是語言的能力。而這對Spring Cloud來說不可能。如果你想要消費 Spring Cloud/Netflix OSS 基礎服務,比如配置管理,服務發現,或者負載均衡,解決方案不是很優雅。Netflix Prana[5] 專案實現了 sidecar 模式,讓 Java 客戶端庫基於 HTTP 協議,使得那些非 JVM 語言寫的應用也可以存在於 NetflixOSS 系統中,但是這種方式不是很優雅。
Java 開發者需要關注非常多的事情,Java 應用需要處理非常多的事情。每個微服務都需要執行各種客戶端來獲得配置恢復、服務發現、負載均衡等功能。這些客戶端很容易建立,但是它們沒有隱藏環境的構建時和執行時依賴。例如,開發者可以用 @EnableConfigServer 標籤建立一個配置伺服器,但是這也是唯一路徑。每次開發者想要執行一個單一的微服務,他們需要使配置伺服器正常執行。對一個受控環境,開發者不得不考慮讓配置伺服器高可用,且因為它可以由 Git 或者 Svn 來支援,他們還需要一個共享的檔案系統。同樣的,對服務發現來說,開發者首先需要啟動一個Eureka伺服器。對一個受控環境,他們需要在每個 AZ 上都用多個例項來實現叢集。這有點類似於,除了實現所有的功能性服務外,Java開發者還需要構建和管理一個非試用型的微服務平臺。
單獨使用 Spring Cloud 在微服務旅程上無法走得很長遠,在一個完整的微服務經歷中,開發者還需要考慮自動化部署,排程,資源管理,程序隔離,自愈,構建流水線等功能。在這點上,我覺得單獨拿 Spring Cloud 和 Kubernetes 來比較不太公平,更公正的比較應該是 Spring Cloud + Cloud Foundry(或者 Docker Swarm)和 Kubernetes 來比較。但是那也說明,對一個完整的端到端的微服務經歷,Spring Cloud 還需要補充一個應用平臺,就像 Kubernetes 那樣。
Kubernetes
Kubernetes 是一個針對容器應用的自動化部署,伸縮和管理的開源系統。它相容多種語言且提供了建立,執行,伸縮以及管理分散式系統的原語。優勢
Kubernetes 是語言不感知的容器管理平臺,能相容執行原生雲應用和傳統的容器化應用。它提供的服務,比如配置管理,服務發現,負載均衡,度量收集,以及日誌聚合,能被各種語言使用。這使得組織可以只提供一個平臺供多個專案組使用(包括使用 Spring 的 Java 開發者),並且提供多種目的:應用開發,測試環境,構建環境(執行資源控制系統,構建伺服器,人工倉庫)等。
和 Spring Cloud 相比,Kubernetes 實現了更廣闊的 MSA 概念集合。除了提供執行時服務,Kubernetes 也允許我們提供環境變數,設定資源限制,RBAC,管理應用生命週期,使能自動伸縮和自愈(表現為就像一個反脆弱[6]平臺)。
Kubernetes 的技術是基於 Google 15年的管理容器的研究和開發經驗。除此以外,還有將近 1000 個 committer,它幾乎是 GitHub 上開源社群最活躍的專案。
缺點
Kubernetes 是相容多種語言的,因此它的服務和原語是通用的,不像 Spring Cloud 對 JVM 那樣,沒有針對不同的平臺做優化。例如,配置是通過環境變數或者掛載檔案系統傳遞給應用的。它沒有 Spring Cloud 配置提供的那樣精妙的配置更新能力。
Kubernetes 不是一個針對開發者的平臺。它的目的是供有 DevOps 思想的IT人員使用。因此,Java 開發者需要學習一些新的概念,並更開放得學習新的解決問題的方式。不管使用 MiniKube 來部署一個 Kubernetes 開發例項是多麼得容易,手工安裝一個高可用的 Kubernetes 叢集是有明顯的操作成本的。
Kubernetes 仍是一個相對較新的平臺(2年),它也還在活躍得開發和生長中。因此每個版本都會有許多新的特性,使得我們很難去一直跟蹤。好訊息是這個問題已經被正視,API 做成了可擴充套件且是後向相容的。
正如你所看到的,兩個平臺都有各自的強項,也有需要提高的地方。Spring Cloud 是一個容易上手的,開發者友好的平臺。而 Kubernetes 是 DevOps 友好的,有著陡峭的學習曲線,但是包含了更廣泛的微服務概念。這裡是針對這幾點的總結。
Strengths and weaknesses兩個框架實現了不同範圍的 MSA 概念,使用的是從根源上就有區別的方式。Spring Cloud 方式是盡力在 JVM 範疇內來解決每個 MSA 的挑戰,而 Kubernetes 的方式是盡力為開發者在平臺層面消除這些問題。Spring Cloud 在 JVM 內非常強大,Kubernetes 在管理這些 JVM 上非常強大。因此,整合這兩者取它們的最佳部分,是一個很自然的進步過程。
Spring Cloud backed by Kubernetes有了這樣一個整合,Spring 提供應用的打包,Docker 和 Kubernetes 提供部署和排程。Spring 通過 Hystrix 執行緒池提供應用內的隔離,而 Kubernetes 通過資源,程序和名稱空間來提供隔離。Spring 為每個微服務提供健康終端,而 Kubernetes 執行健康檢查,且把流量導到健康服務。Spring 外部化配置並更新它們,而 Kubernetes 分發配置到每個微服務。這個列表將一直持續。
My favorite microservices stack我最喜歡的微服務平臺是哪個?我兩個都喜歡。我喜歡 Spring 框架提供的開發者經驗。它是標籤驅動的,並且擁有包含了各種功能需求的庫。跟任何整合相關的,我喜歡 Apache Camel(而不是 Spring Integration),它能提供應用級別的聯結器,訊息,路由,可靠性和容錯功能。而對跟叢集和管理多應用例項相關的,我更喜歡魔法般的 Kubernetes 能力。不論何時,有重複功能,比如服務發現,負載均衡,配置管理,我儘量使用 Kubernetes 提供的跟語言無關的原語。
相關連結:
https://dzone.com/articles/microservice-architecture-with-spring-cloud-and-do
https://news.ycombinator.com/item?id=12509533
https://github.com/fabric8io/kubeflix
https://github.com/fabric8io/spring-cloud-kubernetes
https://github.com/Netflix/Prana
http://www.ofbizian.com/2016/07/from-fragile-to-antifragile-software.html
原文連結:https://dzone.com/articles/deploying-microservices-spring-cloud-vs-kubernetes
基於Kubernetes的容器雲平臺實踐培訓本次培訓包含:Kubernetes核心概念;Kubernetes叢集的安裝配置、運維管理、架構規劃;Kubernetes元件、監控、網路;針對於Kubernetes API介面的二次開發;DevOps基本理念;Docker的企業級應用與運維等,點選識別下方二維碼加微信好友瞭解具體培訓內容。
點選閱讀原文連結即可報名。