本指南介绍了如何使用 Cloud Build 和 Terraform 在 Compute Engine 代管式实例组 (MIG) 上执行零停机蓝绿部署。
Cloud Build 可让您自动执行各种开发者流程,包括将应用构建和部署到各种 Google Cloud 运行时,例如 Compute Engine、Google Kubernetes Engine、GKE Enterprise 和 Cloud Run 函数。
借助 Compute Engine MIG,您可以在多个相同的虚拟机 (VM) 上运行应用。您可以利用自动化 MIG 服务让您的工作负载具有可伸缩性和高可用性,这些服务包括自动伸缩、自动修复、区域(多地区)部署和自动更新。使用蓝绿持续部署模型,您将学习如何逐步将用户流量从一个 MIG(蓝色)转移到另一个 MIG(绿色),这两个 MIG 都在生产环境中运行。
设计概览
下图展示了本文档中所述代码示例使用的蓝/绿部署模型:
从宏观层面来看,此模型包含以下组件:
- 两个 Compute Engine 虚拟机池:蓝色和绿色。
- 三个外部 HTTP(S) 负载平衡器:
- 一种蓝/绿负载均衡器,可将最终用户的流量路由到蓝色或绿色虚拟机实例池。
- 一个蓝色负载均衡器,用于将流量从质量检查工程师和开发者路由到蓝色虚拟机实例池。
- 一个绿色负载均衡器,用于将来自 QA 工程师和开发者的流量路由到绿色实例池。
- 两组用户:
- 有权访问蓝/绿负载均衡器的最终用户,该负载均衡器会将他们定向到蓝色或绿色实例池。
- 需要同时访问这两组池的 QA 工程师和开发者,以便进行开发和测试。他们可以访问蓝色和绿色负载平衡器,这些负载平衡器会将他们分别路由到蓝色实例池和绿色实例池。
蓝色和绿色虚拟机池以 Compute Engine MIG 的形式实现,外部 IP 地址通过外部 HTTP(s) 负载平衡器路由到 MIG 中的虚拟机。本文档中描述的代码示例使用 Terraform 来配置此基础架构。
下图说明了部署中发生的开发者操作:
在上图中,红色箭头表示首次设置部署基础架构时发生的引导流程,蓝色箭头表示每次部署期间发生的 GitOps 流程。
如需设置此基础架构,您需要运行一个设置脚本,该脚本会启动引导加载程序进程并设置 GitOps 流程的组件。
设置脚本会执行一个 Cloud Build 流水线,该流水线会执行以下操作:
- 在 Cloud Source Repositories 中创建一个名为
copy-of-gcp-mig-simple
的代码库,并将 GitHub 示例代码库中的源代码复制到 Cloud Source Repositories 中的该代码库。 - 创建两个名为
apply
和destroy
的 Cloud Build 触发器。
apply
触发器附加到 Cloud Source Repositories 中名为 main.tfvars
的 Terraform 文件。此文件包含表示蓝色和绿色负载平衡器的 Terraform 变量。
如需设置部署,请更新 main.tfvars
文件中的变量。apply
触发器会运行一个 Cloud Build 流水线,该流水线会执行 tf_apply
并执行以下操作:
- 创建两个 Compute Engine MIG(一个用于绿色版本,一个用于蓝色版本)、四个 Compute Engine 虚拟机实例(两个用于绿色 MIG,两个用于蓝色 MIG)、三个负载平衡器(蓝色、绿色和拆分器)以及三个公共 IP 地址。
- 输出可用于查看蓝色和绿色实例中已部署应用的 IP 地址。
销毁触发器会手动触发,以删除应用触发器创建的所有资源。
目标
使用 Cloud Build 和 Terraform 设置具有 Compute Engine 虚拟机实例组后端的外部 HTTP(S) 负载平衡器。
在虚拟机实例上执行蓝绿部署。
费用
在本文档中,您将使用 Google Cloud的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
Install the Google Cloud CLI.
-
如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Verify that billing is enabled for your Google Cloud project.
-
Install the Google Cloud CLI.
-
如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI。
-
如需初始化 gcloud CLI,请运行以下命令:
gcloud init
-
Create or select a Google Cloud project.
-
Create a Google Cloud project:
gcloud projects create PROJECT_ID
Replace
PROJECT_ID
with a name for the Google Cloud project you are creating. -
Select the Google Cloud project that you created:
gcloud config set project PROJECT_ID
Replace
PROJECT_ID
with your Google Cloud project name.
-
-
Verify that billing is enabled for your Google Cloud project.
从 Google 代码示例代码库运行设置脚本:
bash <(curl https://raw.githubusercontent.com/GoogleCloudPlatform/cloud-build-samples/main/mig-blue-green/setup.sh)
当设置脚本要求用户同意时,输入 yes。
脚本会在几秒钟内完成运行。
在 Google Cloud 控制台中,打开 Cloud Build 构建记录页面:
点击最新 build。
您会看到构建详情页面,其中显示了一个包含三个构建步骤的 Cloud Build 流水线:第一个构建步骤在 Cloud Source Repositories 中创建一个代码库,第二个步骤将 GitHub 中示例代码库的内容克隆到 Cloud Source Repositories,第三个步骤添加两个构建触发器。
打开 Cloud Source Repositories:
在代码库列表中,点击
copy-of-gcp-mig-simple
。在页面底部的历史记录标签页中,您会看到一个提交,其说明为
A copy of https://github.com/GoogleCloudPlatform/cloud-build-samples.git
,由 Cloud Build 创建,用于创建名为copy-of-gcp-mig-simple
的代码库。打开 Cloud Build 的触发器页面:
如需开始部署流程,请更新
infra/main.tfvars
文件:在终端窗口中,创建并进入名为
deploy-compute-engine
的文件夹:mkdir ~/deploy-compute-engine cd ~/deploy-compute-engine
克隆
copy-of-gcp-mig-simple
代码库:gcloud source repos clone copy-of-mig-blue-green
进入克隆的目录:
cd ./copy-of-mig-blue-green
更新
infra/main.tfvars
以将蓝色替换为绿色:sed -i'' -e 's/blue/green/g' infra/main.tfvars
添加更新后的文件:
git add .
提交此文件:
git commit -m "Promote green"
推送文件:
git push
对
infra/main.tfvars
进行更改会触发apply
触发器的执行,从而启动部署。
打开 Cloud Source Repositories:
在代码库列表中,点击
copy-of-gcp-mig-simple
。您会在页面底部的历史记录标签页中看到说明为
Promote green
的提交。如需查看
apply
触发器的执行情况,请在 Google Cloud 控制台中打开构建历史记录页面:点击第一个 build,打开build 详情页面。
您将看到包含两个构建步骤的
apply
触发流水线。第一个 build 步骤会执行 Terraform apply,以创建部署所需的 Compute Engine 和负载均衡资源。第二个 build 步骤会输出您可以在其中查看应用运行情况的 IP 地址。在浏览器中打开与绿色 MIG 对应的 IP 地址。您将看到类似于以下屏幕截图的界面,其中显示了部署情况:
前往 Compute Engine 的实例组页面,查看蓝色实例组和绿色实例组:
打开虚拟机实例页面,查看以下四个虚拟机实例:
打开外部 IP 地址页面,查看三个负载平衡器:
- 与设置脚本相关的源代码。
- 与 Cloud Build 流水线相关的源代码。
- 与 Terraform 模板相关的源代码。
- 启用 Cloud Build、Resource Manager、Compute Engine 和 Cloud Source Repositories API。
- 向您项目中的 Cloud Build 服务账号授予
roles/editor
IAM 角色。Cloud Build 需要此角色才能创建和设置部署所需的 GitOps 组件。 - 向您项目中的 Cloud Build 服务账号授予
roles/source.admin
IAM 角色。Cloud Build 服务账号必须具有此角色,才能在您的项目中创建 Cloud Source Repositories,并将示例 GitHub 代码库的内容克隆到您的 Cloud Source Repositories。 内联生成名为
bootstrap.cloudbuild.yaml
的 Cloud Build 流水线,该流水线:- 在 Cloud Source Repositories 中创建新代码库。
- 将示例 GitHub 代码库中的源代码复制到 Cloud Source Repositories 中的新代码库。
- 创建 apply 和 destroy 构建触发器。
tf_apply build
构建步骤,用于调用安装 Terraform 的函数tf_install_in_cloud_build_step
。tf_apply
用于创建 GitOps 流程中使用的资源。函数tf_install_in_cloud_build_step
和tf_apply
在bash_utils.sh
中定义,构建步骤使用source
命令来调用它们。describe_deployment
build 步骤,用于调用可输出负载平衡器 IP 地址的函数describe_deployment
。main.tf
:这是 Terraform 配置文件main.tfvars
:此文件定义了 Terraform 变量。mig/
和splitter/
:这些文件夹包含定义负载平衡器的模块。mig/
文件夹包含 Terraform 配置文件,用于定义蓝色和绿色负载平衡器的 MIG。蓝色 MIG 和绿色 MIG 是相同的,因此只需定义一次,然后针对蓝色对象和绿色对象进行实例化。拆分器负载均衡器的 Terraform 配置文件位于splitter/
文件夹中。- 为 Google Cloud 项目定义了变量。
- Google 已设置为 Terraform 提供商。
- 为命名空间定义了变量。Terraform 创建的所有对象都以该变量为前缀,以便在同一项目中部署多个版本的应用,并且对象名称不会相互冲突。
- 变量
MIG_VER_BLUE
、MIG_VER_BLUE
和MIG_ACTIVE_COLOR
是infra/main.tfvars
文件中变量的绑定。 删除由应用触发器创建的 Compute Engine 资源:
打开 Cloud Build 的触发器页面:
在触发器表中,找到与 destroy 触发器对应的行,然后点击运行。当触发器完成执行时,由 apply 触发器创建的资源会被删除。
如需删除在引导过程中创建的资源,请在终端窗口中运行以下命令:
bash <(curl https://raw.githubusercontent.com/GoogleCloudPlatform/cloud-build-samples/main/mig-blue-green/teardown.sh)
- 详细了解构建触发器。
- 了解如何查看 build 出处。
测试
您会看到两个名为 apply
和 destroy
的 build 触发器。apply
触发器已附加到 main
分支中的 infra/main.tfvars
文件。每当文件更新时,系统都会执行此触发器。destroy
触发器是手动触发器。
了解代码
此代码示例的源代码包括:
设置脚本
setup.sh
是运行引导过程并为蓝绿部署创建组件的设置脚本。该脚本执行以下操作:
Cloud Build 流水线
apply.cloudbuild.yaml
和 destroy.cloudbuild.yaml
是设置脚本用于为 GitOps 流程设置资源的 Cloud Build 配置文件。apply.cloudbuild.yaml
包含两个构建步骤:
destroy.cloudbuild.yaml
调用 tf_destroy
,后者会删除 tf_apply
创建的所有资源。
函数 tf_install_in_cloud_build_step
、tf_apply
、describe_deployment
和 tf_destroy
在文件 bash_utils.sh
中定义。构建配置文件使用 source
命令来调用函数。
以下代码显示了在 bash_utils.sh
中定义的函数 tf_install_in_cloud_build_step
。build config 文件会调用此函数来动态安装 Terraform。它会创建一个 Cloud Storage 存储桶来记录 Terraform 状态。
以下代码段显示了在 bash_utils.sh
中定义的函数 tf_apply
。它首先调用 terraform init
加载所有模块和自定义库,然后运行 terraform apply
以从 main.tfvars
文件加载变量。
以下代码段显示了在 bash_utils.sh
中定义的函数 describe_deployment
。它使用 gcloud compute addresses describe
通过名称提取负载平衡器的 IP 地址,然后将其打印出来。
以下代码段显示了在 bash_utils.sh
中定义的函数 tf_destroy
。它会调用 terraform init
来加载所有模块和自定义库,然后运行 terraform destroy
来卸载 Terraform 变量。
Terraform 模板
您可以在 copy-of-gcp-mig-simple/infra/
文件夹中找到所有 Terraform 配置文件和变量。
以下代码段显示了 infra/main.tfvars
的内容。它包含三个变量:两个用于确定要部署到蓝色池和绿色池的应用版本,一个用于确定有效颜色(蓝色或绿色)。对此文件的更改会触发部署。
以下是 infra/main.tf
中的一个代码段。在此代码段中:
以下代码段来自 infra/main.tf
,展示了拆分器模块的实例化。此模块会接收有效颜色,以便拆分器负载平衡器知道要将应用部署到哪个 MIG。
infra/main.tf
中的以下代码段为蓝色和绿色 MIG 定义了两个相同的模块。它会接收在拆分器模块中定义的颜色、网络和子网。
文件 splitter/main.tf
定义了为拆分器 MIG 创建的对象。以下是 splitter/main.tf
中的一个代码段,其中包含在绿色 MIG 和蓝色 MIG 之间切换的逻辑。它由服务 google_compute_region_backend_service
提供支持,该服务可以将流量路由到两个后端区域:var.instance_group_blue
或 var.instance_group_green
。capacity_scaler
定义要路由的流量百分比。
以下代码会将 100% 的流量路由到指定的颜色,但您可以更新此代码以进行 Canary 部署,从而将流量路由到部分用户。
文件 mig/main.tf
定义了与蓝色和绿色 MIG 相关联的对象。此文件中的以下代码段定义了用于创建虚拟机池的 Compute Engine 实例模板。请注意,此实例模板的 Terraform 生命周期属性设置为 create_before_destroy
。
这是因为,在更新池的版本时,如果模板仍被旧版池使用,您就无法使用该模板创建新版池。但是,如果在创建新模板之前销毁了旧版本的池,则会有一段时间池处于关闭状态。为避免这种情况,我们将 Terraform 生命周期设置为 create_before_destroy
,以便先创建较新版本的虚拟机池,然后再销毁较旧版本。
清理
为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。
删除各个资源
删除项目
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID