導讀:對于如何治理錯綜復雜的組件關(guān)系網(wǎng),經(jīng)過幾十年的積累,開發(fā)者們已經(jīng)提煉出了一套通用的解決方案:依賴管理(Dependency Management)。
前言
分布式云應用(也叫微服務)在大行其道的同時,也給應用本身的設計和運維帶來巨大的復雜性。以前單體服務時代,尚可將這種復雜性隱藏于自身內(nèi)部,而到了微服務時代,這種復雜性幾乎擴散到了成百上千個“松耦合”的服務上面。盡管每個微服務都可以使用不同的語言構(gòu)建,也可以快速地橫向擴展,但他們作為一個整體,相比于單體服務,分布式的特性常常會帶來規(guī)劃、部署和安全上的難題。
這些問題也給云原生應用的管理和發(fā)展帶來挑戰(zhàn)。我們不禁要思考,怎樣才能確保云原生應用的持續(xù)健康,如何才能取其精華,去其糟粕,既保持面向服務設計的優(yōu)勢,同時不增加開發(fā)維護等成本?
還好在微服務之前就遇到過類似的問題,對于如何治理錯綜復雜的組件關(guān)系網(wǎng),經(jīng)過幾十年的積累,開發(fā)者們已經(jīng)提煉出了一套通用的解決方案:依賴管理(Dependency Management)。
其實我們每天都在使用依賴管理器提供的公共或者私有的軟件包,在這些包的基礎(chǔ)之上增加自己的功能,最后再精心地打包為標準格式以供后續(xù)使用。筆者認為依賴管理正是釋放分布式應用強大能力的關(guān)鍵,現(xiàn)在是時候引入依賴管理機制來推動云原生技術(shù)的發(fā)展了,具體來說,有以下5點原因。
1.開發(fā)者之間的相互協(xié)作
NPM, Pip, Maven等依賴管理器最重要的作用之一,就是促進了開發(fā)者之間的相互協(xié)作。通過提供一套統(tǒng)一的打包管理機制,依賴管理器可以讓你的代碼被其他團隊使用或者增強。此外,不僅在企業(yè)內(nèi)部團隊之間,我們也看到了依賴管理大范圍地用于促進開源社區(qū)上的協(xié)作。工具的一致性和使用的廣泛性也使我們能夠創(chuàng)建強大易得的軟件庫,從而供所有人使用并在其上進行構(gòu)建。
這種級別的協(xié)作已經(jīng)在各個語言社區(qū)中實現(xiàn),比如JavaScript的NPM,Python的Pip等,但在云原生社區(qū)里還沒有成型的落地方案。雖然有Docker定義了云服務打包的規(guī)范,但各種容器方案還缺乏足夠的信息去解析和拓展服務間的依賴關(guān)系。如果我們希望微服務也能實現(xiàn)這種協(xié)作效果,就像各個語言對軟件庫做的那樣,就非常有必要增加合適的依賴管理機制,使其能檢索并處理各個終端服務之間的關(guān)系。
2.環(huán)境的自服務
依賴管理器的協(xié)作效果并不能憑空產(chǎn)生,而是得益于統(tǒng)一的依賴解析。統(tǒng)一的依賴解析之所以強大,主要是因為世界各地的開發(fā)者都能夠使用相同的命令和程序來重現(xiàn)他們的效果??芍貜托?Reproducibility)是依賴管理器的一個關(guān)鍵要素,缺少了這個要素,如果沒有定制復雜的啟動邏輯,開發(fā)者們就不能方便地下載和操作其他人創(chuàng)建的庫和包,而這些將增加開發(fā)成本,成為大規(guī)模采用和分發(fā)的巨大障礙。
在這方面,微服務與各種語言庫之間沒有太大的差別。我們擴展他人工作的成果,取決于我們可以運行或調(diào)用期望的服務和應用程序的能力。目前,我們已經(jīng)可以通過沙盒環(huán)境,集中QA的形式來完成任務,但還無法真正做到環(huán)境的完全重現(xiàn),從而會產(chǎn)生一系列的問題。由于依賴他人的服務無法輕松交付,開發(fā)者并沒有完全操控自己的開發(fā)環(huán)境的能力,需要被迫編寫自己的腳本來本地或者遠程地運行他人的應用程序,同時每個團隊都需要開發(fā)生產(chǎn)級別的工具,自行保證網(wǎng)絡問題和安全問題。
如果擁有統(tǒng)一的依賴關(guān)系管理解決方案,每個團隊只需要聲明其服務的網(wǎng)絡依賴關(guān)系,即可為組織中的每個人提供相同的方式來運行其技術(shù)棧中的服務,并同時準備好服務的依賴,可以使每個開發(fā)者真正地擁有操控環(huán)境的能力。
3.自動化
自助服務優(yōu)勢不僅僅意味著開發(fā)者可以操控自己的環(huán)境,也意味著開發(fā)環(huán)境可以通過程序自動化來提供并且細化。只需使用一個命令或程序,就能實現(xiàn)依賴關(guān)系的解析、網(wǎng)絡的豐富、安全性的自動保證,這是能否集成到CI/CD管道的關(guān)鍵。
如果每個服務都可以使用統(tǒng)一的機制運行(例如,使用容器平臺)并且知道自己的依賴關(guān)系,那么每次Git合并請求就能提供一套新的環(huán)境,并且無縫地發(fā)布到預生產(chǎn)和生產(chǎn)環(huán)境。這意味著每個團隊都可以為每個成員和每個添加到應用里的新服務提供非常靈活的基于Git的自動運維部署,即GitOps。
4.安全性
微服務架構(gòu)其中的一個安全風險,是每個服務都需要暴露API接口以提供功能的調(diào)用。由于這些服務作為單獨的進程存在,因此通過網(wǎng)絡進行通信幾乎是服務間相互連接、接收處理請求的唯一方式。這意味著每個新服務都會公開一些其他人可以訪問的接口,如果開發(fā)者不小心,可能會錯誤地暴露接口給到本不允許訪問的服務。
防止網(wǎng)絡接口的意外暴露是依賴管理可以大展身手的另一個領(lǐng)域。通過帶有網(wǎng)絡依賴的結(jié)構(gòu)化索引,我們不僅可以自動解析服務間的依賴,還可以豐富環(huán)境配置,生成對應的網(wǎng)絡策略來保障接口的合法訪問,也就是說只有相互依賴的服務才能相互訪問。這種結(jié)構(gòu)化的方式將極大減少開發(fā)者了解網(wǎng)絡安全工具的需求,并讓他們可以更自由地創(chuàng)建新服務。
5.靈活性
微服務或者說分布式應用的依賴管理的另一個好處是靈活性。一旦開發(fā)者確定好依賴項并關(guān)聯(lián)到自己的服務上,解析器自己就可以在每個部署的環(huán)境中唯一地構(gòu)建好關(guān)系網(wǎng)絡。想嘗試不同的API網(wǎng)關(guān)(API Gateway)或服務網(wǎng)格(Service Mesh)?想通過每個服務的入口和出口流量來進行鏈接追蹤?通過依賴解析器的自動化分析,開發(fā)者可以自由地試驗新工具和配置,而無需分散精力對現(xiàn)有的任何代碼進行更改。
那為什么分布式應用的依賴管理還沒出現(xiàn)?
依賴解析將是一個非常強大的解決方案,使得開發(fā)者能夠相互協(xié)作并對云原生應用做出貢獻,那么我們能使用現(xiàn)有的包管理器來幫助實現(xiàn)嗎?盡管使用現(xiàn)有的工具也許可行,但解決網(wǎng)絡應用的依賴關(guān)系和解決二進制庫文件之間還是有著明顯的差異。
依賴的二進制庫文件是在主庫文件編譯構(gòu)建時才下載的,但是微服務不會捆綁到單個二進制文件中,它們需要作為獨立服務運行,然后通過網(wǎng)絡連接交互形成一個完整的應用。這意味著解析有著額外的步驟,并且發(fā)生在與二進制庫完全不同的生命周期階段。事實證明,可以正確解析分布式應用依賴關(guān)系的最早時間是在部署階段。正是在部署時,我們既知道技術(shù)棧中所有服務間的關(guān)系,也了解正確配置和連接服務所需的工具與目標環(huán)境細節(jié)。
結(jié)語
總而言之,目前還很難創(chuàng)建一個大規(guī)模的解析器用于解決網(wǎng)絡依賴,但這樣做會給工程團隊和整個云社區(qū)帶來巨大的好處。如果我們要正確引導云原生工具的發(fā)展方向,我們就需要從過去的依賴管理實踐中總結(jié)學習。
原文標題:Why Distributed Apps Need Dependency Management,作者:David Thor