作者 | 元吟
來源 | 阿裡技術公衆号
一 背景
2018年7月9日,我通過校招加入阿裡雲,開啟了職業生涯。有幸參與了資源編排服務從1.0到2.0的全部設計、開發、測試工作,這對我了解雲上服務起到了啟蒙作用。當然,本文源于我在設計開發過程中的思考和感悟。
在傳統軟體架構下,撇開業務層代碼,都需要部署計算節點、存儲資源、網絡資源,然後安裝、配置作業系統等。而雲服務本質上是實作 IT 架構軟體化和 IT 平台智能化,通過軟體的形式定義這些硬體資源,充分抽象并封裝其操作接口,任何資源均可直接調用相關 API 完成建立、删除、修改、查詢等操作。
有賴于阿裡雲對資源的充分抽象以及高度統一的OpenAPI,這讓基于阿裡雲建構一套完整的 IT 架構并對各資源進行生命周期管理成為可能。客戶按需求提供資源模闆,編排服務将會根據編排邏輯自動完成所有資源的建立和配置。
二 架構設計
伴随着業務場景的增加和業務規模的指數級增長,原有架構逐漸暴露出租戶隔離粒度大、并發量小、服務依賴嚴重等問題,對于服務架構的重構迫在眉睫,其中最重要三個方面就是拓撲設計、并發模型設計和工作流設計。
1 拓撲設計
拓撲設計的核心問題是明确産品形态和使用者需求、解決資料通路問題。站在産品角度考慮的點包括: 1. 資源所有者(服務資源[計費單元]、使用者資源)、2. 資源通路權限(隔離、授權)。站在使用者角度需要考慮的點包括: 1. 服務類型(WebService型-需公網通路、資料計算型-阿裡雲内網通路)、2. 資料打通(源資料、目的資料)。
資源所有者分為服務賬号和使用者賬号。資源屬于服務賬号的模式又叫做大賬号模式,該模式優點有: 1. 管控能力更強;2.計費更容易。但易成為瓶頸的點包括:1.資源配額;2. 依賴服務的接口流控。很顯然,全量資源托管是不現實的,比如VPC、VSwitch、SLB、SecurityGroup等資源客戶往往需要和其他系統打通,這部分資源通常是使用者提供的,而ECS執行個體則比較适合通過大賬号建立。
多租戶隔離在大賬号模式下是非常重要的問題。既要保證某一使用者的資源彼此可以互相通路,又要保證多個客戶之間不能有越界行為。一個常見的例子是,所有使用者的ECS均開在同一個服務VPC内,同一個VPC内執行個體預設是可以互相通路的,存在安全風險,是以在系統設計初期就需要考慮到相關問題的應對方案。
對于上述問題我們的設計是,ECS執行個體通過大賬号模式建立在服務賬号下的資源VPC内, 通過企業級安全組實作不同使用者執行個體的通路隔離。涉及使用者資料(NAS、RDS等)通路的操作時,需要使用者提供這些通路點所在的VPC和Vswitch,通過在執行個體上建立ENI并綁定到使用者VPC上,實作對使用者資料的通路。具體資料通路如圖所示。
常見的服務架構
2 并發模型設計
模型設計的核心是解決高并發(High Concurrency)、高性能(High Performance)、高可用(High Availability)問題。
資源編排的高并發主要名額為QPS(Queries-per-second),對于動辄以分鐘為機關的資源編排邏輯而言,同步模型顯然不能支撐較高并發請求。資源編排的高性能主要名額為TPS(Transactions-per-second),在根據使用者資源模闆編排資源的過程中,資源彼此間存在一定的依賴關系,線性地建立資源會導緻大量時間處于忙等狀态,服務吞吐嚴重受限。資源編排的高可用主要名額為SLA(Service Level Agreement),在HA基礎上若能解耦CRUD對内部服務的依賴,在服務更新或發生異常時就可以減小對SLA的影響。
對于上述問題我們的設計是,在服務前端僅進行簡單的參數檢查後立即将使用者模闆寫入持久化層,寫入成功後立即傳回資源ID,已持久化的資源模闆将被視為未處理完成的任務等待排程處理。随後,我們周期性掃表探測任務,有序建立資源并同步其狀态,如遇資源狀态不滿足向下推進的條件則立即傳回,經過多輪次處理,最終達到期望的狀态, 一個簡化的分布式模型如圖所示。
分布式并發模型
為了避免任務較多情況下的鎖争搶問題,我們設計一套任務發現 + 租約續租的機制,一旦叢集從資料庫池子中被某個節點争搶到之後會被添加到該節點的排程池中并設定租約, 租約管理系統會對即将到期的租約進行續租(加鎖)。這樣可以確定一個叢集在下一次服務被拉起前一直隻被某個節點處理,如果服務重新開機,則任務會因逾時自動解鎖并被其他節點捕獲。
3 工作流設計
流程設計的核心是解決依賴問題。依賴問題包含兩種情況:前序資源的狀态不符合預期和資源本身狀态不符合預期。我們假設各資源的狀态隻有可用和不可用,并且假定可用的資源不會跳轉到不可用狀态,最簡單的情況就是一個線性任務,如圖所示。考慮到部分子資源的編排工作可以并行,編排過程就可以看作是一個有向無環圖( DAG, Direct Acyclic Graph)任務。
資源線性編排結構
世界不隻是非黑即白,資源的狀态也是一樣,有向無環成為了美好的願望,有向有環才符合真實世界的運作規律。對于這種情況,簡單的工作流很難覆寫複雜的流程,隻有進一步對工作流抽象,設計符合要求的有限狀态機(FSM, Finite State Machine)。有限狀态機說起來過于抽象,但ECS執行個體的狀态轉移大家都接觸過,下圖就是ECS執行個體的狀态轉移模型。
ECS執行個體狀态轉移模型
結合實際業務需求,我設計了如下圖所示的叢集狀态轉移模型。該模型簡化了狀态轉移邏輯,有且僅有Running這一穩态,其他三種狀态(Rolling、Deleting、Error)均為中間态。處于中間态的資源會根據目前資源狀态嘗試向着穩态越遷,每次狀态越遷過程均按照一定的Workflow執行相關操作。
叢集狀态轉移模型
從這時起,服務的整體架構和設計思路基本确立。
三 核心競争力
資源(ECS)短缺問題日益嚴峻,加上粗粒度的擴縮容、升降配功能已不能滿足客戶的需求,資源池化(Resource Pooling)、自動伸縮(Auto Scaling)、滾動更新(Rolling Update)被提上日程并成為提升産品競争力的一大利器。
1 資源池化
資源池化簡單來說就是提前預留某些資源以備不時之需,很顯然,資源池化的前提一定是大賬号模式。對開發者而言,線程池不是陌生的詞彙,但資源池卻相對比較遙遠,實際上,資源池解決的就是資源建立、删除時間開銷很大以及庫存不可控的問題。當然, 池化資源另一個假設是,被池化的資源會被頻繁使用且可被回收利用(規格、配置相對單一)。
由于計算資源建立周期較長且經常被資源庫存等問題困擾,加之産品期望在業務上有所拓展,是以我們設計了如圖所示的資源池化模型并對多種計算資源進行抽象,提供了一套可以應對異構資源的處理邏輯。
資源池化模型
資源池化可以大大縮短資源建立等待時間,解決庫存不足問題,另外,它可以幫上層使用到資源的服務解耦複雜的狀态轉移邏輯,對外提供的資源狀态可以精簡到Available和Unknown兩種,所得即可用。但不得不考慮的問題包括:
- ECS執行個體的建立是否受使用者資源的限制(如使用者提供VSwitch會限制ECS可用區)。
- 如何解決資源閑置問題(成本問題)。
對于第一個問題,目前受制于VSwitch由客戶提供,暫時還沒有比較好的解法,隻能盡量要求客戶提供的VSwitch覆寫更多的可用區,如果VSwitch屬于服務賬号,就可以比較好規劃資源池建在哪個AZ。對于第二個問題,資源池本身也是一種資源,成本控制我們可以從接下來提到的自動伸縮上得到答案。
2 自動伸縮
雲計算最大的吸引力就是降低成本,對資源而言,最大的好處就是可以按量付費。實際上,幾乎所有線上服務都有其峰谷,而自動伸縮解決的正是成本控制問題。它在客戶業務增長時增加ECS執行個體以保證算力,業務下降時減少ECS執行個體以節約成本,如圖所示。
自動伸縮示意圖
我對自動伸縮的設計思路是,先對時間分片觸發定時任務,再對時間段内配置伸縮政策。伸縮政策也包含兩部分,一部分是最大ECS規模和最小ECS規模,它指定了該時間段内叢集規模的浮動範圍,另一部分是監控名額、耐受度和步進規則,它提供了伸縮依據和标準。這裡監控名額是比較有意思的點,除了采集雲監控的CPU、Memory使用率外,還可以通過對ECS空閑、忙碌狀态的标記,計算出工作節點占比率,一旦超出耐受範圍,即可按步進大小觸發一次擴容或縮容事件。
3 滾動更新
客戶服務架構的修改往往涉及複雜的重建邏輯,在重建過程中不可避免的會影響服務品質,如何優雅平滑地做升降配成為了諸多客戶的剛需。滾動更新正是解決不停服、可調控的升降配問題的。
滾動更新示意圖
一次簡化的滾動更新過程如上圖所示。滾動更新的核心是對更新進行灰階,按照一定比例開出Standby資源直到它們可以順利服役,随後再下線掉相應台數的資源。經過多次滾動之後,使其全部資源更新到最新預期,通過備援實作更新不停服。
四 可觀測性
服務可觀測性将來必将成為雲服務的核心競争力之一,它包括面向使用者的可觀測行和面向開發者的可觀測性兩部分。時至今日,仍然記得半夜被客戶電話支配的恐懼,仍記得對着海量日志調查問題的不知所措,仍記得客戶一通抱怨後毫無頭緒的茫然。
1 面向使用者
是的,我希望使用者在向我們回報遇到的問題時,提供的資訊是有效的,甚至是能直接指向病竈的。對使用者而言,能夠直接通過API擷取資源編排所處的階段以及各階段對應資源的狀态資訊,确實能夠極大地提高使用者體驗。針對這個問題,我分析了系統處理流程, 設計了面向“階段 - 事件 - 狀态”的運作狀态收集器。
具體包括:對的業務流程進行拆分得到多個處理階段,對每個階段依賴的事件(資源及其狀态)進行整理,對每個事件可能出現的狀态做結構化定義(尤其是異常狀态)。一個典型的樣例如代碼樣例所示。
[
{
"Condition":"Launched",
"Status":"True",
"LastTransitionTime":"2021-06-17T18:08:30.559586077+08:00",
"LastProbeTime":"2021-06-18T14:35:30.574196182+08:00"
},
{
"Condition":"Authenticated",
"Status":"True",
"LastTransitionTime":"2021-06-17T18:08:30.941994575+08:00",
"LastProbeTime":"2021-06-18T14:35:30.592222594+08:00"
},
{
"Condition":"Timed",
"Status":"True",
"LastTransitionTime":"2021-06-17T18:08:30.944626198+08:00",
"LastProbeTime":"2021-06-18T14:35:30.599628262+08:00"
},
{
"Condition":"Tracked",
"Status":"True",
"LastTransitionTime":"2021-06-17T18:08:30.947530873+08:00",
"LastProbeTime":"2021-06-18T14:35:30.608807786+08:00"
},
{
"Condition":"Allocated",
"Status":"True",
"LastTransitionTime":"2021-06-17T18:08:30.952310811+08:00",
"LastProbeTime":"2021-06-18T14:35:30.618390582+08:00"
},
{
"Condition":"Managed",
"Status":"True",
"LastTransitionTime":"2021-06-18T10:09:00.611588546+08:00",
"LastProbeTime":"2021-06-18T14:35:30.627946404+08:00"
},
{
"Condition":"Scaled",
"Status":"False",
"LastTransitionTime":"2021-06-18T10:09:00.7172905+08:00",
"LastProbeTime":"2021-06-18T14:35:30.74967891+08:00",
"Errors":[
{
"Action":"ScaleCluster",
"Code":"SystemError",
"Message":"cls-13LJYthRjnrdOYMBug0I54kpXum : destroy worker failed",
"Repeat":534
}
]
}
]
代碼樣例:叢集次元狀态收集
2 面向開發者
對開發者而言,可觀測性包含監控和日志兩部分,監控可以幫助開發者檢視系統的運作狀态,而日志可以協助問題的排查和診斷。産品從基礎設施、容器服務、服務本身、客戶業務四個次元進行了監控和資料聚合,具體用到的元件如圖所示。
各級别監控、告警體系
基礎設施主要依托雲監控(Cloud Monitor)追蹤CPU、Memory等使用率;容器服務主要依賴普羅米修斯(Prometheus)監控部署服務的K8S叢集情況。對服務本身,我們在各個運作階段都接入了Trace用于故障定位;對最難處理的客戶業務部分,我們按通過SLS收集客戶使用情況,通過UserId和ProjectId進行資料聚合,并整理出普羅米修斯的DashBoard,可以快速分析某個使用者的使用情況。
除監控外,已接入雲監控告警、普羅米修斯告警和SLS告警,系統、業務分别設定不同告警優先級,并整理了豐富的應急響應方案。
五 其他
從懵懂到能夠獨立負責資源編排服務的設計、開發工作,阿裡雲提供了寶貴的學習平台。如今秋招大幕已經拉開,歡迎應屆同學加入我們,履歷請投遞郵箱: [email protected]. 此時此刻,非你莫屬。
技術公開課
虛拟化技術入門
本課程共7個課時,主要講解雲計算技術的核心技術之一——虛拟化技術,介紹說明虛拟化技術的主要作用以及常見實作方法,并針對硬體中常用的虛拟化技術(CPU、記憶體、IO)進行詳細的講解,最後針對目前流行的開源虛拟化項目,講解其出現的漏洞以及阿裡雲是如何進行漏洞分析和處理的。
點選這裡,快去學習吧~