使用 Cloud Build 持续部署到 Google Kubernetes Engine (GKE)
关于此 Codelab
subject上次更新时间:2月 28, 2022
1. 概览
在本实验中,您将学习如何使用 Cloud Build 为 GKE 设置持续交付流水线。本实验重点介绍如何为不同的 Git 事件触发 Cloud Build 作业,以及 GKE 中自动化 Canary 版本的简单模式。
您将完成以下步骤:
- 创建 GKE 应用
- 自动为 Git 分支进行部署
- 为 Git 主分支自动进行部署
- 自动部署 Git 标记
3. 准备环境
- 创建要在整个教程中使用的环境变量:
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 - 启用以下 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 - 克隆示例源代码并切换到实验目录:
git clone https://github.com/GoogleCloudPlatform/software-delivery-workshop.git gke-progression
cd gke-progression/labs/gke-progression
rm -rf ../../.git - 将示例代码库中的占位值替换为您的
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
- 如果您之前未使用过 Cloud Shell 中的 Git,请设置您要使用的
user.name
和user.email
值:git config --global user.email "YOUR_EMAIL_ADDRESS"
git config --global user.name "YOUR_USERNAME" - 将示例代码库中的代码存储在 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 - 创建 GKE 集群。
gcloud container clusters create ${CLUSTER} \
--project=${PROJECT_ID} \
--zone=${ZONE} - 为 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 应用
在本部分中,您将构建和部署在本教程中使用的初始生产应用。
- 使用 Cloud Build 构建应用:
gcloud builds submit --tag gcr.io/$PROJECT_ID/$APP_NAME:1.0.0 src/
- 手动部署到 Canary 和生产环境:使用
kubectl apply
命令创建生产和 Canary 部署和服务。 此处部署的服务会将流量路由到 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 - 检查正在运行的 Pod 数量。确认为前端运行了四个 Pod,包括三个用于生产流量的 Pod,一个用于 Canary 版本。这意味着,对 Canary 版本所做的更改只会影响四分之一 (25%) 的用户。
kubectl get pods -n production -l app=$APP_NAME -l role=frontend
- 检索生产服务的外部 IP 地址。。
负载平衡器返回 IP 地址后,继续执行下一步kubectl get service $APP_NAME -n production
- 存储外部 IP 以供日后使用。
export PRODUCTION_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}" --namespace=production services $APP_NAME)
- 查看应用程序 检查服务的版本输出。它应该显示为 Hello World v1.0
curl http://$PRODUCTION_IP
恭喜!您已部署示例应用!接下来,您将设置用于持续部署更改的触发器。
5. 自动执行 Git 分支部署
在本部分中,您将设置一个触发器,以在提交除 main
以外的任何分支时执行 Cloudbuild 作业。此处使用的 Cloud Build 文件会自动为任何现有分支或新分支创建命名空间和部署,让开发者能够在与主分支集成之前预览其代码。
- 设置触发器:此触发器的关键组件是使用
branchName
形参来匹配main
,并使用invertRegex
形参(设置为 true)并更改branchName
模式以匹配除main
以外的任何内容。为便于您参考,您可以在build/branch-trigger.json
中找到以下几行内容。 此外,与此触发器搭配使用的 Cloud Build 文件的最后几行还会创建一个以触发作业的分支命名的命名空间,然后在新命名空间中部署应用和服务。为供您参考,您可以在"branchName": "main", "invertRegex": true
build/branch-cloudbuild.yaml
中找到以下几行内容 现在您已了解所使用的机制,接下来请使用下面的 gcloud 命令创建触发器。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 beta builds triggers create cloud-source-repositories \
--trigger-config build/branch-trigger.json - 如需查看触发器,请前往控制台中的“Cloud Build 触发器”页面。前往“触发器”
- 创建新分支:
git checkout -b new-feature-1
- 修改代码以指明 v1.1Edit
src/app.py
,并将响应从 1.0 更改为 1.1@app.route('/')
def hello_world():
return 'Hello World v1.1' - 提交更改并推送到远程代码库:
git add . && git commit -m "updated" && git push gcp new-feature-1
- 如需查看正在进行的构建,请前往控制台中的 Cloud Build 历史记录页面。前往“构建”构建完成后,继续下一步
- 检索新部署的分支服务的外部 IP 地址。。
负载平衡器返回 IP 地址后,继续执行下一步kubectl get service $APP_NAME -n new-feature-1
- 存储外部 IP 以供日后使用。
export BRANCH_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}" --namespace=new-feature-1 services $APP_NAME)
- 查看 applicationCheck 服务的版本输出。它应该显示为 Hello World v1.0
curl http://$BRANCH_IP
6. 自动执行 Git 主分支的部署
在将代码发布到生产环境之前,通常先将代码发布到一小部分实时流量,然后再将所有流量迁移到新的代码库。
在本部分中,您将实现一个触发器,该触发器会在代码提交到主分支时激活。触发器会将接收所有实时流量的 25% 的 Canary 部署部署到新修订版本。
- 为主分支设置触发器:
gcloud beta builds triggers create cloud-source-repositories \
--trigger-config build/main-trigger.json - 如需查看新触发器,请前往控制台中的“Cloud Build 触发器”页面。前往“触发器”
- 将分支合并到主行并推送到远程代码库:
git checkout main
git merge new-feature-1
git push gcp main - 如需查看正在进行的构建,请前往控制台中的 Cloud Build 历史记录页面。前往“构建”构建完成后,继续下一步
- 查看来自 server 的多个响应。运行以下命令,并注意大约 25% 的响应显示的是 Hello World v1.1 的新响应
准备好继续后,按while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1; done
Ctrl+c
退出循环。
7. 自动部署 Git 标记
使用一小部分流量验证 Canary 部署后,您需要将部署发布到其余实时流量。
在本部分中,您将设置一个触发器,该触发器会在代码库中创建标记时激活。触发器会使用适当的标记来标记映像,然后将更新部署到生产环境,以确保 100% 的流量访问带标记的映像。
- 设置代码触发器:
gcloud beta builds triggers create cloud-source-repositories \
--trigger-config build/tag-trigger.json - 如需查看新触发器,请前往控制台中的“Cloud Build 触发器”页面。前往“触发器”
- 创建新标记并推送到远程代码库:
git tag 1.1
git push gcp 1.1 - 如需查看正在进行的构建,请前往控制台中的 Cloud Build 历史记录页面。前往“构建”
- 查看来自服务器的多个响应。运行以下命令,并注意,所有响应都显示 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。