避免不完全的雲原生(四):技術和基礎設施角度

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"},{"type":"strong"}],"text":"本文最初發佈於The Startup博客,經原作者授權由InfoQ中文站翻譯並分享。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"注意:這是該系列文章的第4部分。你可以點擊這裏閱讀"},{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/LmUVC2HHNPD5lHSzETUa","title":"xxx","type":null},"content":[{"type":"text","text":"上一部分"}]},{"type":"text","marks":[{"type":"italic"}],"text":"。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雖然我們在前兩篇文章中討論的人員、流程、架構和設計問題都是雲原生解決方案的關鍵推動因素,但云原生解決方案最終要落在技術和基礎設施上,這也是我們在本文中要討論的內容。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/57\/2d\/5731748bacaa59c5bf382bfe99e6ef2d.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"雲原生要素:技術和基礎設施"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雲基礎設施就是將底層硬件抽象出來,使解決方案能夠快速地自助配置和擴展。它應該能夠使用相同的操作技能管理不同的語言和產品運行時。此外,它應該促進操作自動化,並提供一個可觀測性框架。讓我們仔細看下,在雲原生方法中使用的基礎設施有什麼關鍵特徵。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/4e\/7c\/4ec1dc3d3db92ea173994c26f3545f7c.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"雲原生的技術和基礎設施"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"彈性、不可知且安全的平臺"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了實現雲原生,我們必須向部署組件的平臺提很多要求。平臺應該提供一種通用的機制,不管我們部署什麼,它都能提供幫助,讓我們不用考慮非功能性問題,同樣,還應該“內置”安全性。因此,我們對平臺的主要要求有:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"彈性資源能力"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不可知部署和操作"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默認安全設置"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果開發人員要提高他們的生產力,就需要能夠專注於編寫創造業務價值的代碼。這意味着平臺應該解決負載平衡、高可用性、可伸縮性、彈性,甚至災難恢復等問題。在部署時,我們應該能夠指定高級的非功能性需求,而由平臺完成剩下的工作。在這方面,我們將使用Kubernetes容器編排作爲一個強大(實際上無處不在)的例子,但是雲原生絕對不限於Kubernetes平臺。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kubernetes集羣可根據所部署的組件的需求,提供CPU、內存、存儲、網絡等資源的自動化、彈性配置。資源池可以分佈在許多物理機上,也可以分佈在許多獨立地區的多個可用區域上。它負責找到你所需要的資源,並將組件部署到這些資源中。你只需要指定需求——需要什麼資源,它們應該或不應該擴展,以及它們應該如何擴展和升級。對於基於虛擬機的平臺,我們也可以這樣說,但正如我們將要看到的,容器帶來了更多的東西。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"假設我們遵循了上一節的架構原則,在容器中交付應用程序組件,讓Kubernetes以標準化的方式執行部署和後續操作,而不考慮任何特定容器的內容。如果組件基本上是無狀態的、可拋棄的、細粒度的、良好解耦的,那麼平臺就很容易以通用的方式部署、擴展、監控和升級它們,而不需要了解它們的內部結構。對於每一種軟件,現在都有一種逐步拋棄專有安裝和拓撲配置的趨勢,像Kubernetes這樣的標準就是其中的一部分。現在,它們都以相同的方式工作,我們可以受益於操作的一致性、學習曲線的降低以及附加功能(如監視和性能管理)更廣泛的適用性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後,我們希望平臺內置了安全,這樣,我們從第一天起就可以相信它是安全的應用程序運行環境。我們不應該每次設計一個新組件時都需要重新設計安全內核;相反,我們應該能夠從平臺繼承一個模型。在理想情況下,這應該包括身份管理、基於角色的訪問管理、保護外部訪問和內部通信。我們注意到,在這個例子中,Kubernetes本身只是部分解決方案;對於一個完整的安全解決方案,還需要添加一些元素,比如用於內部通信的服務網格,以及用於入站流量的入站控制器。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"輕量級運行時"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"要想實現操作敏捷性,就要保證組件儘可能簡單和輕量級。這可以歸結爲三個主要特性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"快速啓動\/關閉"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"基於文件系統的安裝和配置"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"基於文件系統的代碼部署"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了實現可用性和可伸縮性,組件必須能夠快速創建和銷燬。也就是說,容器內的運行時必須可以優雅地啓動和關閉。它們還必須能夠處理不優雅地關閉。這意味着有許多優化可能可以做:從刪除依賴項,減少初始化過程中的內存佔用,到在鏡像構建中啓用編譯“左移”。至少,運行時應該能夠在幾秒內啓動,這個期望值會不斷降低(如"},{"type":"link","attrs":{"href":"https:\/\/quarkus.io\/blog\/runtime-performance\/","title":"","type":null},"content":[{"type":"text","text":"Quarkus"}]},{"type":"text","text":")。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果採用持續集成,我們還希望構建儘可能簡單、快速。大多數現代運行時已經不再需要單獨安裝軟件,而只需將文件放到文件系統上。類似地,根據定義,不可變鏡像不應該在運行時更改,它們通常從屬性文件讀取配置,而不是通過自定義運行時命令接收配置。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"同樣,實際的應用程序代碼也可以放在文件系統中,而不是在運行時部署。這些特性組合在一起,使得構建能夠通過簡單的文件複製快速完成,非常適合容器鏡像的分層文件系統。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"操作自動化"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果我們能夠作爲發佈的一部分,交付在運行時配置解決方案的整個行動方案(包括基礎設施和拓撲結構的所有方面),會怎麼樣呢?如果我們可以將行動方案存儲在代碼存儲庫中,並可以像處理應用程序代碼那樣觸發更新,情況會怎樣?如果我們讓操作人員這個角色聚焦於實現環境自治和自愈,會怎樣?這些問題引出了一些關鍵的方法,我們應該以不同的方式處理基礎設施:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"基礎設施即代碼"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"存儲庫觸發的操作(GitOps)"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"站點可靠性工程"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正如前面所討論的,基於鏡像的部署已經使部署的一致性提高了很多。然而,這隻交付了代碼及其運行時。我們還需要考慮如何部署、擴展和維護解決方案。在理想情況下,我們希望能夠將所有這些都作爲“代碼”和組件的源代碼一起提供,以確保在不同環境中構建時的一致性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"術語“基礎設施即代碼”最初關注的是編寫底層基礎設施(比如虛擬機、網絡、存儲等)的腳本。編寫基礎設施腳本並不是什麼新鮮事,但有越來越多的專用工具,如Chef、Puppet、Ansible和Terraform,大大推動了這方面的發展。這些工具首先假定有可用的硬件,然後在硬件上準備並配置虛擬機。有趣的是,當我們遷移到容器平臺時,這個過程會有什麼變化。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在理想情況下,我們的應用程序應該可以假設,已經有一個Kubernetes集羣可用。集羣本身可能是使用Terraform構建的,但這與我們的應用程序無關;我們只要假設集羣是可用的。那麼,現在我們需要提供什麼樣的基礎設施即代碼元素,來完整地描述我們的應用程序呢?可以認爲,就是那些打包在helm charts或Kubernetes Operator中的各種Kubernetes部署定義文件以及相關的客戶資源定義(CRD)文件。結果是一樣的——將一組文件與我們的不可變鏡像一起交付,它們完整地描述了應該如何部署、運行、擴展和維護。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因此,如果我們的基礎設施現在成了代碼,那麼爲什麼不用與應用程序相同的方式構建和維護基礎設施呢?每次我們提交一個基礎設施的重大更改時,都可以觸發一次“構建”,它會自動地部署到環境中。這種日益流行的方法被稱爲GitOps。值得注意的是,這種方法特別偏愛採用“聲明式”而非“命令式”方法的基礎設施工具。你提供了一個描述“將來”目標狀態的屬性文件,然後該工具將解決如何讓你達到目標狀態的問題。上面提到的許多工具都可以在這種方式下工作,這是Kubernetes的基本操作方式。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"真正的系統是複雜的、不斷變化的,所以認爲它們永遠不會崩潰是不合理的。不管像Kubernetes這樣的平臺在自動化動態擴展和可用性方面有多好,問題還是會出現,至少最初還是需要人工干預來診斷和解決。然而,在實現了細粒度、彈性伸縮組件自動化部署的世界中,反覆的人工干預將變得越來越不可能,只要可能,就要實現自動化。爲了做到這一點,操作人員需要重新接受培訓,成爲“站點可靠性工程師”(SRE),編寫代碼執行必要的操作工作。事實上,一些組織已在明確地招聘,或將開發人員移到運營團隊中,以確保工程文化。人們越來越多地保證解決方案是可自愈的,這意味着當系統擴展時,我們不再需要增加相應的操作人員。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"可觀測性和監控"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"隨着組織向更細粒度的容器化工作負載發展,將監控作爲事後加上去的東西是不可持續的。爲了在雲原生環境中取得成功,這又是一個我們需要“左移”的例子。解決這個問題取決於我們是否能夠回答下面三個關於組件的問題:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它是健康的嗎?你的應用程序有可以輕鬆訪問的狀態嗎?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它裏面發生了什麼?你的應用是否有效地使用了平臺無關的日誌記錄和跟蹤?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它是如何與其他組件交互的?你利用了跨組件相關性嗎?"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可觀測性並不是一個新術語,儘管它在IT領域,尤其是在雲原生解決方案方面得到了新的應用。它的定義來自於非常古老的控制理論。它是一種度量,是指基於從外部看到的內容,可以在多大程度上理解系統內部的狀態。如果你希望響應性地控制某個東西,你就需要能夠準確地觀測它。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有些定義還做了區分,監控是針對已知的未知因素(如組件狀態),而可觀測性是針對未知的未知因素——爲之前沒有想過的問題尋找答案。在一個高度分佈式的系統中,你兩者都需要。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"平臺必須能夠輕鬆、迅速地評估已部署組件的運行狀況,以便快速做出生命週期決策。例如,Kubernetes要求組件實現"},{"type":"link","attrs":{"href":"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/configure-liveness-readiness-startup-probes\/","title":"","type":null},"content":[{"type":"text","text":"簡單的探測"}]},{"type":"text","text":",以報告容器是否已啓動、是否已準備好工作以及是否運行良好。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"此外,組件應該基於其活動,以標準的形式提供易於訪問的日誌記錄和跟蹤結果,用於監控和診斷。通常,在容器中,我們只簡單地記錄到標準輸出。然後,平臺可以分類整理和聚合這些日誌,並提供查看和分析服務。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於細粒度組件,涉及多個組件的交互可能會增加。爲了能夠理解這些交互並診斷問題,我們需要能夠可視化跨組件請求。"},{"type":"link","attrs":{"href":"https:\/\/opentracing.io\/","title":"","type":null},"content":[{"type":"text","text":"OpenTracing"}]},{"type":"text","text":"是一個非常適合容器世界的、越來越流行的現代化分佈式跟蹤框架。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"回顧"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下圖是前面提到的讓雲原生採用取得成功的所有關鍵要素:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/03\/e9\/03aec106876e8f46e7c05f56b0a8e0e9.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.infoq.cn\/resource\/image\/2d\/20\/2d4f615de16028914ddd0e7714c06220.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"雲原生的要素"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通常,它們是相互聯繫,而且相互加強的。你需要全部都做嗎?這樣的問題表述方式可能是錯誤的,就好像是說上面的任何一項都是簡單的二元問題,“是的,你需要”或“不,你不需要”。問題應該是你要做的多深入。無疑,你需要考慮每一個方面的現狀,並評估是否需要更進一步。在"},{"type":"link","attrs":{"href":"https:\/\/kylegenebrown.medium.com\/the-why-of-cloud-native-goals-and-benefits-5c559a4e73a5","title":"","type":null},"content":[{"type":"text","text":"下一篇文章"}]},{"type":"text","text":"中,我們將回到“爲什麼”人們被雲原生所吸引,並看看這是否可以幫我們理清,我們如何、何時以及在多大程度上採納上述要素。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"查看英文原文:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/medium.com\/swlh\/the-how-of-cloud-native-technology-and-infrastructure-perspective-765be1606840","title":"","type":null},"content":[{"type":"text","text":"The “How” of Cloud-Native: Technology and Infrastructure Perspective"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"延伸閱讀:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/LmUVC2HHNPD5lHSzETUa","title":"xxx","type":null},"content":[{"type":"text","text":"避免不完全的雲原生(三):架構和設計角度"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/Qj0SqAEDZZyVOPyhyTXY","title":"","type":null},"content":[{"type":"text","text":"避免不完全的雲原生(二):人員和流程要素"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/PfHdeTgybyC47SpAB2fo","title":"","type":null},"content":[{"type":"text","text":"避免不完全的雲原生(一):雲原生到底意味着什麼?"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/LIRjAI0mhsClCooPtzLw","title":"","type":null},"content":[{"type":"text","text":"避免不完全的雲原生"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章