
作者 | 張裕
來源 | 阿裡技術公衆号
一 什麼是雲原生DevOps
我們先通過一個簡單的例子來了解什麼是雲原生DevOps,它和DevOps有什麼不同。
上圖是一個大排檔,圖中的大廚在非常努力的去切、炒、制作各種美食,并将它賣出去。從原材料的采購到加工到銷售到售後,都是一兩個人完成。這是非常典型的DevOps場景,團隊搞定端到端的所有的事情。這種情況,當廚師水準比較高、銷售能力比較強的時候,可以做到高效率、低浪費。但存在的問題是,想要規模化會很難。因為它的流程都是非标準的,需要廚師有很強的個人能力。
我們再看這張南京大排檔的圖,雖然名字裡有大排檔,但它顯然不是我們上面說的大排檔。我們随便走進任何一家南京大排檔,都可以發現,南京大排檔的廚師,可以專注在為客戶提供更好的菜品上,研發試驗新菜品,并通過小批量的使用者來嘗試和推廣。無論是使用者量增加或減少,都能很快的去适應。店鋪擴張也可以很快。這種我們可以了解為雲原生DevOps。
為了進一步友善大家了解,下面的小視訊裡,我們邀請了2位阿裡大廚,讓他們告訴你什麼是雲原生DevOps。
視訊連結:
https://v.qq.com/x/page/u3220cutt7v.html是以,總結來看,我們認為:雲原生DevOps是充分利用雲原生基礎設施,基于微服務/無服務架構體系和開源标準,語言和架構無關,具備持續傳遞和智能自運維能力,進而做到比傳統DevOps更高的服務品質、更低的開發運維成本,讓研發專注于業務的快速疊代。
如上圖所示,雲原生DevOps基于兩個原則:符合開放标準、語言和架構無關;有兩個基礎:微服務/無服務架構、Serverless基礎設施 BaaS/FaaS;提供兩個能力:智能自運維、持續傳遞。
- 符合開放标準、語言和架構無關,相比于針對某個特定語言、特定架構,在技術更新或疊代時可以有更高的彈性、更好的發展和生命力,形成更好的生态。
- 兩個基礎:基于微服務和無服務架構,可以讓DevOps成為可能;基于Serverless的基礎設施,是面向資源和需求,以達到更好的彈性。
- 在這兩個原則和兩個基礎之上,做到兩個能力:持續傳遞和智能自運維。
二 阿裡巴巴雲原生DevOps更新案例
我們先來看一個阿裡某團隊雲原生DevOps轉型的案例。
案例背景:阿裡某海外電商團隊面臨海外市場站點多、建站成本高、需求變化快、傳遞慢、運維成本高等挑戰,如何平滑地更新到雲原生DevOps來解決這些問題,以提升業務傳遞效率呢?我們是這麼做的。
1 架構更新——服務治理sidecar和mesh化
第一步是架構更新,首先将服務治理的代碼下沉到應用之外的sidecar部分,同時用服務網格來承載了如環境路由之類的能力。如上圖所示,每個綠點代表一個服務應用代碼,每一個橘點代表一個服務治理代碼,這些代碼以二方包的形式存在這個容器中。随着服務治理體系的建設,這裡面就包含了非常多的東西,如日志采集、監控埋點、運維幹預等等,我們把這種容器稱之為富容器。它的問題很明顯:即便是日志采集的更新或調整,我們都需要把應用重新更新、建構和部署一遍。然而這個其實與應用本身是沒有任何關系的。同時,因為關注點不分離,日志采集的一個bug,都會影響到應用本身。
本着讓應用能更專注于應用本身的目的,我們做的第一件事就是把所有服務治理的代碼從應用容器中剝離出來,放到了sidecar裡面,這樣服務治理和應用的代碼就存在兩個容器裡了。同時我們又把原來服務治理的一些事情,比如測試路由、鍊路追蹤等交給了Mesh sidecar 。這樣應用就瘦身了,應用隻需要關心應用代碼的本身。
這樣做的好處是,業務可以專注于業務相關的應用代碼,而無需依賴于服務治理了。
這是第一步,這一步是平滑的,因為我們可以逐漸把服務治理遷移到sidecar裡面,不用擔心一次遷移成本過大。
2 架構更新——從建構解耦、釋出解耦到運維解耦
第二步,我們做了三個層面的解耦:建構解耦、釋出解耦、運維解耦。
了解微服務和無服務架構的人應該清楚,隻有當一個業務能夠獨立去開發、測試、釋出、運維的時候,業務才能跑得更快、更好。因為這樣跟其他人的耦合性降到最低。
但是我們也知道,随着業務越來越複雜和應用的持續演進,應用裡會包含越來越多的業務代碼。比如下圖中這個應用,它裡面有一些代碼是針對某個特定業務的,比如作為一個支付應用,有的是針對盒馬的特定需求的,有的是針對天貓的特定需求的,還有一些是通用代碼,或者叫平台代碼,是針對所有業務場景的。
顯然,從提高開發效率的角度講,業務方改自己相關的業務代碼,可以減少溝通成本,提高研發效率。但這帶來了一個新的問題:如果某一個業務有需求改動,但并不涉及通用的業務邏輯時,也需要對整個應用的所有業務進行全面回歸,如果這個時間段還有其他業務改動,他們需要一起內建并進行釋出。如果改動的業務多,大家就需要排隊內建。這種情況下,內建測試和溝通協調的成本非常高。
我們的目标是每個業務都能獨立的開發、釋出和運維。為了平滑地達到這個目标,我們首先要做的是讓它們在建構階段能夠解耦。比如,對一個相對獨立的業務,我們将其單獨建構為一個容器鏡像,并通過編排把它放到Pod的init Container中,Pod啟動的時候,再将其挂載到主應用容器的存儲空間。
但是這時,應用的釋出和運維還是在一起的,我們需要将它們分開。
我們知道,應用的親密性粗略可以分為三類:
- 超親密,在同一個程序中,通過函數調用通信。
- 位于同一個Pod的不同容器,通過IPC通信。
- 位于同一個網絡中,通過RPC通信。
我們可以根據業務的特點,逐漸地把一些業務代碼拆分成一個個RPC或者IPC服務,這樣它們就可以獨立的釋出和運維了。
至此我們就完成了應用容器的建構解耦、釋出解耦和運維解耦。
3 IaC & GitOps
第三步我們看一下開發和運維态。在很多研發場景中,一個棘手的問題是:不同的環境和業務會有非常多的自己特有的配置,在釋出和運維時經常需要根據情況修改和選擇正确的配置,而這個配置和應用代碼本身其實就是釋出的一部分,傳統的通過控制台去維護的方式成本将會非常高。
在雲原生背景下,我們認為IaC(Infrastructure as Code)和GitOps是更好的選擇。每個應用除了有一個代碼庫之外,我們還有一個IaC 倉庫。這個倉庫裡面會包含應用的鏡像版本和所有相關的配置資訊。當代碼變更需要釋出或配置有變化時,都通過代碼push 的形式推送到IaC倉庫。GitOps引擎能自動檢測到IaC的變化,并自動将其翻譯為符合OAM規範的配置,然後基于OAM模型把改動應用到對應的環境上。無論是開發還是運維,都可以通過 IaC 的代碼版本了解到系統發生了哪些變化,而且每次釋出都是完整的。
4 資源的BaaS化
最後一步是資源的BaaS化。
我們想象一下在應用中是怎麼去使用資源的。我們一般會先去對應的控制台送出資源申請,描述我們需要的資源規格和要求,然後通過審批後得到資源的連接配接串和認證資訊。在應用的配置中加上資源配置,之後如果有改動,再到對應的控制台操作,并配合代碼釋出進行審批。當然,對于這類資源的運維和監控一般也是在獨立的控制台進行的。
當我們的資源種類越來越多,操作和維護成本就非常高了,尤其是在建立站點的時候。
本着用聲明式的方式去描述資源、按需使用的原則,我們通過在IaC 裡定義這些資源的方式,去簡化所有應用對資源的使用。所有的資源都是聲明式的描述,能夠實作資源的智能管理和按需使用。同時我們所有的資源都采用的是雲上通用資源、标準協定,極大降低了遷移成本。這樣我們就逐漸把業務團隊遷移到雲原生基礎設施上。
是以,資源BaaS化的兩大關鍵點是:
- 聲明式地描述資源需求,智能管理,按需使用。
- 采用雲上通用資源,對齊标準協定。
三 雲效驅動雲原生DevOps高效落地
上面我們分享的是阿裡内部的實踐,它依賴于阿裡内部的研發協作平台Aone。Aone的公有雲版本即阿裡雲雲效。我們如何通過阿裡雲雲效去落地雲原生DevOps呢?
ALPD——雲原生時代的研發新範式
從前面的案例我們可以看到,雲原生DevOps的落地是一個系統性的工程,需要有系統的方法和工具體系支撐。上圖是阿裡雲雲效專家團隊提出的下一代精益産品開發方法體系——ALPD,可以看到,ALPD提供了系統的雲原生DevOps落地的方法支撐(圖中籃筐所示)。
上圖是雲效雲原生DevOps解決方案圖。
這裡,我們将使用者分為2種角色:
- 技術主管或架構師。
- 工程師,包括開發、測試和運維等。
作為技術主管或架構師,他需要從整體上去定義和把控企業的研發行為。從大的角度講,研發過程包含四個方面:可運作、可觀測、可治理、可變更。
首先他會去定義企業的研發協作模式,例如是采用靈活研發還是精益看闆。其次他需要掌握整體的産品架構、如需要用到哪些雲産品、這些雲産品如何協調和管理等。然後他會去決定團隊的研發模式:怎麼做好研發協作,怎麼把控研發品質等。第三步,他需要确定釋出政策,采用灰階釋出還是藍綠部署,灰階政策是什麼等等。最後,就是服務的監控政策,比如服務需要接入哪些監控平台,怎麼探測服務狀态,全局監控配置等等。
一線開發、測試、運維工程師,關注的是工作過程的順暢和高效。在雲效項目協作平台接收到一個需求或任務之後,可以通過雲效去編碼、送出、建構、內建、釋出和測試,并部署到預發和生産環境上,将管理者配置的研發模式、釋出政策真正落地。同時,各個環境都是自動觸發和流轉的,不需要人為地協調和拉動。
整個研發過程中産生的資料是一個有機的整體,可以産生大量的資料洞察,可以驅動團隊進行持續改進。當團隊在研發過程中遇到瓶頸或迷茫時,還可以從雲效專家團隊獲得專業的診斷建議和研發指導。
總結一下,雲效的雲原生DevOps解決方案是在ALPD方法論指導下,基于專家建議的最佳實踐,深度整合到完整的DevOps工具鍊中,幫助企業漸進式地邁入雲原生DevOps。
接下來,我們看一個具體的案例。
某網際網路企業,研發團隊在30人左右,沒有專職的運維人員,産品包括20多個微服務以及幾十個前端應用(web、小程式、APP等)。其業務增長非常快,在面對快速增長的客戶和越來越多的需求情況下,原先基于Jenkins+ECS的腳本為主的部署方式漸漸無法滿足訴求,特别是無法解決零停機部署更新的問題。于是,開始需求雲效的幫助,并最終全面遷移到雲效雲原生DevOps。
這個研發團隊主要面臨三大痛點:
- 客戶量大、緊急需求多。
- 無專職運維、雲原生技術如K8S的學習門檻高。
- IT基礎設施架構複雜、釋出耗時耗力。
針對這些問題,雲效從基礎能力、釋出能力和運維能力三個方面入手。
首先,引入阿裡雲ACK在已有ECS資源之上進行基礎設施更新,應用進行容器化改造。在服務治理和應用架構上,從Spring Cloud全家桶簡化為SpringBoot,通過K8S标準能力支撐服務發現和治理。
其次,通過雲效流水線實作自動化容器部署,配合灰階部署政策,做到灰階上線,自動擴容,出現故障自動重新開機,同時,基于雲效流水線做到零停機快速復原任意成本,節約機器成本的同時解決了企業無專職運維人員的問題。
第三,通過雲效自動化流水線和分支保護規範研發模式,包括代碼評審、代碼檢測、測試卡點等,提升回報效率和釋出品質。
下圖為整體解決方案的架構圖。
四 雲原生DevOps更新路徑
我們将雲原生DevOps落地分為5個階段。
第一個階段:全手工傳遞和運維
它是我們最初始的階段,應用架構還沒有進行服務化改造,也沒有使用雲基礎設施或僅使用IaaS,沒有持續內建、測試自動化,使用手工部署釋出和手工運維。相信很少還有企業停留在這個階段了。
第二個階段:工具化地傳遞和運維
首先要做的是應用架構的服務化,采用微服務架構改善服務品質;其次是引入一些研發工具,如gitlab、jenkins這類孤島式的工具解決部分問題。同時我們開始落地單子產品的持續內建,但是一般還沒有實作自動化的品質卡點,釋出往往有自動化工具進行輔助。
第三個階段:有限制的持續傳遞和自動化運維
我們進一步提升基礎能力,将基礎設施進行容器化改造,基于CaaS建設。另一方面,開始引入完整的工具鍊,打通研發資料,例如使用雲效DevOps這樣的工具平台,實作所有資料的完整互通。在釋出能力上能做到持續部署,但是還需要一定的人工幹預。這時,自動化測試已經成為主流了,服務整體可以觀測,運維能夠面向服務,并且是聲明式的。
第四個階段:持續傳遞和人工輔助自運維
我們進一步讓開發同學專注于業務開發,首先在應用架構上開始大量采用無服務架構,并做到無人值守的持續部署;釋出的灰階和復原,能夠在有幹預的情況下盡量的自動化。觀測能力從應用級别提升到業務級别,實作業務的可觀測性,并且能夠在人工輔助的情況下做到部分的自運維。
第五個階段:全鍊路持續傳遞和自運維
這是我們追尋的終極目标。這個階段我們所有的應用和基礎設施采用的都是無服務架構,并做到端到端的無人值守持續傳遞,包括釋出的復原和灰階也是自動化的;技術設施和服務完全實作自運維。開發者真正隻需要關心業務的開發和疊代。
但是,魔鬼都在細節處,當然我們真正的落地的時候仍有很多的問題需要我們去解決,借助雲效這樣的工具平台和ALPD的專家咨詢,可以讓我們少走彎路,更快的實作目标。