到底什麼是"雲原生"啊

什麼是雲原生?

大白話就是:

從開發到運維整個軟件生命週期都是在雲上進行。


原生就是土生土長的意思,我們在開始設計應用的時候就考慮到應用將來是運行雲環境裡面的,要充分利用雲資源的優點,比如️雲服務的彈性分佈式優勢。


優勢就是不用考慮硬件、服務器、操作系統甚至不用考慮運維,僅僅用代碼實現你的想法,然後部署即可。


軟件開發發展歷程

  1. 面向操作系統編程

開發完應用直接部署到操作系統,此時跨平臺特別差,尤其是windows/macos開發,部署到linux,給部署和運維帶來非常多的複雜性。


  1. 面向容器編程:

開發完部署到Docker/k8s,容器層面隔離了操作系統,使得跨平臺成為可能,但是增加了開發流程複雜度。


  1. 面向雲編程:

開發時便考慮“雲”,所有資源(計算/存儲/網絡等)按量使用,隨用隨取,按量付費。


  1. 暢想未來

目前的“雲原生”,還是一種混合雲架構,底層是多個機房,多種物理機,多種操作系統,在多個操作系統中安裝k8s等容器管理軟件來達到另一種“統一的雲操作系統”,顯然多種操作系統還是有計算資源的浪費的。未來一定會有一款雲操作系統,直接部署到物理機,可跨地區、跨機房、跨網絡直接提供服務,所有用戶共用一個操作系統。

另外目前的“雲原生”還是在本地開發,然後部署到雲環境中,未來的開發一定是雲上開發,雲上運行,雲上測試,雲上部署。用戶使用的只有屏幕,沒有處理器,所有操作通過網絡交互完成,所有計算在服務端進行。

達到這種要求需要的基礎設施:

  • 高速便宜的網絡:5G提供了基本的可能性,大概6G/7G有望實現
  • 全球統一的操作系統:一定是全球多國的多個商業互聯網公司合同,共建的生態系統、社區、標準。
  • 便攜終端的出現:比如摺疊屏幕、腕式投影等等
  • 計算能力的飛速提升:量子計算提供了可能性
  • 編程語言的與時俱進


如何搭建雲原生

到底什麼是

系統架構

跨操作系統的容器管理能力,提供:

  • 軟件定義存儲
  • 軟件定義計算
  • 軟件定義網絡

技術實現可以基於Docker和k8s,不關心底層操作系統,不關心機房和硬件。所有資源按量使用。

技術實現

  • 微服務
  • 服務網格

技術上基本SpringCloud/Doubbe兩者統一天下。

最佳實踐和方法論

  • devops
  • 自動化發佈
  • 自動化運維
  • 自動化伸縮

Jenkins等各種devops工具,甚至k8s自帶的各種工具完全可以實現。


CNCF基金會


一個統一中立的開源雲生態(至於是否中立嘛這裡就不談了:)。這對雲原生的生態定位會是很重要的一點,也算CNCF最初成立的宗旨之一吧,打破雲巨頭的壟斷。

到底什麼是


雲原生與十二要素

十二要素 (The Twelve Factors) 是由 Heroku 團隊提出的雲應用設計理念,它為構建流程標 準化和高可移植的 SaaS 應用提供了完善的方法論。遵循十二要素設計的應用具備雲原生應用的 所有特徵。十二要素適用於任何語言開發的後端應用服務,它提供的方法論和核心思想如下。

  • 將流程自動化和標準化,降低新員工的學習成本。
  • 劃清與底層操作系統間的界限,以保證最大的可移植性。
  • 適合部署在現代雲平臺上,避免對服務器與操作系統進行管理。
  • 將開發環境與生產環境的差異降至最低,便於實施持續交付和敏捷開發。
  • 應用可以在不改變現有工具、架構或開發流程的情況下,方便地進行水平伸縮。

十二要素重點關注應用程序的健康成長,開發者之間的有效代碼協作,以及避免軟件腐蝕。 十二要素的內容如圖 1-8 所示。

到底什麼是

下面我們來逐條介紹一下十二要素。

1. 基準代碼 (Codebase)

同一應用對應同一套基準代碼,並能夠多次部署。

部署到不同環境的同一個應用,其基準代碼庫應該相同,但每份部署可以包含各自環境中的不同配置。一次部署對應一個運行起來的應用程序,應用與部署的關係是一對多的,這體現了應用代碼的可重用性。同一套基準代碼可以重用到多次部署中去,共享的是代碼,而不同的僅僅是配置。從另一個角度來說,非運行時的應用對應的是代碼倉庫,它的每一個運行時實例都對應一次部署,同一代碼倉庫可以保障應用的復原能力。

推薦使用 Git、SVN 等優秀的源代碼管理工具作為基準代碼庫。基準代碼與部署的關係如 圖 1-9 所示。

到底什麼是

2. 依賴 (Dependencies)

顯式聲明第三方依賴。

隨著技術的發展,應用程序的開發已不再是一個從零開始的過程,大量的第三方類庫使得工程師們可以站在巨人的肩膀上進行增量式開發。應用程序不應隱式地依賴類庫,而是應該通過依賴清單明確地聲明其依賴項。

顯式聲明依賴簡化了環境配置流程,開發工程師僅需要安裝編程語言環境和它對應的依賴管理工具,並從代碼庫中檢索出代碼,即可通過一個命令來構建所有的依賴項,從而輕鬆地開始工作。

十二要素要求應用同樣不應該隱式依賴某些系統工具,比如 curl。即使這些系統工具存在 於所有的現代操作系統中,也無法保證未來的操作系統都能支持或兼容現有應用的使用方式。

現代編程語言都會提供依賴打包管理工具,如 Java 語言的 Maven、Gradle 以及早期的 Ant 等。

3. 配置 (Config)

將配置存儲至環境變量。

應用的配置在不同環境中部署時也會有所差異,若應用將配置以編碼的方式寫入程序的常量,則會造成代碼與配置混淆。十二要素強調配置應該與代碼分離,不應在源碼中包含任何與環境相關的敏感信息。

雖然將配置提煉到屬性文件可以實現將其與代碼分離,但屬性文件仍然可能會被不小心地提交至源碼倉庫。因此,十二要素推薦將配置存儲於環境變量中,這樣可以非常方便地在不同的部署環境間修改,而無須改動代碼。

與配置文件相比,環境變量與語言和系統無關。將配置存儲在環境變量中能夠方便與 Docker 等基於容器的應用配合使用,也易於與 Kubernetes 的 ConfigMap 配合使用。將配置排除在代碼 之外的標準取決於,應用是否可以立刻開源且不必擔心暴露任何系統的敏感信息。

十二要素並不贊同採用配置分組的方式管理配置。有些開發團隊願意將應用的配置按照特 定的環境 (如開發環境、測試環境和生產環境) 進行分組。採用配置分組方式不利於擴展,當 工程師添加他們自己的開發環境 (例如 john-dev) 時,將導致各種配置組合激增,給管理部署 增加額外的不確定性。

十二要素要求環境變量的粒度足夠小且相對獨立,它們不應該作為環境組合使用,而是應該獨立存在於每個部署之中。當應用程序擁有更多種類的配置項或進行環境部署時,採用這種配置管理方式更容易實現平滑過渡。

需要特別指出的是,這裡所指的配置並不包括應用程序的內部配置。舉例來說,Spring 容 器中 Bean 的依賴注入配置,或者 Servlet 的映射配置文件 web.xml 等,它們更應該被認為是代 碼的一部分。

4. 後端服務 (Backing Services)

將後端服務作為松耦合的資源。

後端服務是指應用程序所依賴的通過網絡調用的遠程服務,如數據庫、緩存、消息中間件 以及文件系統等,不同後端服務之間的區別僅僅在於資源的 URL 不同。

十二要素要求應用程序不應該區別對待本地服務和遠程服務,它們同樣都屬於附加資源。 應用程序可以在不改動任何代碼、僅修改資源地址的情況下,將出現硬件問題的數據庫切換為 備份數據庫,或將本地數據庫切換為雲數據庫。應用程序與這些附加資源應該保持松耦合的狀 態。圖 1-10 展示了後端服務松耦合的狀態。

到底什麼是

5. 構建、發佈、運行 (Build、Release、Run)

嚴格分離構建階段與運行階段。

分離構建階段與運行階段的根本在於,要嚴格區分應用的非運行時狀態和運行時狀態。構建是將應用的源代碼編譯打包成可執行軟件的過程,屬於非運行時行為。將基準代碼轉化為一份部署一般要經過構建階段、發佈階段和運行階段。構建階段是將源碼從編譯狀態轉化為可執行的二進制文件的過程 ; 發佈階段是將構建結果與當前部署所需要的配置相結合,並分發至運行環境的過程 ; 運行階段是在執行環境中啟動一系列發佈完畢的應用程序進程的過程。

十二要素規定,禁止在運行階段改動代碼,這樣做會導致基準代碼失去同步。建議每個發 布版本對應一個唯一的發佈 ID,發佈版本只能追加而不能修改,除了回滾,其他變動都應該產 生新的發佈版本。構建與發佈的流程如圖 1-11 所示。

到底什麼是

6. 進程 (Processes)

將應用作為無狀態的進程運行。

應用進程應該是無狀態的。只有無狀態的應用才能做到水平伸縮,從而利用雲平臺彈性伸縮的能力,而需要持久化的數據應該存儲於後端服務中。

在有些遺留系統的設計中,Web 應用通常會將用戶會話中的數據緩存至內存,並保證將同 一用戶的後續請求路由到同一個進程,這種會話被稱為黏性會話。十二要素並不推薦這種做法, 會話數據應該保存至 Redis 這樣的帶有過期時間的緩存中,並作為後端服務提供服務。

7. 端口綁定 (Port Binding)

通過端口綁定對外發布服務。

應用本身對於發佈服務的環境不應該有過多的要求,不需要依賴雲平臺提供應用運行容器, 只要雲平臺分配某個端口對外發布服務即可。通過端口綁定訪問服務也意味著任何應用都可以 成為另一個應用的後端服務。

例如,可以利用 Jetty 這種內嵌的 Web 服務器或 Spring Boot 等快速開發框架來開發包含可 發佈 HTTP 服務的應用。

8. 併發 (Concurrency)

能夠通過水平伸縮應用程序進程來實現併發。

雲平臺操作系統與 UNIX 操作系統類似,運行在系統之上的不同進程彼此獨立並且共享操作系統管理的硬件資源。不同的應用彼此獨立、互不干擾地運行在一個雲平臺上,可以充分利用雲平臺的整體計算能力。這樣的進程模型對於系統擴容非常實用。

開發人員應該將不同類型的工作分配給不同的進程,例如,將 HTTP 請求交給 Web 服務器 的進程來處理,將常駐後臺進程交給 worker 進程負責,將定時任務交給 clock 進程負責。這條 原則與微服務的設計原則有異曲同工之妙,它希望應用開發者將應用的職責儘可能進行拆分。 圖 1-12 清晰地展示瞭如何通過增加不同類型的應用進程來實現系統的水平伸縮。

到底什麼是

9. 已處理 (Disposability)

可以快速啟動和優雅關閉應用。

快速啟動是為了充分利用雲平臺根據需要調度資源的能力,在需要的時候,以最小的延時擴展計算能力,提供服務。優雅關閉是為了保證應用邏輯的完整性,將該完成的任務正確完成並釋放資源,將未能完成的任務重新交回系統由其他應用的運行實例來繼續完成。隨時可能有大量部署在雲平臺上的應用實例啟動、運行和關閉,因此快速啟動和優雅關閉應用對於維持系統的高性能和穩定性尤為重要。

10. 開發環境與線上環境等價 (Dev/Prod parity)

要保持開發環境與線上環境等價。

開發環境和線上環境之間存在著很多差異,主要包括代碼差異和操作差異。開發人員正在編寫的代碼可能需要很長時間才會上線,這將導致開發環境和線上環境的代碼差異很大。在開發環境中,代碼一般由開發人員編寫並調試,而在線上環境中,代碼則由運維人員部署,不同的操作方式也可能帶來環境的差異。

保持環境一致,可以提高功能測試和集成測試的有效性,避免出現開發環境測試正常但生 產環境出現問題的情況。推薦使用 Jenkins 等持續集成工具來縮短生產代碼和代碼庫中的代碼不 一致的時間,並採用自動化部署的方式避免操作差異。

11. 日誌 (Logs)

使用事件流處理日誌。

運行在雲平臺上的應用處在複雜的分佈式基礎設施之上,如果日誌仍然寫在硬盤的一個文件中,將給系統排錯或通過日誌挖掘信息帶來很大的困難,並且當日志與應用綁定時,應用不能作為無狀態進程,也就無法充分利用雲平臺的擴容能力了。

為了解決以上問題,我們應採取相應措施——應用將日誌輸出到標準輸出 (STDOUT),然 後由雲平臺統一收集並處理。在線上環境中,進程的輸出事件流由運行環境截獲,運行環境會 將所有輸出事件流整合在一起,然後發送給一個或多個最終的處理程序,用於查看或長期存檔。

推薦使用 Flume、Filebeat 或 fluentd 等日誌收集工具。日誌事件流最終可以被髮送到 Elasticsearch 或 Splunk 這樣的日誌索引及分析系統中,用於排錯查詢和後期分析。

12. 管理進程 (Admin Processes)

將後臺管理任務當作一次性進程運行。

與用來處理應用的常規業務進程不同,工程師經常希望執行一些用於管理或維護應用的一次性任務,這類任務被稱為後臺管理任務,例如檢查和清理環境、遷移數據等。

這些後臺管理任務應該作為一次性進程,與常駐進程使用同樣的環境,基於同樣的代碼庫和配置發佈運行。總而言之,一次性進程同樣應該遵循前面提到的十一個要素。

遵循十二要素的應用程序環境是一次性且可複製的。由於應用程序的狀態均通過後端服務持有,因此無狀態的應用有助於編排系統自動化擴展。擴容時,編排系統僅須將應用程序的運行時環境數量擴充到期望位並直接啟動進程即可 ; 縮容時,則需要停止應用進程並刪除環境,無須進行環境狀態備份。

要想了解有關十二要素的詳細內容,請參見官方網站: https://www.12factor.net/。


分享到:


相關文章: