企業上云是近些年的發展熱潮,越來越多的企業把自己的應用部署在各個云廠商中,利用云計算帶來的彈性、靈活、安全、低成本等特性,輕松幫助企業搭建自己的應用,
隨著企業規模和業務形態的發展,一個應用需要組合多種云資源才能對外提供服務,為了便于研發人員開發除錯,每種應用都需要部署到多套環境,單純通過人工手動管理云資源的方式會使得基礎設施管理人員的負擔不斷加重,
因此越來越多的企業選擇使用代碼(而非手動流程)來定義基礎設施,即 IaC(Infrastructure as Code),像對待應用軟體一樣對待基礎設施,這樣不僅能夠免去繁雜的人工操作還可以利用代碼配置原生帶來的版本化和抽象化等能力,
在云計算的時代下,應用的部署往往會依賴多個基礎設施(計算、存盤、網路),企業內部往往需要一個 PaaS 平臺來交付自己的應用,但是 PaaS 平臺的開發和維護需要企業有較大的技術和人力投入,對于快速發展的企業更希望能夠把精力專注于企業的核心業務,
阿里云 Serverless 應用引擎 SAE(Serverless App Engine)是一個面向應用的 Serverless PaaS 平臺,天然支持通過 IaC 的方式來創建和管理,而 Terraform 作為 IaC 領域的事實標準,已成為了企業 IaC 管理的首選工具,將 Terraform 和 SAE 組合會發生一些奇妙的化學反應,企業可以以一種 ADaC(Application Deploy as Code)的方式,通過簡單的代碼組態檔管理企業的應用,
下面,我們簡單的介紹 IaC 和 SAE 給企業帶來的巨大便利,并通過一個使用 Terraform 創建 SAE 應用的例子感受 SAE & Terraform 給傳統企業 IT 設施管理帶來的降維打擊,
基礎設施即代碼
企業基礎設施管理發展歷程
應用能夠正常對外服務需要依賴計算、存盤、網路等基礎資源,他們是應用正常運行的基礎背景關系,這些資源也稱為環境基礎設施,在傳統的管理模式下,大多數公司都會有專門的運維團隊來管理自己的正式生產和測驗環境,隨著業務的升級和公司規模的增長,運維團隊在基礎資源管理上會經歷大概 3 個階段:
- 手工運維:在企業發展初期,企業的業務種類和規模都處于起步階段,而且基礎環境屬于變更頻率相對很低的資源,運維團隊往往通過人工管理就可以搭建起服務所需的基礎資源,使用云服務的企業在云廠商的控制臺通過滑鼠操作就可以完成云資源的創建,這一階段研發人員基礎設施需求很低,運維人員通過手工運維就能滿足,
- 運維操作腳本化:伴隨企業規模和業務的發展,運維團隊會接收到越來越多的環境創建請求,大部分運維團隊的成員為了提升環境創建效率會自發的撰寫規范化的檔案和腳本,或者通過 CLI 來輔助資源的創建,但是因為一個服務往往需要多種基礎設施資源配合才能正常對外提供服務,腳本還無法簡單的處理不同基礎設施之間的依賴關系,這一段運維人員創建環境會逐步變成一個繁瑣且低效的作業,
- 基礎設施即代碼:手工運維和檔案腳本化已經極大的影響開發效率,企業會逐步把基礎設施抽象成代碼,用管理代碼的方式配置基礎設施,對環境基礎設施可以像對待代碼一樣進行版本控制和回滾,而且多個環境之間可以復用相同的代碼模塊,實作環境基礎設施的快速交付,
Terraform 應運而生
2014 年,HashiCorp 公司推出了產品 Terraform,它是一個可以安全、高效地建立,變更以及版本化管理基礎設施的工具,時至今日 Terraform 絕對是 IaC 領域的王者,使用 Terraform 管理企業基礎設施可以給企業帶來多種好處:
- 使用宣告式的 IaC 管理基礎設施:宣告式的描述能夠保證即使代碼執行多次也能達到一致的狀態,使用代碼來描述基礎資源,能夠更加形象直接的展示出不同環境之間的差異,不論什么環境出現問題,都能快速的復刻出一個新的環境,
- 豐富的 modules 生態:幾乎包含所有云廠商的云資源,使用者可以在官方維護的模塊倉庫 Terraform Registry 中使用各種官方和社區提供的高質量模塊,讓使用者不用再重復撰寫其他云廠商的模塊,利用開源社區的能力,不斷完善和壯大 Terraform 生態,
- 資源依賴管理:Terraform 會根據模板中的定義,構建所有資源的 DAG 拓撲關系圖,對于有依萊澩的資源,會根據依賴關系有序執行,對于沒有任何依賴關系的資源會以并行的方式創建以保證執行的高效性,
云計算時代下的企業應用部署
應用的部署往往會涉及到 VPC 網路管理和劃分,虛擬機的創建,通過負載均衡暴露應用的服務地址,在微服務架構盛行的今天,企業還需要部署和運維一些微服務組件,以提供服務發現、配置管理、無損上下線等功能保證應用能夠提供穩定不斷流的服務,為了能夠監控應用的運行狀態,通過 Trace、Metrics、Logs 等資訊來了解應用健康狀態是必不可少的部分,
一個健康的應用需要組合一系列基礎設施的能力,每個應用的測驗和上線都會耗費研發和運維管理人員大量的精力,其實不難發現,每個應用的依萊澩都存在相似的地方,很多差異性只表現在一些配置項上,
如果一個產品能夠組合這些基礎設施的能力,對外提供應用的概念,研發人員只需要關心業務代碼的撰寫,運維管理人員也不需要管理和維護大量的基礎設施,企業研發效率會有極致的提升,
阿里云提供的 Serverless 應用引擎 SAE 就是這樣一個降低企業 IT 人員心智的產品,
SAE 是面向應用的 Serverless PaaS 平臺,能夠幫助 PaaS 層用戶免運維 IaaS、按需使用、按量計費,做到低門檻微服務應用上云,相對于其他 Serverless 產品,它將應用的概念抽象化,幫助企業屏蔽了大量的基礎設施的創建和管理,并提供了一整套微服務解決方案,支持 Spring Cloud、Dubbo、HSF 等主流的微服務開發框架,實作了 Serverless 架構和微服務架構的完美結合,
SAE 提供了保姆級的托管服務,研發人員只需要提供一個編譯好的 JAR 包或者 WAR 包,就能夠部署一個擁有全套微服務體驗的應用,基礎設施管理人員的也無需管理大量的基礎設施,
SAE & Terraform,應用即代碼
現在你可以通過 Terraform 來創建和管理 SAE 上的應用,結合 Terraform IaC 和 SAE 以應用為中心的能力,這樣企業就能將應用的全部配置代碼化,輕松描述和管理應用,當因為人為或者其他意外因素導致應用處于不健康或者不可用的狀態,我們可以快速的復刻出一個相同的應用來把影響最小化,
Terraform 通過宣告式的 HCL 語言來描述基礎設施,程式員告訴 Terraform 我期望獲取的資源狀態,剩下的事情就交由 Terraform 來創建即可,不過 Terraform 不關心創建出的應用的運行狀態,運行在 Terraform 創建出資源的服務的正常運行需要研發人員來保證,SAE 底層基于 Kubernetes,利用 Kubernetes 宣告式的能力,SAE 能夠保證應用服務一直保持宣告的狀態,正常的對外提供服務,Terraform 結合 SAE 更好的發揮了應用資源宣告式描述的能力,
下面,請跟上我們的步伐,一起來感受 IaC 的魅力,
準備作業
本節為你演示如何利用 Terraform 的 IaC 和依賴管理能力,快速拉起不同環境的應用以及組合 SAE 和其他云資源來構建你的應用,
開始之前,我們先把演示相關的代碼克隆到本地:
git clone [email protected]:yangsoon/terraform-sae.git
把創建云資源必要的 AK,SK 暴露到環境變數中,( Terraform 創建云資源的時候會使用環境變數中指定 AK 和 SK 創建云資源),
export ALICLOUD_ACCESS_KEY=(your access key id)
export ALICLOUD_SECRET_KEY=(your secret access key)
快速創建多環境應用
進入到專案的根目錄并簡單看下專案的目錄結構,modules 檔案夾包含了封裝好的環境基礎設施模塊,包括使用阿里云 SLB 實作負載均衡和外網訪問能力的 lb,提供專有網路的 network 模塊,webserver 模塊對阿里云 SAE 資源進行了進一步封裝,方便用戶在不同環境創建應用時,能夠直接復用,減少不必要的代碼拷貝,
stage 和 prod 分別存盤企業在預發環境和生產環境的資源配置,預發環境和生產環境的環境基礎設施存在較大的差異,并且生產環境的資源配置有更高的安全需求,為了防止誤操作導致生產環境的資源被損壞,我們通過檔案布局進行隔離,

打開 ./stage/webserver/main.tf 檔案,可以看到在預發環境我們指定使用 webserver 組件創建應用,
module "network" {
source = "../../modules/network"
vpc_name = var.vpc_name
}
module "webserver" {
source = "../../modules/webserver"
sg_id = module.network.SG_ID
vpc_id = module.network.VPC_ID
vswitch_id = module.network.VSWITCH_ID
app_name = var.app_name
image_url = var.image_url
namespace_name = var.namespace_name
namespace_id = var.namespace_id
}
在 ./stage/webserver/vars.tf 中填入預發環境對應的應用名稱和鏡像地址(這里以 nginx 為例),
variable "app_name" {
description = "The name of the application"
type = string
default = "webserver-stage"
}
variable "image_url" {
description = "The image of the application"
type = string
default = "nginx:stable"
}
下面,我們就利用 Terraform 快速構建一個預發環境.
- 進入到 ./stage/webserver 檔案夾,初始化 Terraform 作業區
cd terraform-sae/stage/webserver
terraform init
該步驟會幫你初始化 Terraform 子模塊已經安裝必要的插件,執行成功后顯示如下所示資訊

- 查看預發環境會創建出的資源型別和個數
terraform plan

執行 terraform plan 之后輸出內容較多,這里就截取了部分資訊,可以看到預發環境會創建 6 個資源,輸出結果會顯示新創建的資源的具體配置資訊,
- 確認無誤之后,我們開始創建預發環境所需的資源,
terraform apply

terraform apply 會再次為你展示本次執行會創建出的資源資訊,確認無誤之后,輸入 yes,這時候 Terraform 才會真正的為你創建資源,
這里稍等一段時間,等待資源創建完成,你可以登錄阿里云控制臺查看剛剛創建的應用,

等一系列除錯測驗驗證通過之后,可以繼續創建生產環境的資源,
打開 ./prod/webserver/main.tf 檔案,可以看到我們可以直接復用 webserver 模塊,并修改一些應用名稱和應用鏡像為生產環境相關的配置即可,除此之外,我們新建了一個 SLB,允許應用能夠被外界訪問,下面我們繼續創建生產環境的應用,
module "lb" {
source = "../../modules/lb"
slb_name = var.app_name
address_type = "internet"
vswitch_id = module.network.VSWITCH_ID
}
resource "alicloud_sae_load_balancer_internet" "example" {
app_id = module.webserver.app_id
internet_slb_id = module.lb.slb_id
internet {
protocol = "HTTP"
port = var.port
target_port = 80
}
}
module "webserver" {
source = "../../modules/webserver"
sg_id = module.network.SG_ID
vpc_id = module.network.VPC_ID
vswitch_id = module.network.VSWITCH_ID
app_name = var.app_name
image_url = var.image_url
namespace_name = var.namespace_name
namespace_id = var.namespace_id
}
修改./prod/webserver/vars.tf 中填入生產環境對應的應用名稱和鏡像地址等資訊,
進入到 ./prod/webserver 檔案夾,初始化 Terraform 作業區
cd terraform-sae/prod/webserver
terraform init
查看生產環境會創建出的資源型別和個數
terraform plan

這里生產環境會多創建 2 個和 SLB 相關的資源,
- 確認無誤之后,我們開始創建生產環境所需的資源,
terraform apply

等待一段時間后,我們創建了一個外網可以訪問的應用,輸出結果里包含了我們可以訪問的外網地址,請求該地址,可以看到一個 nginx 服務器已經搭建成功,

至此,我們利用 Terraform 的能力快速創建了多環境應用,
使用 Terraform 依賴管理能力高效組合 SAE 和其他云資源
SAE 在 Terraform 生態下還有更高階的玩法,你可以任意組合其他云資源,以 RDS 為例,你可以把 RDS 的一些連接資訊以環境變數的形式注入到 SAE 應用中,應用啟動之后可以通過環境變數的資訊連接到目標資料庫,
打開 ./prod/webserver-with-db/main.tf,我們引入了 mysql 模塊幫我們創建一個阿里云 RDS 實體,創建 RDS 之后的資料庫連接資訊,以環境變數的形式注入了 SAE 應用中,
module "mysql" {
source = "../../modules/mysql"
databases = [
{
"name" : "sae-demo",
"character_set" : "utf8",
"description" : "sae demo database"
},
]
rds_instance_name = var.rds_instance_name
rds_account_name = var.rds_account_name
rds_password = var.rds_password
}
module "webserver" {
source = "../../modules/webserver"
sg_id = module.network.SG_ID
vpc_id = module.network.VPC_ID
vswitch_id = module.network.VSWITCH_ID
app_name = var.app_name
image_url = var.image_url
namespace_name = var.namespace_name
namespace_id = var.namespace_id
envs = [{
name = "DB_HOST"
value = https://www.cnblogs.com/Serverless/archive/2022/09/26/module.mysql.DB_HOST
}, {
name ="DB_PORT"
value = https://www.cnblogs.com/Serverless/archive/2022/09/26/module.mysql.DB_PORT
}, {
name ="DB_PASSWORD"
value = https://www.cnblogs.com/Serverless/archive/2022/09/26/module.mysql.DB_PASSWORD
}, {
name ="DATABASE_NAME"
value = https://www.cnblogs.com/Serverless/archive/2022/09/26/module.mysql.DATABASE_NAME
}]
}
下面我們演示一下創建一個使用 RDS 作為資料存盤的應用,
和之前 2 個例子類似,我們進入到 terraform-sae/prod/webserver-with-db 目錄下,執行作業空間初始化作業,
cd terraform-sae/prod/webserver-with-dbterraform init
開始創建資源
terraform apply
資源創建完成之后,會輸出資料庫的公網范圍地址,

- 檢查 SAE 應用中的環境變數
可以看到創建出的 RDS 的連接資訊已經被配置到了環境變數中,

執行完 Demo 指令創建云資源后,為了避免不必要的扣費,記得及時銷毀創建的演示資源,
$ cd terraform-sae/stage/webserver && terraform destroy
$ cd terraform-sae/prod/webserver && terraform destroy
$ cd terraform-sae/prod/webserver-with-db && terraform destroy
總結
SAE 和 Terraform 的結合,能夠幫助企業像處理代碼一樣管理自己的應用,對資源的操作都變得可審計,可追溯,可回滾,同時也降低人為操作帶來的風險,而 SAE 將應用的概念抽象化,幫助企業屏蔽了大量的環境基礎設施的創建和管理,降低了用戶使用門檻,助力企業快速上云,
參考文獻
[1] Yevgeniy Brikman.《Terraform: Up & Running: Writing Infrastructure as Code》.O'Reilly Media
[2] 喬梁.《持續交付2.0》.人民郵電出版社
更多內容關注 Serverless 微信公眾號(ID:serverlessdevs),匯集 Serverless 技術最全內容,定期舉辦 Serverless 活動、直播,用戶最佳實踐,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/509611.html
標籤:其他
下一篇:《Vision Permutator: A Permutable MLP-Like ArchItecture For Visual Recognition》論文筆記
