使用 Spinnaker 和 Google Kubernetes Engine 实现持续交付流水线

本教程介绍如何使用 Google Kubernetes Engine (GKE)、Cloud Source Repositories、Cloud Build 和 Spinnaker for Google Cloud 创建持续交付流水线。创建示例应用后,您可以配置这些服务以自动执行构建、测试和部署。修改应用代码时,更改会触发持续交付流水线,以自动重建、重新测试和重新部署新版本。

DevOps 现状报告确定了可提高软件交付方面表现的功能。本教程将帮助您使用以下功能:

流水线架构

下图展示了持续交付流水线的架构。

面向开发者和用户的流水线架构。

为保证向用户持续交付应用更新,您需要一种能够以可靠的方式构建、测试和更新软件的自动化流程。代码更改应自动流经包含工件创建、单元测试、功能测试和生产部署的流水线。在某些情况下,您希望代码更新仅应用于部分用户,以便在将其推送到整个用户群之前进行“实战演练”。如果其中某个 Canary 版本不能令人满意,那么您的自动程序必须能够快速回滚软件更改。

利用 GKE 和 Spinnaker,您可以创建稳健的持续交付流程,以确保您的软件在完成开发和验证后尽快发布。尽管快速迭代是您的最终目标,但您必须首先确保每个应用修订版本均经过一系列自动化的验证,之后才成为生产发布的候选版本。通过自动化审核给定的更改后,您还可以手动验证应用,并执行进一步的预发行测试。

在您的团队确定应用已准备好投入生产之后,您的某名团队成员可以批准其进行生产部署。

应用交付流水线

在本教程中,您将构建如下图所示的持续交付流水线。

应用交付流水线的架构。

该流水线的简要步骤如下:

  1. 开发者更改代码并将其推送到代码库。

  2. Cloud Build 会检测更改、构建 Docker 映像、测试映像,并将映像推送到 Spinnaker。

  3. Spinnaker 会检测映像、将映像部署到 Canary,并测试 Canary 部署。手动批准后,Spinnaker 将映像部署到生产环境中。

目标

  • 通过启动 Cloud Shell 并部署 Spinnaker for Google Cloud 来设置您的环境。
  • 创建一个向其部署示例应用的 GKE 集群。
  • 下载示例应用,创建 Git 代码库,并将其上传到 Cloud Source Repositories。
  • 构建 Docker 映像。
  • 创建触发器,在应用发生更改时创建 Docker 映像。
  • 将 Spinnaker 流水线配置为以可靠且持续的方式将您的应用部署到 GKE。
  • 部署代码更改、触发流水线,并观察更改发布到生产环境。

费用

本教程使用 Google Cloud 的以下收费组件:

  • GKE
  • Cloud Load Balancing
  • Cloud Build
  • Cloud Source Repositories
  • Container Registry

请使用价格计算器根据您的预计使用情况来估算费用。

Google Cloud 新用户可能有资格申请免费试用

准备工作

  1. 登录您的 Google 帐号。

    如果您还没有 Google 帐号,请注册一个新帐号

  2. 在 Cloud Console 的项目选择器页面上,选择或创建 Cloud 项目。

    转到项目选择器页面

  3. 确保您的 Google Cloud 项目已启用结算功能。 了解如何确认您的项目已启用结算功能

  4. 启用 GKE, Cloud Build, and Cloud Source Repositories API。

    启用 API

设置环境

在本部分中,您将配置完成本教程所需的基础架构。

使用 Cloud Shell 部署 Spinnaker for Google Cloud

请从 Cloud Shell 运行本教程中的所有终端命令。

借助 Spinnaker for Google Cloud,您可在支持生产环境且针对 Google Cloud 进行了优化的配置中设置和管理 Spinnaker。借助帮助程序和常见工具(如 spinhal),Spinnaker for Google Cloud 可设置资源(GKE、Memorystore、Cloud Storage 存储分区和服务帐号),将 Spinnaker 与相关服务(如 Cloud Build)集成,并为 Spinnaker 的安装提供基于 Cloud Shell 的管理环境。

  1. 在 Cloud Shell 中打开 Spinnaker for Google Cloud。这会将 Spinnaker for Google Cloud 代码库克隆到 Cloud Shell 环境中并启动详细的安装说明。

    转到 Cloud Shell

  2. 配置 Git。如果您之前配置过 Git,则可以跳过此步骤。

    git config --global user.email "EMAIL_ADDRESS"
    git config --global user.name "USERNAME"
    

    替换以下内容:

    • EMAIL_ADDRESS:您的 Git 电子邮件地址
    • USERNAME:您的 Git 用户名
  3. 设置一个环境变量,定义要将 Spinnaker 安装到哪个 Cloud 项目:

    DEVSHELL_PROJECT_ID=YOUR_PROJECT_ID
    

    YOUR_PROJECT_ID 替换为您为本教程选择或创建的项目。

  4. 安装 Spinnaker for Google Cloud。

    PROJECT_ID=${DEVSHELL_PROJECT_ID} ~/cloudshell_open/spinnaker-for-gcp/scripts/install/setup_properties.sh
    ~/cloudshell_open/spinnaker-for-gcp/scripts/install/setup.sh
    
  5. 重启 Cloud Shell 以加载新的环境设置。

    Cloud Shell 重启菜单选项。

  6. 连接到 Spinnaker。

    ~/cloudshell_open/spinnaker-for-gcp/scripts/manage/connect_unsecured.sh
    
  7. 在 Cloud Shell 中,点击网页预览图标,然后选择在端口 8080 上预览

    Cloud Shell 网页预览

  8. 您应该看到欢迎屏幕,随即显示 Spinnaker 界面:

    Spinnaker 欢迎屏幕。

    Spinnaker 界面。

为应用部署创建 GKE 集群

一种常见模式是将一个 GKE 集群用于构建和部署等操作,然后将其他 GKE 集群用于运行应用。在本部分中,您还将创建一个 GKE 集群 (app-cluster),以将示例应用部署到该集群。

  1. 在 Cloud Shell 中,创建一个新的 GKE 集群:

    ZONE=us-east1-c
    gcloud config set compute/zone $ZONE
    gcloud container clusters create app-cluster \
    --machine-type=n1-standard-2
    
  2. 将新的 GKE 集群添加到 Spinnaker。默认值应该是合适的。

    ~/cloudshell_open/spinnaker-for-gcp/scripts/manage/add_gke_account.sh
    

    示例输出和值:

    Please enter the context you wish to use to manage your GKE resources: gke_spinnaker-246920_us-east1-c_app-cluster
    Please enter the id of the project within which the referenced cluster lives: spinnaker-246920
    Please enter a name for the new Spinnaker account: app-cluster-acct
    

  3. 将 kubernetes 上下文更改回您的 Spinnaker 集群:

    kubectl config use-context gke_${DEVSHELL_PROJECT_ID}_${ZONE}_spinnaker-1
    
  4. 将配置更改推送并应用到 Spinnaker:

    ~/cloudshell_open/spinnaker-for-gcp/scripts/manage/push_and_apply.sh
    

构建 Docker 映像

在本部分中,您将配置 Cloud Build 以检测应用源代码的更改、构建 Docker 映像,随后将该映像推送到 Container Registry。

创建存储源代码的代码库

  1. 在 Cloud Shell 中,下载示例源代码:

    cd ~
    wget https://gke-spinnaker.storage.googleapis.com/sample-app-v4.tgz
    
  2. 解压缩源代码:

    tar xzfv sample-app-v4.tgz
    
  3. 将目录更改为包含源代码的目录:

    cd sample-app
    
  4. 对存储源代码的代码库执行初始提交:

    git init
    git add .
    git commit -m "Initial commit"
    
  5. 创建一个代码库来托管您的代码:

    gcloud source repos create sample-app
    git config credential.helper gcloud.sh
    
  6. 将新创建的代码库添加为远程代码库:

    export PROJECT=$(gcloud info --format='value(config.project)')
    git remote add origin https://source.developers.google.com/p/$PROJECT/r/sample-app
    
  7. 将您代码推送到新代码库的 master 分支:

    git push origin master
  8. 检查您能否在控制台中查看自己的源代码:

    转到“源代码”页面

配置构建触发器

下图展示了您在本部分构建的触发器。

Spinnaker 工作流

您需要配置 Cloud Build,使其在您每次将 Git 标记推送到源代码库时构建并推送 Docker 映像。Cloud Build 会自动检查您的源代码,通过代码库中的 Dockerfile 构建 Docker 映像,并将该映像推送到 Container Registry。

  1. 在 Cloud Console 的 Cloud Build 部分中,点击触发器,然后点击创建触发器

    转到“构建触发器”页面

  2. 设定以下触发器设置:

    • 名称sample-app-tags
    • 事件:选择推送新标记
    • 代码库sample-app
    • 标记(正则表达式)v.*
    • 构建配置/cloudbuild.yaml
  3. 点击创建

    创建触发器时的触发器设置。

从现在开始,每当您将以字母“v”为前缀的 Git 标记推送到存储源代码的代码库时,Cloud Build 都会自动将您的应用构建为 Docker 映像,并将其推送到 Container Registry。

准备 Kubernetes 清单以便在 Spinnaker 中使用

Spinnaker 需要访问您的 Kubernetes 清单以将其部署到您的集群。本部分将创建一个 Cloud Storage 存储分区,在 Cloud Build 中的持续集成过程中,系统将使用您的清单填充该存储分区。在您的清单显示在 Cloud Storage 中后,Spinnaker 即可在流水线执行期间下载并应用这些清单。

  1. 创建存储分区。

    export PROJECT=$(gcloud info --format='value(config.project)')
    gsutil mb gs://$PROJECT-kubernetes-manifests
    
  2. 在存储分区上启用版本控制,以保证您可以获得清单的历史记录。

    gsutil versioning set on gs://$PROJECT-kubernetes-manifests
    
  3. 在 Kubernetes 部署清单中设置正确的 Google Cloud 项目 ID:

    sed -i s/PROJECT/$PROJECT/g k8s/deployments/*
    
  4. 将更改提交到代码库:

    git commit -a -m "Set project ID"
    

配置部署流水线

现在您的映像已在自动构建,接下来您需要将它们部署到 Kubernetes 集群。

下图展示了部署流水线步骤。

配置部署流水线。

您可以部署到规模缩减的环境以进行集成测试。集成测试通过后,您必须手动批准更改以将代码部署到生产服务。

创建部署流水线

  1. 使用 spin 在 Spinnaker 中创建应用。

    spin application save --application-name sample \
                          --owner-email example@example.com \
                          --cloud-providers kubernetes \
                          --gate-endpoint http://localhost:8080/gate
    

    接下来,您要创建持续交付流水线。在本教程中,流水线配置为检测带有前缀为 v 的标记的 Docker 映像到达了您的 Container Registry。

  2. 在 Cloud Shell 的新标签页中,在源代码目录中运行以下命令,以将示例流水线上传到 Spinnaker 实例:

    export PROJECT=$(gcloud info --format='value(config.project)')
    sed s/PROJECT/$PROJECT/g spinnaker/pipeline-deploy.json > pipeline.json
    spin pipeline save --gate-endpoint http://localhost:8080/gate -f pipeline.json
    

构建您的映像

使用以下步骤推送您的第一个映像:

  1. 转到 Cloud Shell 中的源代码文件夹。
  2. 创建一个 Git 标记:

    git tag v1.0.0
  3. 推送标记:

    git push --tags
  4. Cloud Build 中,点击构建记录以检查是否已触发构建。如果没有,请验证在上一部分中是否正确配置了触发器。

    转到“构建记录”

    构建记录

查看流水线执行情况

您刚刚创建的配置使用新的带标记映像的推送通知来触发 Spinnaker 流水线。在上一步中,您将标记推送到 Cloud Source Repositories,后者触发 Cloud Build 以构建映像并将其推送到 Container Registry。现在,您可以检查已触发的流水线。

  1. 点击流水线返回“流水线”页面。

  2. 点击详细信息以查看有关流水线进度的更多信息。此部分显示部署流水线的状态及其步骤。蓝色步骤表示正在运行的步骤,绿色步骤是已成功完成的步骤,红色步骤则是已失败的步骤。点击一个阶段以查看有关它的详细信息。

    3 到 5 分钟后,集成测试阶段完成,流水线需要手动批准才能继续部署。

  3. 将光标悬停在推送至生产环境 (Push to production) 上,然后点击继续

    您的发布将继续进入到生产前端和后端部署。操作会在几分钟后完成。

  4. 如需查看应用,请在 Spinnaker 界面选择基础架构 > 负载平衡器

    基础架构下拉列表(已选择“负载平衡器”)。

  5. 在负载平衡器列表中向下滚动,然后在 sample-frontend-production 下点击默认

    默认负载平衡器。

  6. 在右侧的“详细信息”窗格中向下滚动,然后点击 Ingress IP 处的剪贴板按钮复制应用的 IP 地址。Spinnaker 界面的 Ingress IP 链接默认使用 HTTPS,但应用配置为使用 HTTP。

    包含应用 IP 地址的“详细信息”窗格。

  7. 将地址粘贴到浏览器中以查看应用的生产版本。

    应用的生产版本。

    现在,您已手动触发流水线以构建、测试和部署您的应用。

通过代码更改触发流水线

在本部分中,您将通过执行代码更改、推送 Git 标记以及观察响应中的流水线运行情况来对流水线执行端到端的测试。通过推送以“v”开头的 Git 标记,您可以触发 Cloud Build 构建新的 Docker 映像并将其推送到 Container Registry。Spinnaker 检测到以“v”开头的新映像标记,并触发流水线以将该映像部署到 Canary 版、运行测试,然后将相同的映像发布到部署中的所有 pod。

  1. 将应用的颜色从橙色更改为蓝色:

    cd ~/sample-app
    sed -i 's/orange/blue/g' cmd/gke-info/common-service.go
    
  2. 标记您的更改并将其推送到存储源代码的代码库:

    git commit -a -m "Change color to blue"
    git tag v1.0.1
    git push --tags
    
  3. Cloud Build 构建记录中,您会看到新版本。

  4. 点击流水线以观察流水线开始部署映像。

  5. 观察 Canary 部署。在部署暂停,等待其发布到生产环境时,开始刷新包含应用的标签页。您的 4 个后端正在运行该应用的早期版本,只有 1 个后端正在运行 Canary 版。大约每刷新十次,您就会看到应用的新蓝色版本。

  6. 测试完成后,返回 Spinnaker 标签并批准部署。

  7. 流水线完成后,您的应用如以下屏幕截图所示。版本字段现在显示为 v1.0.1

    已更新应用的生产版本。

    至此,您已成功将应用发布到整个生产环境!

  8. (可选)您可以通过还原先前的提交来回滚此更改。回滚会添加一个新的标记 (v1.0.2),并通过部署 v1.0.1 时采用的流水线将该标记推回:

    git revert v1.0.1
    git tag v1.0.2
    git push --tags

清理

为避免系统因本教程中使用的资源向您的 Google Cloud Platform 帐号收取费用,请执行以下操作:

  1. 删除 Spinnaker for Google Cloud:

    cd ~
    ~/cloudshell_open/spinnaker-for-gcp/scripts/manage/generate_deletion_script.sh
    ~/cloudshell_open/spinnaker-for-gcp/scripts/manage/delete-all_${DEVSHELL_PROJECT_ID}_spinnaker-1_spinnaker-1.sh
    
  2. 删除 GKE 集群:

    gcloud container clusters delete app-cluster --zone=us-east1-c
    
  3. 删除代码库:

    gcloud source repos delete sample-app
    
  4. 删除存储分区:

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-kubernetes-manifests
    gsutil -m rm -r gs://$BUCKET
    
  5. 删除容器映像:

    export PROJECT=$(gcloud info --format='value(config.project)')
    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.0
    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.1
    
  6. 如果您在上面的可选回滚步骤中创建了 v1.0.2,请删除该容器映像:

    gcloud container images delete gcr.io/$PROJECT/sample-app:v1.0.2
    

后续步骤