為 Serverless Devs 插上 Terraform 的翅膀,實現企業級多環境部署(上)

語言: CN / TW / HK

簡介: Serverless Devs 離不開對雲資源的操作,但支援新資源時需要開發相應的元件程式碼;​如果將環境模板的定義通過 Terraform IaC 來完成,在 Serverless Devs 的體系內不僅能良好地銜接,還能夠極大拓寬使用者領域;​使用者可以通過編寫 Terraform 檔案來定義自己的基礎設施,用 Serverless Devs 完成所有工作流的串聯。​

前言

隨著現代化應用的普及和企業上雲的深入,專案中會涉及越來越多的雲資源使用。企業上雲過程中,往往會有平臺(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點:

  1. 要為不同的環境維護不同的 s.yaml,維護成本比較高。更新環境時需要重新發起部署,對接 CI/CD 服務時就要重新發起一次完整的釋出上線操作。(但通常情況下環境的變化,例如升降配、更新許可權,對程式來說是安全的,不需要發起一次上線);
  2. 難以實現基礎設施團隊、平臺團隊、研發團隊分層協作的場景。比如阿里雲函式計算的服務描述提供了日誌、網路、NAS、服務角色等平臺管理員視角的配置。收到客戶反饋,這些配置是幹嘛的研發基本都不清楚,無疑減低了研發效率並增加了安全風險,經常出現研發改錯配置導致線上服務有損的情況;
  3. Serverless Devs 的資源操作主要由元件來實現,但對於一些資源的變更可能會引起例項重建或者不能提供服務(比如更改資料庫引擎、更換了FC的服務角色、更換VPC)的風險,元件開發者未必會清楚也可能會忽略,即使清楚也需要 Case By Case 的通過很多判斷程式碼來解決,這無疑增加了元件開發的複雜度和使用成本;

如果採用本文前言章節中描述的分層的模板化方案,以上問題就可以順利解決:

  1. 平臺團隊通過封裝環境模板,僅需對研發人員暴露安全的引數(比如例項規格),研發人員使用模板建立環境,填寫必要的引數即可完成基礎設施的搭建;通過更新環境即可自助化地完成基礎設施的升級,並且不需要重新發起

    程式碼釋出操作; 2. 平臺團隊在環境模板中宣告更加嚴格的訪問策略,拒絕某些有風險的資源操作,可以更好地控制爆炸半徑;

那麼,接下來的問題就是:如何在 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 命令,可以實現如下的工作流:

  1. 通過基礎設施即程式碼(IaC)的能力定義可複用的環境模板
  2. 基於模板構建不同的測試、預發、生產等互相隔離的環境,並自動完成基礎設施的搭建
  3. 將函式的同一份程式碼部署到不同的環境上

下面我們通過一個實際案例演示整個操作流程。

假設業務場景需要:

  • 在函式中讀寫OSS檔案
  • 日誌檔案寫入NAS,前端做實時展現
  • 函式日誌寫入SLS,做系統分析

作為平臺管理員,需要為研發:

  • 建立 OSS Bucket,Bucket 名字研發可以自己指定,但是ACL策略必須是私有
  • 建立 NAS 掛載點,涉及的VPC、VSwitch、NAS檔案系統、訪問組、掛載點完全由管理員指定
  • 建立SLS Project 、Logstore,名字研發可以自己指定,但是自動分裂、最大分裂數完全由管理員指定

01 平臺管理員:開發環境模板

環境模板採用 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 這些常用的讀許可權。

完整程式碼示例https://github.com/devsapp/fc/blob/main/examples/multi-envs/infra/policy.json

02 平臺管理員:釋出環境模板

通過 s env apply-template 釋出環境模板

s env apply-template --name testing --description 'it is a demo' --code ./infra

引數含義如下:

引數全稱

是否必填

引數含義

name

True

環境模板名字

description

False

環境模板描述

code

False

模板程式碼目錄

操作成功後,會返回當前模板的 varibaleoutputs狀態policy文字內容版本 等資訊。

03 研發:使用環境模板建立環境

環境需要操作對應雲資源的許可權,

授予函式計算以角色扮演的方式訪問的雲資源,因此需要:

  1. 建立普通的服務角色,授信服務選擇函式計算
  2. 為該角色授予環境所需要的許可權

通過 s env init 命令進入互動式操作,輸入環境名、地域、角色、環境模板以及模板引數,完成環境的部署:

執行成功後,會在本地 .s 目錄下建立 env/fc-env-testing.yaml 描述檔案,可以檢視並編輯該檔案。

04 研發:部署函式到指定環境

開發人員編寫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:https://www.pulumi.com/

Terraform:https://www.terraform.io/

RAM:https://www.aliyun.com/product/ram?spm

阿里雲函式計算(FC):https://www.aliyun.com/product/fc?

原文連結:http://click.aliyun.com/m/1000347184/

本文為阿里雲原創內容,未經允許不得轉載。