十分鐘理解微服務(wù)、容器和 Kubernetes
什么是微服務(wù)?
從根本上講,微服務(wù)只是一個運行在服務(wù)器或虛擬計算實例上并響應(yīng)網(wǎng)絡(luò)請求的計算機(jī)程序。
這與典型的 Rails/Django/Node.js 應(yīng)用程序有何不同?它根本上沒有什么不同。事實上,您可能會發(fā)現(xiàn)您的組織中已經(jīng)部署了十幾個微服務(wù)。沒有任何新的神奇技術(shù)使您的應(yīng)用程序有資格稱為微服務(wù)。微服務(wù)不是由它的構(gòu)建方式來定義的,而是由它如何變成更通用的系統(tǒng)或解決方案來定義的。
那么是如何使服務(wù)成為微服務(wù)呢?一般來說,微服務(wù)的范圍更窄,專注于做好較小的任務(wù)。讓我們通過看一個例子來進(jìn)一步探索。
微服務(wù)示例:亞馬遜產(chǎn)品列表
讓我們檢查在 Amazon 上為您提供此產(chǎn)品頁面的系統(tǒng)。它包含幾個信息塊,可能是從不同的數(shù)據(jù)庫中檢索到的:
- 產(chǎn)品描述,包括價格、標(biāo)題、照片等。
- 推薦項目,即其他人購買的類似書籍。
- 與此項目相關(guān)的贊助商列表。
- 關(guān)于本書作者的信息。
- 顧客評論。
- 您自己在亞馬遜商店中瀏覽其他商品的歷史記錄。
如果您要快速編寫用于此列表的代碼,那么簡單的方法將如下所示:
當(dāng)用戶的請求來自瀏覽器時,它將由 Web 應(yīng)用程序(Linux 或 Windows 進(jìn)程)提供服務(wù)。通常,被調(diào)用的應(yīng)用程序代碼片段稱為請求處理程序。處理程序內(nèi)部的邏輯將依次多次調(diào)用數(shù)據(jù)庫,獲取呈現(xiàn)頁面所需的信息并將其拼接在一起,然后呈現(xiàn)返回給用戶的網(wǎng)頁。很簡單吧?事實上,許多 Ruby on Rails 書籍都有類似這樣的教程和示例。那么,你可能會問,為什么要把事情復(fù)雜化?
想象一下隨著應(yīng)用程序的增長和越來越多的工程師參與其中會發(fā)生什么。上面例子中的推薦引擎是由一小群程序員和數(shù)據(jù)科學(xué)家維護(hù)的。有幾十個不同的團(tuán)隊負(fù)責(zé)渲染該頁面的某些組件。這些團(tuán)隊中的每一個通常都希望獲得以下自由:
- 更改他們的數(shù)據(jù)庫架構(gòu)。
- 快速且頻繁地將他們的代碼發(fā)布到生產(chǎn)環(huán)境中。
- 使用他們選擇的編程語言或數(shù)據(jù)存儲等開發(fā)工具。
- 在計算資源和開發(fā)人員生產(chǎn)力之間做出自己的權(quán)衡。
- 偏好維護(hù)/監(jiān)控其功能。
可以想象,隨著時間的推移,讓團(tuán)隊就發(fā)布 Web 商店應(yīng)用程序的新版本的所有內(nèi)容達(dá)成一致將變得更加困難。
解決方案是將組件拆分為更小的、獨立的服務(wù)(也就是微服務(wù))。
升級流程變得更小、更笨。它基本上是一個代理,它簡單地將傳入的頁面請求分解為幾個專門的請求,并將它們轉(zhuǎn)發(fā)給相應(yīng)的微服務(wù),這些微服務(wù)現(xiàn)在是他們自己的進(jìn)程并在其他地方運行?!皯?yīng)用微服務(wù)”基本上是專門服務(wù)返回的數(shù)據(jù)的聚合器。您甚至可以完全擺脫它并將該工作卸載到用戶的設(shè)備上,讓此代碼在瀏覽器中作為單頁 JavaScript 應(yīng)用程序運行。
其他微服務(wù)現(xiàn)在被分離出來,每個開發(fā)微服務(wù)的開發(fā)團(tuán)隊都可以:
- 隨心所欲地部署他們的服務(wù),而不會干擾其他團(tuán)隊。
- 以他們認(rèn)為合適的方式擴(kuò)展他們的服務(wù)。例如,使用他們選擇的 AWS 實例類型,或者可能在專用硬件上運行。
- 擁有自己特定于其服務(wù)的監(jiān)控、備份和災(zāi)難恢復(fù)。
什么是容器?
從技術(shù)上講,容器只是一個從可執(zhí)行文件產(chǎn)生的進(jìn)程,運行在 Linux 機(jī)器上,它有一些限制,例如:
- 容器不允許“看到”所有文件系統(tǒng),它只能訪問其中的指定部分。
- 一個容器不允許使用所有的 CPU 或 RAM。
- 容器在如何使用網(wǎng)絡(luò)方面受到限制。
從歷史上看,現(xiàn)代操作系統(tǒng)總是對進(jìn)程施加限制,例如每個 Linux 進(jìn)程都以系統(tǒng)用戶的權(quán)限運行,但是容器化技術(shù)引入了更多可能的限制并使其更加靈活。
基本上,任何 Linux 可執(zhí)行文件都可以受到限制,即可以“容器化”。
大多數(shù)情況下,當(dāng)人們說“容器”時,他們不僅僅指的是 Linux 進(jìn)程,還指的是可執(zhí)行文件的打包和存儲方式。
類似的工具Docker允許開發(fā)人員獲取他們的可執(zhí)行文件及其依賴項,以及他們想要的任何其他文件,并將它們?nèi)看虬梢粋€文件。這項技術(shù)與 tarball 之類的存檔沒有太大區(qū)別。Docker 還允許包含一些額外的指令和配置來運行這個打包的可執(zhí)行文件。通常這些文件,通常稱為“容器鏡像”,也稱為容器。
但為了簡單起見,請記?。?
- 一個容器就是一個運行受限制的linux進(jìn)程
- 容器鏡像是可執(zhí)行進(jìn)程的依賴和配置打包
容器鏡像是自給自足的。它們將在任何 Linux 機(jī)器上運行,因此容器化使得將代碼從開發(fā)人員的機(jī)器復(fù)制(部署)到任何環(huán)境變得更加容易。
微服務(wù)和容器有什么區(qū)別?
我們剛剛了解到,容器只是一種打包、部署和運行 Linux 程序/進(jìn)程的方法。您可以將一個巨大的單體應(yīng)用程序作為容器,也可以擁有一群完全不使用容器的微服務(wù)。
容器是一種有用的資源分配和共享技術(shù)。這是 DevOps 人們感到興奮的事情。微服務(wù)是一種軟件設(shè)計架構(gòu)。這是開發(fā)人員感到興奮的事情。
它們是相關(guān)的,但不需要彼此。您可以將單體應(yīng)用部署為容器,也可以擁有不受限制的、非容器化的微服務(wù)。
什么時候使用微服務(wù)?
微服務(wù)背后的想法并不新鮮。幾十年來,軟件架構(gòu)師一直致力于將單體應(yīng)用程序分解為可重用的組件。
微服務(wù)的好處
微服務(wù)的好處很多,包括:
- 更簡單的自動化測試;
- 快速靈活的部署模式;
- 更強(qiáng)彈性擴(kuò)縮容。
采用微服務(wù)的另一個好處是能夠為工作選擇最佳工具。應(yīng)用程序的某些部分可以從 C++ 的速度中受益,而其他部分可以從更高級別語言(例如 Python 或 JavaScript)的生產(chǎn)力提高中受益。
微服務(wù)的缺點
微服務(wù)的缺點包括:
- 需要更仔細(xì)的規(guī)劃;
- 更高的研發(fā)投入;
- 過度設(shè)計的誘惑。
如果應(yīng)用程序和開發(fā)團(tuán)隊足夠小并且工作量不具有挑戰(zhàn)性,則通常無需投入額外的工程資源來解決您尚未解決的問題并使用微服務(wù)。但是,如果您開始看到微服務(wù)的利大于弊,這里有一些具體的設(shè)計注意事項:
- 計算和存儲分離。隨著您對 CPU 能力和存儲需求的增長,這些資源具有非常不同的擴(kuò)展成本和特性。從一開始就不必依賴本地存儲,這將使您能夠相對輕松地適應(yīng)未來的工作負(fù)載。這既適用于文件系統(tǒng)等簡單的存儲形式,也適用于數(shù)據(jù)庫等更復(fù)雜的解決方案。
- 異步處理。通過添加越來越多的相互調(diào)用的子進(jìn)程或?qū)ο髞碇鸩綐?gòu)建應(yīng)用程序的傳統(tǒng)方法隨著工作負(fù)載的增長而停止工作,并且應(yīng)用程序本身必須跨多臺機(jī)器甚至數(shù)據(jù)中心擴(kuò)展。將需要圍繞事件驅(qū)動模型重新構(gòu)建應(yīng)用程序。這意味著發(fā)送事件(而不是等待結(jié)果)而不是調(diào)用函數(shù)并同步等待結(jié)果。
- 擁抱消息總線。這是必須實現(xiàn)異步處理模型的直接后果。隨著您的單體應(yīng)用程序被分解為事件處理程序和事件發(fā)射器,就需要一個健壯、高性能和靈活的消息總線。有多種選擇,選擇取決于應(yīng)用程序規(guī)模和復(fù)雜性。對于一個簡單的用例,像 Redis 這樣的東西就可以做到。如果您需要您的應(yīng)用程序真正是云原生的并自行擴(kuò)展和縮減,您可能需要能夠處理來自多個事件源的事件:從 Kafka 等流管道到基礎(chǔ)設(shè)施,甚至監(jiān)控事件。
- API 版本控制。由于您的微服務(wù)將使用彼此的 API 通過總線相互通信,因此設(shè)計用于保持向后兼容性的架構(gòu)將是至關(guān)重要的。只需部署一個微服務(wù)的最新版本,開發(fā)人員就不應(yīng)該要求其他人升級他們的代碼。這將是向整體方法向后兼容的一步,開發(fā)團(tuán)隊必須在永遠(yuǎn)支持舊 API 和保持更高的開發(fā)速度之間達(dá)成合理的妥協(xié)。這也意味著 API 設(shè)計成為一項重要的技能。頻繁的破壞性 API 更改是團(tuán)隊無法高效開發(fā)復(fù)雜微服務(wù)的原因之一。
- 重新考慮您的安全性。許多開發(fā)人員沒有意識到這一點,但遷移到微服務(wù)為更好的安全模型創(chuàng)造了機(jī)會。由于每個微服務(wù)都是一個專門的進(jìn)程,因此最好只允許它訪問所需的資源。這樣,僅一個微服務(wù)中的漏洞就不會將系統(tǒng)的其余部分暴露給攻擊者。這與大型單體形成對比,后者傾向于以更高的特權(quán)(每個人都需要的超集)運行,并且可能導(dǎo)致更多的違規(guī)行為。
Kubernetes 與微服務(wù)有什么關(guān)系?
Kubernetes太復(fù)雜了,無法在此詳細(xì)描述,但值得對其進(jìn)行概述,因為很多人在有關(guān)微服務(wù)的對話中都會提到它。
嚴(yán)格來說,Kubernetes(又名 K8s)的主要好處是通過跨多個進(jìn)程高效共享計算資源來提高基礎(chǔ)設(shè)施利用率。Kubernetes 是動態(tài)分配計算資源以滿足需求的大師。這允許組織避免為他們不使用的計算資源付費。但是,K8s 的一些附帶好處使向微服務(wù)的過渡變得更加容易。
當(dāng)您將單體應(yīng)用程序分解為單獨的、松散耦合的微服務(wù)時,您的團(tuán)隊將獲得更多的自主權(quán)和自由度。但是,在與微服務(wù)必須運行的基礎(chǔ)設(shè)施進(jìn)行交互時,它們?nèi)匀槐仨毭芮泻献鳌?/p>
您必須解決以下問題:
- 預(yù)測每個服務(wù)需要多少計算資源;
- 這些要求在負(fù)載下如何變化;
- 如何劃分基礎(chǔ)設(shè)施分區(qū)并將它們劃分到微服務(wù)之間;
- 實施資源限制。
Kubernetes 非常優(yōu)雅地解決了這些問題,并提供了一個通用框架來描述、檢查和推理基礎(chǔ)設(shè)施資源的共享和利用。這就是為什么采用 Kubernetes 作為微服務(wù)重新架構(gòu)的一部分是一個好主意。
然而,Kubernetes 是一項需要學(xué)習(xí)的復(fù)雜技術(shù),而且更難管理。如果可以,您應(yīng)該利用云提供商提供的托管 Kubernetes 服務(wù)。但是,對于需要跨多個云提供商和企業(yè)數(shù)據(jù)中心運行自己的 Kubernetes 集群的公司來說,這并不總是可行的。
結(jié)論
總結(jié)一下:
- 容器只是具有應(yīng)用受限制的 Linux 進(jìn)程。限制的示例包括允許進(jìn)程使用多少 CPU 或內(nèi)存。Docker 之類的工具允許開發(fā)人員將他們的可執(zhí)行文件與依賴項和附加配置打包在一起。這些包被稱為 鏡像,并且經(jīng)常且容易混淆地也被稱為容器。
- 微服務(wù)并不新鮮。這是一種舊的軟件設(shè)計模式,由于互聯(lián)網(wǎng)公司的規(guī)模不斷擴(kuò)大,它越來越受歡迎。微服務(wù)不一定要容器化。同樣,單體應(yīng)用程序可以是微服務(wù)。
- 小項目不應(yīng)該回避整體設(shè)計。它為較小的團(tuán)隊提供更高的生產(chǎn)力。
- Kubernetes 是由多個微服務(wù)組成的復(fù)雜應(yīng)用程序的絕佳平臺。
- Kubernetes 也是一個復(fù)雜的系統(tǒng),學(xué)習(xí)曲線陡峭,管理成本非常高。