大纲
Google Cloud Build 简介
Google Cloud Build(谷歌云构建)是谷歌云平台(Google Cloud Platform,GCP)提供的一项服务,可帮助开发人员以一致和自动化的方式构建、测试和部署应用程序或构件。它为构建和部署应用程序提供了一个完全托管、可扩展和灵活的环境。
使用Cloud Build,开发人员可以使用配置文件(如YAML或JSON)定义构建流水线,指定构建过程中要执行的步骤和操作。可以根据事件(如代码库提交或更改)自动触发这些流水线,也可以由开发人员手动触发。
Cloud Build支持各种构建工具和编程语言,允许开发人员使用他们喜欢的工具和框架。它与其他GCP服务(如Cloud Storage、Container Registry和Cloud Run)无缝集成,实现了平滑的部署和发布工作流程。
Cloud Build的主要功能包括并行构建以加快执行速度、可定制的构建步骤、缓存以提高构建性能以及与版本控制系统的集成,便于源代码管理。
总之,Cloud Build简化了构建和部署过程,促进了自动化和协作,并帮助开发人员在谷歌云平台上优化软件开发生命周期。
与Jenkins 对比的优缺点
可以认为Cloud build 就是jenkins 的简单替代品, 比起jenkins, cloud build 有如下的优缺点
优点1:
Cloud build是完全云原生和serverless 的, 而jenkins 需要额外部署, 单这一点,足以让部分人选择它。
优点2:
Cloud build的配置简单, 学习成本低
对比起Jenkins 那复杂的一堆配置。。。
Cloudbuild 的部署步骤用yaml 编写, 跟Ansible 类似, 而Jenkins 的groovy script 学习曲线相对更陡峭
缺点1:
只适用于部署GCP的服务, 对于on-prem service 的部署比较吃力
缺点2:
配置简单, 但是没有jenkins 部署那么灵活, groovy script 功能更加强大
缺点3:
由于cloud build 的每个step 都在一个单独的容器内完成, 导致一些文件共享的问题
例如 如果有两个步骤, 第1个步骤 , mvn test 下载了1堆依赖
下1个步骤 mvn package 还是要下载同样的依赖。。。
总之
Cloudbuild 适合POC 场景下的部署, 快速简单.
Jenkins 更适合复杂场景的部署, 例如如果你的部署pipeline 需要包含 代码漏洞扫描, approval 流程系统集成 等其他步骤, 还是Jenkins 更方便
clould build yaml - 定义部署的步骤
用1个简单的例子:
我有1个简单的springboot service
https://github.com/nvd11/demo_cloud_user
想部署到google 的cloud run平台中。
步骤无非就是
- 编译 并 执行Junit cases - command: mvn test
- 打包成jar package - command: mvn package
- 打包成 docker image - command: docker build
- push docker image 到 Google Artifact Repository (google 镜像仓库)- command : docker pull 《image-path》
- 把镜像deploy 到 google cloud run 平台 - command: gcloud run deploy 《service name》–image=《image-path》。。
而上面提到, 其实每1个步骤就是1个命令
其中 步骤1和2执行的是mvn 的命令, 所以步骤1和2我们需要引入 mvn 的docker 镜像
步骤3和4是docker 命令, 需要引入包含docker/kaniko 的docker 镜像
步骤5 是gcloud 命令, 则需要 google sdk的docker 镜像
所以我们需要在springboot service 的项目主目录下新建1个cloudbuild.yaml (如果需要docker部署, dockerfile也还是需要的)
cloudbuild.yaml
steps:
- id: check maven and jdk version
name: maven:3.9-sapmachine-21 # https://hub.docker.com/_/maven
entrypoint: mvn
args: ['--version']
- id: run maven test
name: maven:3.9-sapmachine-21 # https://hub.docker.com/_/maven
entrypoint: mvn
args: ['test']
- id: run maven package
name: maven:3.9-sapmachine-21 # https://hub.docker.com/_/maven
entrypoint: mvn
args: ['package', '-Dmaven.test.skip=true']
# https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values
- id: build docker image
name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/demo-cloud-user', '.']
- id: upload docker image to GAR
name: 'gcr.io/cloud-builders/docker'
args: [ 'push', 'europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/demo-cloud-user']
# deploy to Cloud run
- id: deploy image to cloud run
name: 'gcr.io/cloud-builders/gcloud'
args: ['run', 'deploy', 'demo-cloud-user',
'--image=europe-west2-docker.pkg.dev/$PROJECT_ID/my-docker-repo/demo-cloud-user',
'--port=8080',
'--platform=managed',
'--region=europe-west2',
'--no-allow-unauthenticated',
'--service-account=vm-common@jason-hsbc.iam.gserviceaccount.com',
'--key=projects/$PROJECT_ID/locations/europe-west2/keyRings/mykeyring/cryptoKeys/mycmek']
# https://stackoverflow.com/questions/68779751/error-publishing-source-code-from-cloud-build-to-a-bucket-using-triggers
logsBucket: gs://jason-hsbc_cloudbuild/logs/
options: # https://cloud.google.com/cloud-build/docs/build-config#options
logging: GCS_ONLY # or CLOUD_LOGGING_ONLY https://cloud.google.com/cloud-build/docs/build-co
十分简单易懂:
其中Google 已经允许在Cloudbuild 使用built-in的默认参数, 例如$PROJECT_ID 代替真实的gcp project id
参考:
https://cloud.google.com/build/docs/configuring-builds/substitute-variable-values
值得注意的是options- logging 如果配置了CLOUD_LOGGING_ONLY则cloud build 日志会发送到google 日子平台
日志格式:
如果是选择GCS_ONLY 则需要配置logsBucket
日志格式:
个人更喜欢更简介的第2种。
用Cloud build trigger 触发部署
当写好cloudbuild.yaml写好后, 有两种方法出发部署
第一种是使用cloud build trigger
所谓cloud build trigger 就是让你的代码仓库的更新事件(commit/pull request) 去触发一个部署
而目前代码仓库只支持github 和 bitbucket, 置于国内的gitee, coding之类或者gitlab 私有化部署的代码仓库不支持
新建1个trigger 的详细步骤
1.打开trigger 的google console 页面, 点击新建trigger button
填写trigger 参数
有几个关键参数
region: 建议和您的其他resource 的region保持一致,减少网络传输距离
Name: cloudbuild的名字, 必填
Repository: 就是你的代码仓库, 第一次使用,需要配置google cloud 到github Oauth2 授权
branch: 就是制定某个branch的时间, 可以用.*代替全部branch, 建议只写某几个release branch
Event:有3个选项, 这里不解释了
1.push to a new branch
2.push new tag
3.pull request
Cloud Build configuration file location:
默认是 /cloudbuild.yaml 当然可以改成其他的, 让1个项目可以多种部署参数。
Service account: 部署所以用的service account, 如果不填, 则用cloud build 本身的agent service account 去部署, 权限问题是个坑。
注意上面的步骤也可以用terraform管理
触发Trigger
有两种方式, 1就是真的去修改代码, 利用commit/pull request/tag 事件出发
2是在ui上按run
查看build 状态和历史
部署历史的dashboard 能在UI上查看
点进去某个item 就能看详细的日志
当然用命令行也是可以的, 但是不太方便, 主要是查看具体日志的部分, 暂时我只能基于bucket 里的日志来查看:
Service URL: https://demo-cloud-user-7hq3m4pdya-nw.a.run.app
[gateman@manjaro-x13 demo_cloud_user]$ gcloud builds list --region=europe-west2
ID CREATE_TIME DURATION SOURCE IMAGES STATUS
499f567c-10c9-4ae3-9456-d29bbc02168a 2024-05-01T18:21:10+00:00 3M21S - - SUCCESS
6eec19d7-d7dc-4b51-8c5a-57a00879f044 2024-05-01T18:00:28+00:00 3M16S - - SUCCESS
678554d2-b56b-4c5b-a81a-61addde1bc46 2024-05-01T15:03:33+00:00 3M19S - - SUCCESS
d9ef5b26-52c6-4278-b1b1-e42ec5d456ad 2024-04-23T15:31:07+00:00 2M46S - - SUCCESS
85946729-b839-4d42-9fda-e610f4333ba2 2024-04-23T15:02:02+00:00 2M37S - - FAILURE
d636308d-2c19-4c59-9943-6371b185a022 2024-04-22T19:16:26+00:00 2M35S - - SUCCESS
114660c2-6c23-410e-8bf9-76877dcd3bb0 2024-04-22T19:02:52+00:00 17S - - SUCCESS
8d21277c-51c5-4f59-8a00-6db5d1dbd837 2024-04-22T18:34:56+00:00 35S - - FAILURE
b3221243-5ada-4ccb-958e-c06ce127e788 2024-04-22T18:28:51+00:00 - - - FAILURE
e1fde2bf-b7a1-47aa-9629-b3561c2dcca0 2023-11-04T20:54:29+00:00 1M38S - - SUCCESS
[gateman@manjaro-x13 demo_cloud_user]$ gsutil cat gs://jason-hsbc_cloudbuild/logs/log-499f567c-10c9-4ae3-9456-d29bbc02168a-step-5.txt
Already have image (with digest): gcr.io/cloud-builders/gcloud
Deploying container to Cloud Run service [demo-cloud-user] in project [jason-hsbc] region [europe-west2]
Deploying...
Setting IAM Policy.............done
Creating Revision..........................................................................................................................................................................................................done
Routing traffic.....done
Done.
Service [demo-cloud-user] revision [demo-cloud-user-00006-v9c] has been deployed and is serving 100 percent of traffic.
Service URL: https://demo-cloud-user-7hq3m4pdya-nw.a.run.app
用google SDK 命令行去触发
这种方法无需配置trigger, 只需要在local 本地或者安装有google sdk 的环境下
进入代码项目的folder
执行
gcloud builds submit --config=path/to/custom-build-config.yaml
config 参数可以不写, 默认的config 位置就是./cloudbuild.yaml
这种trigger 方式还有这些好处
- 无需关心git remote 的地址, 支持任何项目, 甚至没有交给git管理的项目
- 无需commit 代码就可以触发build, 随改随部署
例子:
[gateman@manjaro-x13 demo_cloud_user]$ gcloud builds submit
Creating temporary tarball archive of 24 file(s) totalling 108.2 KiB before compression.
Some files were not included in the source upload.
Check the gcloud log [/home/gateman/.config/gcloud/logs/2024.05.02/03.17.04.250214.log] to see which files and the contents of the
default gcloudignore file used (see `$ gcloud topic gcloudignore` to learn
more).
Uploading tarball of [.] to [gs://jason-hsbc_cloudbuild/source/1714591025.18917-5d48d906138b4c9d906c9ceb47c62898.tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/jason-hsbc/locations/global/builds/8bf33682-33a3-452c-9653-5966a35e1611].
Logs are available at [ https://console.cloud.google.com/cloud-build/builds/8bf33682-33a3-452c-9653-5966a35e1611?project=912156613264 ].
ID CREATE_TIME DURATION SOURCE IMAGES STATUS
8bf33682-33a3-452c-9653-5966a35e1611 2024-05-01T19:16:48+00:00 2M57S gs://jason-hsbc_cloudbuild/source/1714591025.18917-5d48d906138b4c9d906c9ceb47c62898.tgz - SUCCESS
至于具体日志,还是建议去console 上查看
cloud build 的一些坑
1. gcloud SDK 执行的cloud build 的region 是global (non-region)
这个是google 暂时的limitation
导致两个问题:
1. 在gcp console 上我们必须用global region 去filter google sdk出发的cloudbuild 历史和看日志, 这代表 用trigger 出发和google sdk出发的cloudbuild 历史不在同1页上
2. gcloud builds submit command 默认下会尝试在 us region(人类希望的大本营) 创建bucket, 如果你的gcp project 所在的organization policy限制了us region的权限, 则你会遇到这个错误:
ERROR: (gcloud.builds.submit) HTTPError 412: 'us' violates constraint 'constraints/gcp.resourceLocations'
原因: cloud build 无法在us region 创建staging folder
https://cloud.google.com/sdk/gcloud/reference/builds/submit#–gcs-source-staging-dir
解决方法1:
ERROR: (gcloud.builds.submit) HTTPError 412: 'us' violates constraint 'constraints/gcp.resourceLocations'
解决方法2:
创建bucket gs://_cloudbuild/ bucket
我采用了第二种
glcoud builds build 所以的service account 是cloud build 默认的agent account
即使你用admin account 执行 gcloud build 命令, 默认下它用的是 cloud build 的agent account
最好预先分配好权限, 否则部署cloud run/ GKE 时很可能会失败
当然用下面页面分配也是可以的
还有一种方法,
可以用 glcoud builds build --account=emailaddr 来强制使用某个service account来部署, 前提是这个service account 已经在当前环境用gcloud auth 登陆