作者:封崇
前言
隨着現代化應用的普及和企業上雲的深入,項目中會涉及越來越多的雲資源使用。企業上雲過程中,往往會有平臺(Platform)團隊和基礎設施(Infra)團隊:平臺團隊關注業務,根據業務場景進行抽象,對研發人員屏蔽基礎設施;基礎設施團隊關注安全及成本,爲平臺團隊規劃了不同的子賬號、權限策略以及網絡配置。這種分層管理的必然結果導致應用和基礎設施的生命週期會完全不同,因此基礎設施管理員、平臺管理員、研發人員關注的雲資源視角也不盡相同。比如:
-
基礎設施管理員管理整家企業的雲賬號,規劃企業的網絡配置,併爲各個平臺團隊設置不同子賬號以及訪問策略;
-
平臺管理員持有子賬號,根據容災及高可用場景劃分地域、安全、流量策略;根據業務場景規劃日誌、存儲、數據庫的規格、備份配置、Quota 等;根據研發流程要求規劃 CI/CD 流水線;
-
研發人員在使用平臺過程中,僅需關注代碼、數據、配置等程序相關內容:
-
- 當需要訪問數據庫時,向平臺索要數據連接串;
- 當需進行日誌採集時,將採集路徑提交給平臺,由平臺操作日誌服務完成日誌採集配置掛載;
- 當需要使用持久化存儲時,將本地掛載路徑提交給平臺,由平臺操作存儲服務完成文件目錄掛載;
- 發佈代碼,自動觸發 CI/CD 流水線的執行;
因此,隨着職責邊界的不同,平臺團隊面臨着更大的挑戰,既要面向研發人員消化業務,又要面向基礎設施團隊解釋雲產品的使用,無疑增加了很多溝通成本,降低了業務的迭代效率。如果能建立一種自動化的管道,讓不同團隊自助化地完成各自的邊界,勢必會極大地提升生產力。這需要幾個很重要的概念來連接 Dev 和 Ops:
-
服務:對代碼、程序的描述,只描述跟程序相關的信息,比如函數配置、日誌採集路徑
-
- 對於函數型應用,服務一般描述一個函數
- 對於容器化應用, 服務一般描述一個 Workload
-
環境:服務運行在不同的環境上,環境是服務運行的載體,描述了基礎設施(如網絡、集羣、存儲)的配置,以及應用運行時的運維配置(如彈性伸縮、資源規格)
-
流水線:對 CI/CD 的描述,完成代碼到服務的構建,並將服務部署到所有的環境上
-
應用:一組服務、環境、流水線所有資源的集合
要實現高效的自助化操作,合理化的方案是將上述概念進行模板化,並使用如下的工作流來完成:
- 平臺管理員將網絡、日誌服務、存儲、數據庫等基礎設施資源根據測試/生產隔離的要求,封裝成環境模板;將阿里雲函數計算(FC)的函數、Serverless 應用引擎(SAE )應用這些研發關注的業務資源封裝成服務模板;將 CI/CD 的基礎流程封裝成流水線模板;
- 基礎設施管理員審覈模板,通過後爲平臺管理員分配對應的子賬號;
- 平臺管理員持有子賬號選擇環境模板創建不同的測試、預發、生產環境,然後授予研發子賬號訪問權限,或者授予研發寫權限來自助創建環境;
- 研發人員選擇服務模板以及關聯的環境來創建服務,實現將應用程序自動部署到指定的環境上;
- 研發人員選擇流水線模板,通過主動觸發或者代碼提交自動觸發 CI/CD 的執行。
通過這種分邊界的模板化處理方式,可以讓企業不同的團隊自助完成基礎設施的搭建,提高生產效率的同時,又保證了權限隔離,讓基礎設施受到保護。
Serverless Devs 支持多環境所面臨的挑戰
Serverless Devs [1]是一款面向 Serverless 應用全生命週期的管理工具,其模型規範中存在應用和服務的概念,但目前缺少對環境的內在支持,代碼+基礎設施共同維護在一個 s.yaml 下。這種模式在多環境時的限制主要有 3 點:
- 要爲不同的環境維護不同的 s.yaml,維護成本比較高。更新環境時需要重新發起部署,對接 CI/CD 服務時就要重新發起一次完整的發佈上線操作。(但通常情況下環境的變化,例如升降配、更新權限,對程序來說是安全的,不需要發起一次上線);
- 難以實現基礎設施團隊、平臺團隊、研發團隊分層協作的場景。比如阿里雲函數計算的服務描述提供了日誌、網絡、NAS、服務角色等平臺管理員視角的配置。收到客戶反饋,這些配置是幹嘛的研發基本都不清楚,無疑減低了研發效率並增加了安全風險,經常出現研發改錯配置導致線上服務有損的情況;
- Serverless Devs 的資源操作主要由組件來實現,但對於一些資源的變更可能會引起實例重建或者不能提供服務(比如更改數據庫引擎、更換了 FC 的服務角色、更換VPC)的風險,組件開發者未必會清楚也可能會忽略,即使清楚也需要 Case By Case 的通過很多判斷代碼來解決,這無疑增加了組件開發的複雜度和使用成本;\
如果採用本文前言章節中描述的分層的模板化方案,以上問題就可以順利解決:
- 平臺團隊通過封裝環境模板,僅需對研發人員暴露安全的參數(比如實例規格),研發人員使用模板創建環境,填寫必要的參數即可完成基礎設施的搭建;通過更新環境即可自助化地完成基礎設施的升級,並且不需要重新發起代碼發佈操作;
- 平臺團隊在環境模板中聲明更加嚴格的訪問策略,拒絕某些有風險的資源操作,可以更好地控制爆炸半徑;
那麼,接下來的問題就是:如何在 Serverless Devs 中定義環境模板?
當 Serverless Devs 遇見 Terraform
環境模板面向的是基礎設施,也就是雲資源。Serverless Devs 離不開對雲資源的操作,傳統的做法是在組件中直接使用雲產品 SDK,但支持新資源時需要開發相應的組件代碼,因此面臨着資源擴張帶來的開發效率降低以及代碼越來越難以維護的問題,更好的方式是通過基礎設施即代碼(IaC)來完成雲資源的創建。
Serverless Devs 在之前的實踐中採用 Pulumi ,通過一個單獨組件完成對 Pulumi Stack 的封裝,但實踐下來發現,用 GPLs 來定義 IaC 還是需要模型層面良好的抽象,因此將 Pulumi 推廣到組件開發者,在生態成熟度以及靈活性上都不是太好。目前 IaC 生態最強大的工具是 Terraform,已成爲事實標準。Terraform HCL 本身是一種 DSL,任何生態都能很好地兼容,特別是 Provider 極其豐富。
阿里雲的雲產品如果對接 POP,能夠自動生成 Terraform 的 Provider,其可靠性和接入便捷程度已經相當之高。如果將環境模板的定義通過 Terraform IaC 來完成,並且在 Serverless Devs 的體系內能夠良好地銜接,這樣可以極大拓寬用戶領域,用戶可以通過編寫 Terraform 文件來定義自己的基礎設施,用 Serverless Devs 完成所有工作流的串聯。
操作案例
遵循 Serverless Devs 的組件開發規範,將多環境的操作封裝成 env 命令,通過利用 s env 命令,可以實現如下的工作流:
- 通過基礎設施即代碼(IaC)的能力定義可複用的環境模板
- 基於模板構建不同的測試、預發、生產等互相隔離的環境,並自動完成基礎設施的搭建
- 將函數的同一份代碼部署到不同的環境上
下面我們通過一個實際案例演示整個操作流程。假設業務場景需要:
- 在函數中讀寫 OSS 文件
- 日誌文件寫入 NAS,前端做實時展現
- 函數日誌寫入 SLS,做系統分析
作爲平臺管理員,需要爲研發:
- 創建 OSS Bucket,Bucket 名字研發可以自己指定,但是 ACL 策略必須是私有
- 創建 NAS 掛載點,涉及的VPC、VSwitch、NAS 文件系統、訪問組、掛載點完全由管理員指定
- 創建 SLS Project 、Logstore,名字研發可以自己指定,但是自動分裂、最大分裂數完全由管理員指定
平臺管理員:開發環境模板
環境模板採用 IaC 來定義資源,目前只支持 Terraform 類型的模板。環境模板的代碼目錄要包含兩類文件:
-
IaC 文件:即 Terraform 的 .tf 文件,IaC 文件的核心要素爲:
-
- variable:定義模板的參數,用戶使用該模板創建環境時輸入參數的值
- resource:定義模板的資源,環境部署時完成資源的創建
- output:定義模板的輸出,環境部署成功後透出相應輸出,可以被其他服務所訪問
- policy.json:RAM 的權限策略數組,支持自定義策略和系統策略,聲明瞭使用該模板創建資源所需要的權限,授信對象是 函數計算。部署環境時,函數計算會通過角色扮演的方式訪問模板中定義的資源。
編寫 IaC,定義環境模板的 variable、resource、output。完整代碼示例:
https://github.com/devsapp/fc/blob/main/examples/multi-envs/infra/main.tf
爲上述資源定義權限策略,保持權限最小原則,僅放開必要的寫權限。由於 Terraform 在創建資源時會依賴很多資源的讀權限,因此推薦再增加這些常用的讀權限:
-
AliyunECSReadOnlyAccess
-
AliyunVPCReadOnlyAccess
-
AliyunNASReadOnlyAccess
-
AliyunOSSReadOnlyAccess
-
AliyunLogReadOnlyAccess
完整代碼示例:
https://github.com/devsapp/fc/blob/main/examples/multi-envs/infra/policy.json
平臺管理員:發佈環境模板
通過 s env apply-template 發佈環境模板
s env apply-template --name testing --description 'it is a demo' --code ./infra
參數含義如下:
操作成功後,會返回當前模板的 varibale、outputs、狀態、 policy、文本內容、版本 等信息。
研發:使用環境模板創建環境
環境需要操作對應雲資源的權限,授予函數計算以角色扮演的方式訪問的雲資源,因此需要:
- 創建普通的服務角色,授信服務選擇函數計算
- 爲該角色授予環境所需要的權限
通過 s env init 命令進入交互式操作,輸入環境名、地域、角色、環境模板以及模板參數,完成環境的部署:
點擊查看操作視頻:
https://developer.aliyun.com/live/249417
執行成功後,會在本地 .s 目錄下創建 env/fc-env-testing.yaml 描述文件,可以查看並編輯該文件。
研發:部署函數到指定環境
開發人員編寫 s.yaml,並將基礎設施配置關聯到指定環境。可以通過如下方式:
- 通過 environment.outputs 來關聯環境模板中定義的輸出
- FC 的服務往往和一個環境相映射,通常在創建服務時服務名要帶上環境的後綴,可以通過 environment.name 讓服務和環境自動關聯
- 指定環境時,無需在 props 中指定 region,組件會自動保證將服務部署到環境所在的 region
通過 s deploy --env 將函數部署到指定的環境中。
s deploy --env fc-env-testing
執行指令後,組件會先判斷環境是否已經部署,如果環境狀態爲 ready ,則會將服務部署到該環境上;否則會先部署環境,再部署服務。
總結
本文通過分析企業全面上雲時,遇到的應用和基礎設施管理的挑戰,提出採用分層的模板化方式來組織不同團隊的工作流,通過環境、服務、流水線來定義一個現代化的應用,通過環境模板、服務模板、流水線模板來屏蔽基礎設施的複雜性並提升操作安全性,核心是需要一個管道來串聯整個工作流,讓 DevOps 的各個階段可以自助化並安全的完成。作者希望 Serverless Devs 可以充當這個管道,其應用、組件、插件的思路爲開發者提供了良好的構建現代化應用的基礎,並且 Serverless Devs 已經具備了服務及服務模板的抽象,需要擴展的是環境、流水線的能力。
本文關注點是如何利用 Serverless Devs 管理多環境,分析了關鍵的挑戰是要解耦代碼和基礎設施,利用 IaC 來完成基礎設施的定義,而 IaC 生態下最適合引入的是 Terraform,因此選擇用 Terraform HCL 來定義環境模板,環境的資源編排通過後端的 Terraform 服務來完成。這樣就可以通過 Serverless Devs 來完成 "發佈環境模板" -> "部署環境" -> "部署應用到指定環境" 的完整工作流。
當然,要實現上述終態的願景還有很長的路要走,未來規劃主要的 Roadmap 是:
- 持續打磨體驗,輸出更多開箱即用的模板
- 解決應用運行時訪問環境的問題,比如在函數代碼中通過某種方式安全、高效地訪問環境的資源
- 輸出流水線模板、流水線的能力
本篇介紹了 Serverless Devs 多環境功能的使用,在下一篇中我會就一些常見問題,進行詳細解讀。
參考鏈接:
Serverless Devs:
https://www.serverless-devs.com/
Pulumi:
Terraform:
RAM:
https://www.aliyun.com/product/ram?spm
阿里雲函數計算(FC):
https://www.aliyun.com/product/fc
本場景基於 Serverless 應用中心 + 阿里雲函數計算 + 開源企業級在線文件管理系統 KodBox 打造,讓你僅用 “幾次” 點擊,即可擁有一個可隨意保存資源、不限速下載、多端使用、與朋友共享資源……的專屬個人網盤。
自建真網盤:https://developer.aliyun.com/adc/series/activity/serverlessapp
點擊此處,1 分鐘 Serverless 極速部署個人網盤!