使用 Cloud Build 持续部署到 Google Kubernetes Engine (GKE)

1. 概览

在本实验中,您将学习如何使用 Cloud Build 为 GKE 设置持续交付流水线。本实验重点介绍如何为不同的 Git 事件触发 Cloud Build 作业,以及 GKE 中自动化 Canary 版本的简单模式。

您将完成以下步骤:

  • 创建 GKE 应用
  • 自动为 Git 分支进行部署
  • 为 Git 主分支自动进行部署
  • 自动部署 Git 标记

2. 准备工作

在本参考指南中,您需要一个 Google Cloud 项目。您可以创建一个新项目,也可以选择已创建的项目:

  1. 选择或创建 Google Cloud 项目。

转到“项目选择器”页面

  1. 为您的项目启用结算功能。

启用结算功能

3. 准备您的环境

  1. 创建要在整个教程中使用的环境变量:
    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
    export ZONE=us-central1-b
    export CLUSTER=gke-progression-cluster
    export APP_NAME=myapp
    
  2. 启用以下 API:
    • Resource Manager
    • GKE
    • Cloud Source Repositories
    • Cloud Build
    • Container Registry
    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        sourcerepo.googleapis.com \
        cloudbuild.googleapis.com \
        containerregistry.googleapis.com \
        --async
    
  3. 克隆示例源代码并切换到实验目录:
    git clone https://github.com/GoogleCloudPlatform/software-delivery-workshop.git gke-progression
    
    cd gke-progression/labs/gke-progression
    rm -rf ../../.git
    
  4. 将示例代码库中的占位值替换为您的 PROJECT_ID:在此步骤中,您将创建当前环境独有的各种配置文件实例。如需查看要更新的模板的示例,请运行以下命令。
    cat k8s/deployments/dev/frontend-dev.yaml.tmpl
    
    通过执行以下命令来执行变量替换。
    for template in $(find . -name '*.tmpl'); do envsubst '${PROJECT_ID} ${ZONE} ${CLUSTER} ${APP_NAME}' < ${template} > ${template%.*}; done
    
    如需查看替换后的文件示例,请运行以下命令。
    cat k8s/deployments/dev/frontend-dev.yaml
    
  5. 如果您之前未使用过 Cloud Shell 中的 Git,请设置您要使用的 user.nameuser.email 值:
    git config --global user.email "YOUR_EMAIL_ADDRESS"
    git config --global user.name "YOUR_USERNAME"
    
  6. 将示例代码库中的代码存储在 Cloud Source Repositories 中:
    gcloud source repos create gke-progression
    git init
    git config credential.helper gcloud.sh
    git remote add gcp https://source.developers.google.com/p/$PROJECT_ID/r/gke-progression
    git branch -m main
    git add . && git commit -m "initial commit"
    git push gcp main
    
  7. 创建 GKE 集群。
    gcloud container clusters create ${CLUSTER} \
        --project=${PROJECT_ID} \
        --zone=${ZONE}
    
  8. 为 Cloud Build 授予对您的集群的权限。Cloud Build 会将该应用部署到您的 GKE 集群,并且需要相关权限。
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
        --role=roles/container.developer
    

您的环境已准备就绪!

4. 创建 GKE 应用

在本部分中,您将构建和部署在本教程中使用的初始生产应用。

  1. 使用 Cloud Build 构建应用:
    gcloud builds submit --tag gcr.io/$PROJECT_ID/$APP_NAME:1.0.0 src/
    
  2. 手动部署到 Canary 和生产环境:使用 kubectl apply 命令创建生产和 Canary 部署和服务。
    kubectl create ns production
    kubectl apply -f k8s/deployments/prod -n production
    kubectl apply -f k8s/deployments/canary -n production
    kubectl apply -f k8s/services -n production
    
    此处部署的服务会将流量路由到 Canary 版部署和生产环境部署。
  3. 检查正在运行的 Pod 数量。确认为前端运行了四个 Pod,包括三个用于生产流量的 Pod,一个用于 Canary 版本。这意味着,对 Canary 版本所做的更改只会影响四分之一 (25%) 的用户。
    kubectl get pods -n production -l app=$APP_NAME -l role=frontend
    
  4. 检索生产服务的外部 IP 地址。
    kubectl get service $APP_NAME -n production
    
    负载平衡器返回 IP 地址后,继续执行下一步
  5. 存储外部 IP 以供日后使用。
    export PRODUCTION_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=production services $APP_NAME)
    
  6. 查看应用程序 检查服务的版本输出。它应该显示为 Hello World v1.0
    curl http://$PRODUCTION_IP
    

恭喜!您已部署示例应用!接下来,您将设置用于持续部署更改的触发器。

5. 自动执行 Git 分支部署

在本部分中,您将设置一个触发器,以在提交除 main 以外的任何分支时执行 Cloudbuild 作业。此处使用的 Cloud Build 文件会自动为任何现有分支或新分支创建命名空间和部署,让开发者能够在与主分支集成之前预览其代码。

  1. 设置触发器:此触发器的关键组件是使用 branchName 形参来匹配 main,并使用 invertRegex 形参(设置为 true)并更改 branchName 模式以匹配除 main 以外的任何内容。为便于您参考,您可以在 build/branch-trigger.json 中找到以下几行内容。
      "branchName": "main",
      "invertRegex": true
    
    此外,与此触发器搭配使用的 Cloud Build 文件的最后几行还会创建一个以触发作业的分支命名的命名空间,然后在新命名空间中部署应用和服务。为供您参考,您可以在 build/branch-cloudbuild.yaml
      kubectl get ns ${BRANCH_NAME} || kubectl create ns ${BRANCH_NAME}
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/deployments/dev
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/services
    
    中找到以下几行内容 现在您已了解所使用的机制,接下来请使用下面的 gcloud 命令创建触发器。
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/branch-trigger.json
    
  2. 如需查看触发器,请前往控制台中的“Cloud Build 触发器”页面前往“触发器”
  3. 创建新分支:
    git checkout -b new-feature-1
    
  4. 修改代码以指明 v1.1Edit src/app.py,并将响应从 1.0 更改为 1.1
    @app.route('/')
    def hello_world():
        return 'Hello World v1.1'
    
  5. 提交更改并推送到远程代码库:
    git add . && git commit -m "updated" && git push gcp new-feature-1
    
  6. 如需查看正在进行的构建,请前往控制台中的 Cloud Build 历史记录页面前往“构建”构建完成后,继续下一步
  7. 检索新部署的分支服务的外部 IP 地址。
    kubectl get service $APP_NAME -n new-feature-1
    
    负载平衡器返回 IP 地址后,继续执行下一步
  8. 存储外部 IP 以供日后使用。
    export BRANCH_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=new-feature-1 services $APP_NAME)
    
  9. 查看 applicationCheck 服务的版本输出。它应该显示为 Hello World v1.0
    curl http://$BRANCH_IP
    

6. 自动执行 Git 主分支的部署

在将代码发布到生产环境之前,通常先将代码发布到一小部分实时流量,然后再将所有流量迁移到新的代码库。

在本部分中,您将实现一个触发器,该触发器会在代码提交到主分支时激活。触发器会将接收所有实时流量的 25% 的 Canary 部署部署到新修订版本。

  1. 为主分支设置触发器:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/main-trigger.json
    
  2. 如需查看新触发器,请前往控制台中的“Cloud Build 触发器”页面前往“触发器”
  3. 将分支合并到主行并推送到远程代码库:
    git checkout main
    git merge new-feature-1
    git push gcp main
    
  4. 如需查看正在进行的构建,请前往控制台中的 Cloud Build 历史记录页面前往“构建”构建完成后,继续下一步
  5. 查看来自 server 的多个响应。运行以下命令,并注意大约 25% 的响应显示的是 Hello World v1.1 的新响应
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    准备好继续后,按 Ctrl+c 退出循环。

7. 自动部署 Git 标记

使用一小部分流量验证 Canary 部署后,您需要将部署发布到其余实时流量。

在本部分中,您将设置一个触发器,该触发器会在代码库中创建标记时激活。触发器会使用适当的标记来标记映像,然后将更新部署到生产环境,以确保 100% 的流量访问带标记的映像。

  1. 设置代码触发器:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/tag-trigger.json
    
  2. 如需查看新触发器,请前往控制台中的“Cloud Build 触发器”页面前往“触发器”
  3. 创建新标记并推送到远程代码库:
    git tag 1.1
    git push gcp 1.1
    
  4. 如需查看正在进行的构建,请前往控制台中的 Cloud Build 历史记录页面前往“构建”
  5. 查看来自服务器的多个响应。运行以下命令,并注意,所有响应都显示 Hello World v1 的新响应。1 这可能需要一些时间,因为系统需要一些时间在 GKE 中部署新 Pod 并进行健康检查
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    准备好继续后,按 Ctrl+c 退出循环。恭喜!您在 Cloud Build 中为分支和标记创建了 CI/CD 触发器,以便将您的应用部署到 GKE。

8. 清理

删除项目

  1. 在 Cloud 控制台中,前往“管理资源”页面
  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关停以删除项目。