做者 | 司徒放(姬風) 阿里巴巴技術專家docker
本文整理自司徒放(姬風)題目爲《開源的黃金時代,阿里巴巴雲原生開源的探索與實踐》的演講。 關注「阿里巴巴雲原生」公衆號,回覆關鍵詞「開源」便可下載本文 PPT。api
導讀:從擁抱開源、貢獻開源、自主開源,到賦能開源,開源已升級爲阿里技術戰略之一,且正爲開發者源源不斷地輸送切實可見的價值。雲原生是阿里開源的重要領域,短短几年,以 K8s 爲核心的雲原生開源生態迅猛發展,這是全世界開發者合做傑出成果,也是開源力量的結晶。安全
你們好,我是司徒放,目前在阿里巴巴負責阿里雲的應用平臺和微服務產品線。在和你們分享咱們在雲原生應用方面的探索以前,先和你們介紹一下阿里巴巴在整個應用架構方面的演進歷程。性能優化
今年是阿里巴巴成立的二十週年,二十年前,阿里巴巴使用的這個應用的架構,仍是單體應用模式,它有不少的業務模塊都在一個應用裏面,各個業務都在一個應用裏面開發,這個架構的一個好處是簡單,也很是容易部署,對小的創業公司來講是很方便的。它的缺點在於團隊變大變多以後,不能知足快速迭代要求,由於每個業務它須要去發佈的時候,都須要在同一個應用上作修改、發佈,當這個業務迭代很是快的時候,它同時的一個併發修改就很是多。微信
因此在 2008 年的時候,阿里巴巴就引進到了微服務架構,只是當時並不叫微服務,而是叫服務化架構。各個業務模式就按照服務的邊界來拆分,這是比較鬆耦合的一種方式,一個微服務應用是無狀態的,能夠快速擴展實例。並且某個實例有異常好比宕機時會能夠自動下線,不會影響整個服務架構的穩定性。微服務架構也比較容易推進整個互聯網公司的快速迭代需求。架構
大概三年前,阿里巴巴就走向了雲原生的架構。這是一個自然適合雲的、可以充分利用雲的彈性能力和標準雲服務,給整個阿里巴巴的電商下降機器的準備成本,特別是相似於在大促雙十一須要不少機器去支撐,可是大促結束以後,這些機器有一半以上就能夠歸還到雲上。併發
這個時候,阿里巴巴就在往雲原生的方向去邁進,並且經過整個雲服務可以更快地加快整個阿里巴巴的技術構建。並且雲原生架構,是一個比較開放、標準、沒有侵入性的技術架構。app
在阿里巴巴進入到了雲原生以後,咱們看一下阿里巴巴在開源方面作了一些什麼樣的事情呢?負載均衡
首先,整個雲原生架構裏面最重要、最關鍵的一個基石就是 Kubernetes。 阿里巴巴在兩年前,就在大規模的落地 Kubernetes 的整套技術用來作咱們機器資源的調度和管理。在內部有數十萬臺級別的機器以及上百萬級別的容器規模,直接拿開源的 Kubernetes 到這種生產規模下是用不起來的,因此咱們在上面作了不少性能優化,包括針對規模上的改造,使得整個 Kubernetes 在阿里巴巴內部可以很順暢地 run 起來,阿里巴巴也在不斷地向上游去貢獻咱們內部實踐和優化的代碼。 除了 Kubernetes 以外,在整個雲原生生態裏還有像容器、etcd,咱們也在不停地優化它的規模能力以及安全隔離方面的一些能力。同時,也開源了內部使用的蜻蜓(Dragonfly)用來作大規模的鏡像快速分發。框架
在開發領域,阿里巴巴很早就已經使用了微服務架構,也對外進行了開源,好比說 Apache Dubbo,這個是比較知名的 RPC 框架;還有去年開源的 Nacos ,做爲阿里巴巴集團支撐大規模的服務註冊發現、配置推送一個組件;另外,還有 Spring Cloud Alibaba,基於阿里開源的組件提供了一整套 Spring Cloud 最佳實現;還有像支撐整個阿里巴巴高可用的 Sentinel、以及 Apache RocketMQ 消息隊列,都是咱們在開發領域作的開源。
這些組件其實隨着阿里巴巴進入雲原生時代以後,也在逐步結合雲原生作一些改進,好比說 Apache Dubbo,會更好地去適配咱們將來的微服務 Service Mesh 架構,它會理解 Istio 的 xDS 協議,成爲一種數據面;好比 Nacos,它爲 Service Mesh 的 Istio 提供 MCP 協議的對接,成爲雲原生微服務和傳統微服務互通的橋樑。
在開發領域和運維領域之間,其實我認爲還有一個很大的空缺,就是專門用來鏈接整個開發和運維的應用這一塊。
對於開發階段,寫完代碼以後交付的是一個應用包,而這個應用包也是整個運維繫統上運行的一個基礎顆粒。咱們認爲如今在雲原生階段,缺乏了一個很好的應用交付和運維標準,你們在不一樣的公司會看到每一個公司都有不同的運維平臺,應用的部署和交付都沒有辦法被標準化。咱們如今進入雲原生時代,推崇的是標準、開放,因此咱們認爲在這一塊上面還有很大的機會去作進一步的應用標準建設,這是我接下來想要和你們重點分享的一個話題。
先看一下雲原生在交付和運維方面有哪些痛點呢?
剛剛也講到了,在進入到了微服務以後,咱們面臨的一個問題就是應用的實例數會愈來愈多,會到成百上千的規模不斷往上增加;另外還有咱們部署的環境也變得愈來愈多,好比說如今有不一樣的雲廠商,以及咱們有不少專有云的自建機房的輸出;另外還有不少自建的環境,這些環境多樣化以及咱們應用在運行時它會以容器的方式去運行,可能仍是以傳統的虛擬機的方式去運行,或者它會以函數的方式去運行,可是運行時也會有不少不一致,好比不一樣的環境、或運行時的不一致,會致使整個分佈式運維體系變得愈來愈複雜,它的監控、日誌採集也是一個很大的挑戰。
當這些應用已經放到雲上去運行的時候,因爲不少的雲服務並無被標準化,不少這種雲的能力須要集成到應用上的時候,也會有很大集成的困難。而這些雲上應用運維的痛點之前也有相似的,咱們能夠跟過往的解決方案作一個對比。
首先,是相似 Ansible、Puppet 這些基礎設施運維自動化的工具。這些工具對整個運維效率起到了很大的提高做用,減輕了運維同窗的工做量,可是它使用的是一些自應用的模塊,並且它的概念是偏向於腳本運維的方式,很是的底層。
隨後出現了相似 Cloud Foundry 、Heroku 這種比較經典的應用平臺,這些應用平臺是以應用爲中心去作運維和交付,往上把運維的工做進行了一個抽象,按照 buildpack 的方式去作運維和交付,經過 buildpack 的方式,能夠簡化整個應用運維的工做,可是 buildpack 自己覆蓋的範圍比較窄,在運維和交付方面,缺少一些運維交付的標準,因此它的可擴展性是比較差的。
隨着 Docker 容器的橫空出世,打破了傳統基於 buildpack 的應用交付模式,因此就出現了新一代的容器管理平臺,而 Kubernetes 成爲了雲原生時代一個新的容器平臺事實標準。Kubernetes 自己提供了不少基礎服務抽象,好比說 Deployment、Service。在社區裏面它有一句很著名的定位:「Kubernetes is the platform for platforms.」也就是說,Kubernetes 定位是構建平臺的平臺,可以簡化構建應用平臺的複雜度,它不會再去作上層基於應用的抽象。你們能夠發現歷史老是那麼類似,從過去的運維工具到後來基於應用的抽象,到如今容器出現打破運維格局,從新對這個領域進行洗牌,天然,在雲原生時代須要一個對應交付和運維應用的平臺。
關於雲原生時代的應用抽象,咱們要作一個思考:咱們須要什麼樣的應用抽象呢?
首先,它須要解決咱們運維交付的一個複雜度,以及屏蔽底層細節差別。不管何時,都是應用平臺須要解決的問題。另外,參考咱們過去比較傳統的應用平臺的問題,好比說 buildpack 這種方式,它存在不通用/不易於擴展的問題,咱們認爲接下來的應用抽象,它應該要具有在應用運維方面更加通用、可擴展的描述能力。
除此以外,咱們在推廣應用抽象的時候,仍是要採用開源和社區的方式去推動,由於將來必定是更加標準和開放的,咱們推廣這個應用抽象,就是但願有更多開發和運維工做者,可以給這個標準提供更多的建議,可以經過整個社區進一步推進整個應用交付和運維標準的發展。
在上個月中旬,阿里雲和微軟聯合發佈了「Open Application Model(開放應用模型)」這一個開源項目。咱們但願經過這個開放應用模型,解決「在雲原生時代缺少一種應用交付標準」的問題。(「Open Application Model -開放應用模型」後面簡稱爲「OAM」)
OAM 裏面有三種不一樣的角色。
首先是應用開發。很明顯,應用開發是負責編寫業務邏輯的。好比說它會寫 Spark、Wordpress、Spring Cloud 等微服務的程序,它寫完這個微服務的程序以後呢,會按照 OAM 標準編寫一段應用定義;
第二個是應用運維的角色,就是負責應用的交付與運維;
第三個角色是基礎設施平臺。基礎設施平臺在 OAM 裏的一個重要定位,在於它要將本身的基礎服務能力抽象成可被複用、被重用的模塊,並提供給開發和運維人員去使用。
下面爲你們解讀以上的三個角色對應的三個核心概念。
首先是 Component。它是被開發人員定義的一個可被重用的應用組件,這個應用組件描述的就是這個應用它運行的方式;
第二個重要概念是 Trait。它是一種應用的運維特徵,是由基礎設施平臺這個角色定義的,而這個定義它包含了可組合的應用運維特徵,這個特徵是實際上是這個平臺能夠提供出來的某種運維能力抽象;
最後一個是 ApplicationConfiguration。運維人員負責把 Component 和 Trait 兩個綁定在一塊兒,而且做爲一個具體的實例化,生成了這個應用配置(ApplicationConfiguration)以後,就能夠把應用部署起來。
接下來是一個具體的用 OAM 描述的應用配置文件(上圖文件作了必定內容簡化,具體如下面的 yaml 文本爲準)。<br />
apiVersion: core.oam.dev/v1alpha1 kind: ComponentSchematic metadata: name: wordpress spec: workloadType: core.oam.dev/v1alpha1.Server containers: - name: test image: docker/wordpress:latest env: - name: key1 fromParam: test-key ports: - type: tcp containerPort: 9999 name: http parameters: - name: test-key type: string --- apiVersion: core.oam.dev/v1alpha1 kind: ApplicationConfiguration metadata: name: wordpress-app spec: components: - name: wordpress instanceName: wordpress-instance parameterValues: - name: replicas value: 3 - name: test-key value: value-from-ops traits: - name: service parameterValues: - name: portMapping value: - protocol: "TCP" port: 52014 targetPort: 9999 - name: rollout parameterValues: - name: canaryReplicas value: 1
由運維人員編寫的 ApplicationConfiquration 文件,它將 Component 和 Trait 兩個概念綁定在一塊兒。首先裏面描述運維要部署一個叫 wordpress-app的應用,它引用了一個叫 wordpress 的 Component。這是開發人員在另外一個配置文件 Component 定義的,他除了定義 wordpress 應如何運行(好比配置鏡像位置)之外,還容許運維配置運行實例的副本數以及運行時環境變量 test-key
的值。在 ApplicationConfiquration 裏同時引用了兩個運維特徵,運維人員會填寫這個應用須要一個負載均衡,要作外網的端口映射,部署時須要採用金絲雀發佈策略。這個文件對應到實際上的部署階段會變成如上圖右側所示,上面會有一個負載均衡,好比在雲上運行時,就會使用 SLB 去作負載均衡的自動分發,會給它配置外網 IP 和內外端口映射。
經過這個簡單的 yaml 文件,你們就能夠了解到這個應用怎麼作快速部署,而且描述運維要具有什麼能力。
給你們總結一下,我所認爲的 OAM 的重要的設計理念。
首先第一個是配置即代碼。全部的 OAM 上面的運維和交付的操做都會使用配置的方式,徹底經過 yaml 文件去完成全部的交付運維配置;
第二個是依賴倒置。這個依賴倒置有點像 JAVA Spring 開發者使用 IoC 或者 DI 的這種模式,在寫這個應用配置的時候,只是依賴應用標準抽象,而這個標準抽象背後的實現其實是由 OAM 的運行時去作「注入」,經過這個方式就使得咱們的應用運維不依賴於咱們具體的運行環境;
第三個是重要的設計理念就是角色關注點分離。剛剛上面講過 OAM 裏的三種不一樣的重要角色:開發、運維以及基礎設置平臺。這三種角色只須要編寫對應不一樣的配置文件,互相解耦。這樣開發不須要關心應用是怎麼運維的,只須要把運行時須要的配置暴露並描述出來;基礎平臺只須要把平臺能力提煉成 Trait;最終由運維人員把開發須要的參數和運維須要的能力進行結合。
第四個就是整個 OAM 的設計是一個可組合可擴展的方式。它會經過讓咱們剛剛說到的 Traits 可以按需組合、重用、移植和擴展。
上面咱們說了這麼多其實都是比較一些概念性的東西,接下來咱們看一下,在阿里巴巴的雲產品 EDAS 對 OAM 所作一些落地方面的嘗試,這也是第一個在實際生產上面基於 OAM 對外可開放使用的雲產品。
下面會用 EDAS 爲例,給你們作一個介紹,講解一下 OAM 具體怎麼運做。
首先介紹一下 EDAS 是阿里雲上面的一個雲產品,它扮演着我剛纔講到的相似於一個應用平臺的一個角色:
這些是 EDAS 做爲應用平臺在阿里雲上的產品定位。
那麼它在支持 OAM 在運行的時候又是什麼樣的呢?
如圖所示,一個開發人員,他首先須要去編寫一個按照 OAM 標準爲參考去定義一個 Component。這個 Component 裏面會定義如開發應用類型是什麼樣子,好比它的鏡像路徑、它須要多大的存儲空間,以及它的環境變量是什麼樣子,這些都是開發人員在開發的時候須要去描述的內容。
對於阿里雲來講,它是一個基礎設施平臺的身份。它在上面其實有不少運維的能力,好比說像監控報警、塊存儲、須要發佈策略和彈性伸縮的策略。EDAS 會把這些平臺能力抽象成一個一個獨立的 Trait,開放給運維人員使用。
在須要部署應用的時候,運維人員會選擇 EDAS 上提供的 Trait 並填寫相關參數,同時也設置好開發人員的 Component 的參數,這做爲一次應用部署,生成了 ApplicationConfiguration 提交給 EDAS。
EDAS 做爲 OAM 的運行時,在讀取到這份部署配置後,它會去實現 Trait 提供相應的運維特徵動做,好比說運維描述須要一個塊存儲,那麼 EDAS 會在阿里雲上面去申請一個具體的塊存儲對象,並綁定到這個應用上面。同時 EDAS 會提供一個容器環境(如 Kubernetes)去運行開發者定義的 Component 的工做負載,好比購買 ECS,配置好容器環境,把環境變量傳給容器,使 Component 可以正常運行。
以上就是整個 EDAS 支持 OAM 的一個運行示意圖。
那麼 EDAS 在支持 OAM 以後,它的使用狀況又會發生怎樣的變化呢?
在沒有使用 OAM 的時候,客戶須要和系統解釋我要作些什麼事情、我要怎麼作這個事情。好比說,他須要申請 5G NAS 存儲,而且要把它掛載到某個機器的某個目錄上面;或者他還有一個監控的需求,他須要告訴系統如今有一個業務指標文件,須要被監控採集,他要去設置這個文件的指標處理規則,最後把這個指標存儲成時間序列數據,而且設置報警閾值。在使用 OAM 以後,它就變成了描述式,他只要描述我須要什麼東西就夠了。好比開發者能夠說這個目錄上面須要有 5G 的外置可讀寫存儲就夠了,具體這 5G 存儲怎麼申請是由 OAM 運行時去幫助解決的。另外,在監控的時候,他只須要描述本身的這個應用須要被監控、哪一個指標須要被監控並報警就夠了,他不須要了解對接到具體是哪個監控系統,他不須要去關心這些事情。
原來不少雲產品或者原來不少自定義運維平臺都是須要依賴特定的 API 或者 CLI 這種模式去作運維的,這個時候應用要遷移到另一個運維平臺,它的代碼、鏡像、二進制包能夠帶走,可是它的不少運維的設施、運維的配置包括監控的配置,這些東西都是隻能留在這個平臺上的,沒有辦法很容易地遷移到另一個平臺上面。而經過 OAM,能夠將平臺全部的運維配置以 yaml 導出,而且可以很快地導入到另一個環境、甚至是另外一個應用平臺上,整個系統會變得更加標準。
在使用 OAM 之前,運維人員須要去學習不少知識,好比使用的是 Kubernetes,他須要去了解整個容器和 Kubernetes 的使用方式,他要作定製和拓展就須要去學習 Kubernetes。若是他是從虛擬機的模式切換到容器的運維模式,這個時候他就須要不少時間去理解容器和虛擬機運維之間的差別。遷移到 OAM 以後,至關於 OAM 屏蔽了整個平臺底層的細節,因此使得整個運維平臺的 OAM 配置沒有多大差異。
最後一點就是定製的難度上面。剛剛也講到過,這個是 OAM 的一個重要的目標,讓整個運維的擴展可以更容易的被發現、被組合、被替換。在使用 OAM 以前,運維的邏輯都散落在腳本里面,或者說都在運維平臺內部,這個時候很難去統一管理。而一套 OAM 的運行環境是能夠自描述的,能夠很是容易把平臺提供的 Trait、Component 工做負載羅列出來,使用者能夠替換或增長新的 Traits,在運行應用時能夠自由選擇和組合這些 Traits。
以上講了 OAM 相關的一些基本內容,實際上 OAM 剛剛開源還有不少須要補充和完善的地方,這裏也列出了 OAM 上最近這半年的計劃,但願你們可以參與社區,在上面貢獻更多的想法。
主要有幾個規劃:
易用性方面
OAM 開發方面
功能方面
最後,個人演講就到這裏,謝謝你們!喜歡 OAM 的朋友能夠掃描下方二維碼,謝謝!
更多詳細信息請關注「阿里巴巴雲原生」。
「 阿里巴巴雲原生微信公衆號(ID:Alicloudnative)關注微服務、Serverless、容器、Service Mesh等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,作最懂雲原生開發者的技術公衆號。」