雲原生領域的一些技術展望

雲原生的由來

雲原生(Cloud Native)的概念最早出現於2010年,Paul Fremantle的一篇部落格中提出「雲原生」應用應該具有的一些特性。其中包括:分散式、動態插拔、彈性、多租戶、自服務、精確計量及計費、增量部署和測試。後來,Pivotal的Matt Stine於2013年在其推特上推廣雲原生的概念。但彼時雖然雲原生的意義很豐富,其概念並不清晰,直到CNCF(雲原生計算基金會)對其進行了重新定義。

閱讀CNCF對雲原生的定義,我們大致可以這樣理解雲原生:以容器、服務網格、微服務、不可變基礎設施和聲明式API為代表的,有助於各組織在公有雲、私有雲等動態環境中構建可彈性擴展應用的技術體系。其中不可變基礎設施我這裡解釋一下,即對於應用依賴的基礎設施或者環境,如果不符合要求,那麼我們不是去修改它,而是整體部署或者啟動一整個新的。那麼具體的有代表性的雲原生技術有哪些呢?這裡例舉一下常見的。基礎容器編排及環境的kubernets、minikube、kind等,分散式強一致性資料庫etcd,消息隊列nats、pulsar、kafka等,監控告警prometheus、datadog等,服務網格istio、linkerd等,無服務架構knative、openfaas等這些都是。cncf致力於雲原生技術的普及和可持續發展,該社區維護了大量相關項目,如果對這些技術體系感興趣可以看一下cncf的項目全景圖

本篇文章主要想跟大家聊聊雲原生環境下架構相關的一些技術體系,接下來我們來看一些跟架構關係較大的paas平台項目、微服務框架、中間件相關的項目或者趨勢。

paas平台

kubernets向上對應用程式暴露基礎設施能力的數據抽象並提供編排能力,向下提供基礎設施能力接入的標準介面,管理著物理機、虛擬機、網路頻寬、存儲資源等;可以看做是雲原生時代的作業系統內核。為什麼說是內核而不是作業系統呢,因為從使用的角度來看paas平台更像是一個作業系統的角色,而k8s則是各家發行版作業系統共同依賴的內核。據cncf2021年四月底進行的2020中國雲原生調查,在生產環境中使用kubernets的比例已經達到驚人的82%。這說明kubernets已經成為容器編排領域的事實標準。如果對技術發展趨勢有興趣,這個調查報告非常值得一看。

各家企業應用也都有基於kubernets構建的paas平台去滿足企業內部的容器編排、多雲管理等需求。其中可能大家比較熟悉的開源項目有rancher、kubeSphere、openshift等。他們都是基於kubernets去實現,繼承且擴展了kubernets的能力。我們來看一下rancherkubesphere他們的系統架構:


雖然二者圖示的側重點不同,rancher更多的在描述整體宏觀的架構,而kubesphere則更側重於表達涵蓋了哪些能力。過我們仍然可以看出他們的模式是類似的:構建一個中心的管理service,下面鏈接多個k8s集群,在此基礎上再逐步的擴展出豐富的特性,比如cicd、彈性伸縮、監控告警等。目前大多數的企業也都是這麼做的,這麼做對於企業內的業務研發同學來說,屏蔽掉了內部kubernets、cicd、持久化等系統的複雜度,加速了研發過程,促進了企業業務迭代速度。

對於企業來說,這麼做可以滿足需求,當然是沒什麼問題的。但是如果我們把視角提升到整個技術領域、技術社區,則可以發現一些能夠做的更好的地方。首先是擴展性,基於以上的模式開構建paas平台,每當我們想要新引入一個功能特性,都需要一些開發工作,如果要集成到現有的平台中,或者許可權系統等,可能工作量並不小。這樣就不利於引入或者快速試錯社區的工具或者平台等,也就限制了paas平台功能的豐富程度。另外是不同平台入口的統一性,舉個例子,假如自家企業的軟體基礎設施建設的比較全面,既有paas平台又有servless平台,還有一個任務平台。那麼業務研發的同學要上線不同種類的應用時,是不是要到不同的平台中去發布或者管理呢,當然有可能負責平台項目的同學把他們集成到同一個項目中了,但大概率還是在不同的模組中。這樣還是會讓整體的技術體系變得比較複雜。

其實如果都是基於kubernets實現的,那麼這些不同的服務、任務、functions到了實際運行的時候很可能都是kubernets中的一個pod,對於kubernets來說都是工作負載,只不過其類型不同。這樣的話,我們可不可以再做一層上層抽象,給這些不同的工作負載提供一個統一的入口呢?kubevela項目正是這樣做的。kubevela通過定義統一的組件(component)和特徵(trait)來抽象。組件可以根據類型的不同,具體渲染成不同的kubernets工作負載資源,比如說deployment、job、pod等。而特徵也是按照類別區分,特徵可以渲染成類似ingress、hpa、sidcar等工作負載的附加屬性。那麼從用戶定義的組件,到底層渲染的deployment(假定它是deployment類型)這一步是如何實現的呢?這一步是由平台維護人員定義一個WorkloadDefinition來描述特定類型的組件渲染為何種資源類型,及如何去渲染。由於kubernets都是聲明式api的設計,而聲明可以被文本描述,所以這種渲染其實都是文本間的轉化,WorkloadDefinition定義的其實也是一個文本的轉化規則。有了文本、餘下的生成具體資源類型的實現工作kubevela就可以比較容易的完成了。

這樣的話,它就會有另一個優點:會很容易的擴展社區新的工具或者平台。比如說在vela項目中引入argo的功能應該怎麼做呢?首先在集群中安裝argo,其次由平台維護者定義出argo-workflow的WorkloadDefinition,然後用戶就可以愉快的使用了。在使用組件的時候就聲明負載類型為argo-workflow的的類型即可。當然了,全部功能資源類型的統一化管理並不好做,可能一些特殊功能的管理還是需要做兼容性處理,甚至是單獨的管理模組。最後我們來看一下kubevela的架構,如下圖:

可以看到中上層是它的組件和特徵處理層,中間是一些kubevela的controller,負責把用戶定義的組件和特徵渲染為具體的資源類型等功能。下層左側是邊緣計算和物聯網支援、中間是多個雲環境的支援、右側則是可以集成其他工具或者平台的功能到kubevela中。

kubevela有一些下一代paas平台的感覺,其開發人員也是這麼說的。但是它的優勢是否足以取代現有的paas平台構建模式還是個未知數。

service mesh 與 mesh

在久遠的以前,電腦與電腦之間通訊是需要程式開發者自己實現通訊協議的。也即是說現在的網路協議棧中的一部分以前是在程式開發者的程式碼中實現並維護的,後來隨著電腦的增多,慢慢出現了統一的標準協議,對應的實現也下沉到作業系統層面了。再後來隨著軟體規模的膨脹、軟體架構的演進,出現了soa(面向服務的架構)、微服務、service messh(服務網格)這樣的架構設計。由單體應用程式逐步到service mesh的設計,也類似於網路協議的下沉,把服務發現、流量控制、依賴控制等下沉到一個跟程式自身分離的較小的服務(sidecar)中。對這個演進過程感興趣的同學可以瀏覽下這篇service mesh設計模式

istio是開源service mesh框架中被採用率最高的項目之一,據cncf的調查,目前已有至少38%的單位在生產環境中使用service mesh,42%的單位在評估中。可見service mesh的設計模式已經得到了市場的驗證。我們來看一下istio的架構,如下圖:

istio

圖中,control plane為一個控制面板,中心化的服務;envoy proxy則為服務發現、流量控制等邏輯所在之處,每個服務都會存在一個與之對應、為之服務的envoy實例。其中控制面板服務為istiod,其中包含galley、pilot、citadel等模組,分別管理配置及其驗證、配置下發、安全策略等功能。關於istio還有一個值得玩味的小故事,istio的控制面板曾經是一個有多個組件的分散式應用,現在istiod中的模組多為不同的獨立部署的組件。那麼為什麼合併為單體應用了呢?「複雜是萬惡之源,停止焦慮,學會愛上單體」istio開發團隊是這麼說的。直白的說,這是他們做的一個取捨:為了易用性、性能放棄了更為解耦、健壯的架構。由此可見、做架構抉擇時不可盲目的選擇看起來「高大上」的,適合的才是最好的,當魚與熊掌不可兼得的時候,找出我們更看重的方面,做出取捨。

與service mesh十分相似還有一個database mesh 的概念。顧名思義,database mesh即是把存儲能力也網格化。業界已有相關的案例實踐(規劃中),我們來看一下Sharding-JDBC的的mesh化設計,如下圖:

圖中的下方,是一個管理平台,類似於istio的控制面板;上方則是我們的服務節點,其中有service mesh的sidecar、database mesh的sidecar;中間則是資料庫集群和一個註冊中心。與service mesh不同的是,下方的server也會是一個流量入口,因為資料庫存在許多需要人工管理的場景,而人工管理是沒有sidecar可用的。

那麼,除了database的mesh化設計,還有其他的服務於程式的能力可以mesh化嗎?我們來看一下微軟的微服務框架dapr的設計,其說明圖示如下:

圖中,最上層指明支援很多種語言;最下層指明支援很多雲環境。中間層則說明了dapr可以提供哪些能力,其中包括服務間訪問、狀態管理、發布訂閱、資源綁定和觸發器等等。而dapr提供這些能力,也是以sidecar的方式提示共的(也提供了sdk方式)。如此一來,dapr的服務間訪問能力是不是和service mesh有些許相似了。而其於sidecar中提供狀態管理、發布訂閱消息隊列等能力,也可以看做是更多基礎能力下沉到sidecar中的一個類似於service mesh設計的架構演進。service mesh的定位是針對流量的治理,而dapr則是各種分散式應用所需能力的聚合;dapr的設計可以看做是service mesh的擴展和延伸。

我們可以結合螞蟻金服基於mosn的應用運行時框架和dapr一起來看看這個方向的軟體設計的架構演進。mosn在2018最初也是service mesh的形式,在2019年則逐步的加入了message mesh和database mesh,並在當年支援了618促銷活動。可以看到mosn從service mesh到multi mesh再到雲原生運行時(或者也可以叫做all mesh?)的一個演進過程。dapr其實也稱自己為一個運行時,它跟mosn的最終形態還是十分相似的。我們來看一下mosn的架構圖,可以將兩者對比一下:

我個人還有另外一個思路:以node節點守護進程的方式提供中間件的服務,再將其映射到容器內。這樣考慮到pod漂移,可能會需要會引入另外一些的同步數據的複雜度。但是有的場景還是很適合這樣的設計的。比如這樣一個使用database的場景,企業內部不同的業務線使用不同的機器節點資源池,一個業務線內的服務使用相同的一批帳號。此時如果以守護進程的方式提供database的服務,既有database mesh的優點,又避免了database mesh可能帶來的連接數過多的問題。此外,日誌收集服務天生適合這個場景,因為日誌收集在不同的服務間沒有差異性,不需要考慮pod漂移的問題。

綜上,雖然目前只有service mesh有一定的市場採用率,但是service mesh才僅僅是一個開始。mesh模式是雲原生領域的關鍵技術,消息隊列、database、cache、servless等的mesh化已是可見的趨勢。以sidecar或者守護進程來提供服務,應該是中間件技術提供服務的未來形態。

低程式碼

低程式碼是一種方便產生應用程式的平台型軟體及開發環境,這個軟體會開發環境讓用戶以圖形化介面以及配置編寫程式,而不是用傳統的程式設計方法。為什麼提到這個呢?如果低程式碼開發被推廣開來,之前一些需要專業開發人員開發的軟體可以由非軟體開發專業人士來完成,比如說圖書管理系統、報銷流程審批系統等等,這會讓更多的人成為應用開發者,甚至如阿里雲開發者所說:「人人都是開發者」。微軟已經在這個領域做了大量的布局,阿里更是已經在這個領域取得了一定的成果、有了一定的用戶量。阿里內部,使用宜搭搭建的月活應用達3000多個,每天活躍在這些應用的用戶已達10w的量級。釘釘上現在已經有宜搭的入口,打開之後可以看到已經有約80個應用模板。據2021年五月底舉辦的阿里雲開發者大會,有一名鄉村數學老師,花費了2000多的費用,開發了43款低程式碼應用,讓整個校園基本實現了數字化。

由此可見低程式碼也是一個軟體開發分化的方向,越來越多的非專業人員會成為開發者,越來越多的軟體實現過程逐漸的不需要專業的開發人員來完成。但目前來看,低程式碼開發可能更擅長於數據採集、數據統計、流程審批這些功能相對簡單的系統。所以,影響也不會特別的大。

雲上開發vs本地開發

在線開發環境(online-ide,也叫做雲開發環境)是指部署在遠端伺服器的開發環境,用戶在瀏覽器上就可以使用ide進行軟體開發。在線開發環境可以跟測試環境更好的契合,微服務場景下這個優點會更加突出些。但云端開發環境使用體驗上要比本地開發環境差不少,且大多模式單一不靈活(至少我的體驗如此),比如只能用一種ide、無法配合shell使用等。也許你還沒太注意到它的存在,不過很多公有雲已經提供了雲端開發環境,比如華為雲、騰訊雲、AWS、Azure等。開源的在線開發環境也有不少,其中也有高達8k、10k收藏數的項目。但是從我個人的日常工作、同事們和同學們之間的交流來看,在線開發環境的普及率還是相當低的。但是隨著faas(Functions as a Service)的發展,可能會給在線開發環境帶來一個契機。輕量級的functions,開發起來不需要太複雜的操作,直接在雲端迅速開發、發布,這樣的體驗就比較不錯。現有的openfaas項目也確實提供了一個簡單的在線編輯程式碼的環境。個人覺得faas即使發展良好,給在線開發環境的發展帶來的促進作用也有限。如此,在線開發環境何時會有大的發展機會呢?可能會很久遠,直到在線開發環境的體驗優於本地環境、用戶的成本又低於本地環境。

最後

軟體架構的發展過程,其實也是一個複雜度轉移的過程;由應用程式中轉移到作業系統中、框架中、基礎平台中。複雜度的轉移,讓基礎的軟體開發越來越方便、迅速、簡單;也讓承接複雜度的基礎軟體越來越成熟、統一、標準化。順著這個思路極端化一些來思考,也許我們現在做的很多軟體方面的事情,在未來會變成少數企業提供服務其他企業直接使用的、贏者通吃的模式。但是也不必悲觀,屆時科技的發展肯定會帶來更新鮮的事物需要我們去貢獻自己的聰明才智。

最後引用一下Eric Raymond惋惜Plan9的言論:「九號項目會失敗單純只是因為它的改進程度沒大到能取代Unix。與九號項目相比較,雖然UNIX看來破破爛爛又有明顯缺失,但是它還是能好好的把工作完成,這就足以保住它的地位了。這件事情給那些有雄心壯志的系統架構師上了一課:更佳解決方案所面臨的最危險的敵人,是那些已經能能把事情做好的程式(方案)。」

所有參考資料已經以連接形式置於文中。另外,本人知識、水平有限,如有遺漏、疏誤之處歡迎補充和指正。

Tags: