如何解决如何在 Google Cloud Build 中构建 Docker 映像并在以后的构建步骤中使用?
在我的 Rails 项目中,我在一个 repo 中有一个 Docker Image,用于数据库迁移和单元测试。在运行迁移/测试之前,我可能需要更新图像上的 gem。但是,似乎即使在更新 Gems 之后,更新的映像(未推送到存储库,而是在迁移/测试之前的构建步骤中)也无法用于未来的构建步骤。
我的 cloudbuild.yaml 如下所示:
steps:
- id: update_gems
name: 'gcr.io/cloud-builders/docker'
args: [ 'build','-t',"us-central1-docker.pkg.dev/$PROJECT_ID/myregistry/myimage:deploy",'--build-arg','PROJECT=${PROJECT_ID}','-f','docker/bundled.Dockerfile','.' ]
- id: db_migration
name: "gcr.io/google-appengine/exec-wrapper"
args: ["-i","-e","RAILS_ENV=${_RAILS_ENV}","INSTANCE_CONNECTION_NAME=${_INSTANCE_CONNECTION_NAME}","-s","${_INSTANCE_CONNECTION_NAME}","--","./bin/rake","db:migrate"]
- id: unit_test
name: "gcr.io/google-appengine/exec-wrapper"
args: ["-i","RAILS_ENV=test","./bin/rspec"]
- id: deploy_to_GAE
name: gcr.io/cloud-builders/gcloud
args: ['app','deploy','--project','${PROJECT_ID}','app.yaml']
第一步中引用的 Dockerfile 如下所示:
ARG PROJECT
FROM us-central1-docker.pkg.dev/${PROJECT}/myregistry/myimage:deploy
WORKDIR /workspace
ADD Gemfile* ./
RUN bundle update
RUN bundle install
在触发的 Cloud Build 期间,我看到它更新 Gems 并创建一个新的哈希,如下所示:
然后在 db_migration
步骤中,我看到它在更新 Gems 之前拉取了旧图像:
这可以在 update_gems
步骤日志中验证,其中预更新的图像哈希匹配(即新拉出的图像哈希,但尚未更新其 Gems):
我意识到一种解决方法是在构建后推送更新的图像,这实际上是有效的。例如,我可以在 update_gems
步骤之后添加此步骤:
- id: update_image
name: 'gcr.io/cloud-builders/docker'
args: [ 'push','us-central1-docker.pkg.dev/$PROJECT_ID/myregistry/myimage:deploy' ]
然而,它引出了一个问题,为什么新的 udate_image
构建步骤可以访问由 update_gems
步骤构建的映像,而其他后续步骤则不能。
解决方法
图像存储在本地的本地 docker 注册表中,Docker 可以访问该注册表。这就是为什么你可以用 Docker 推送它。
但是,当您使用另一个步骤(例如 gcr.io/google-appengine/exec-wrapper
)时,Docker 不再加载到运行时上下文中,因此本地 Docker 注册表未知/未激活。
所以,解决方案是:
- 要么从外部推送图像,然后使用它。像这样,它不是本地注册表,而是使用的外部注册表,它可以在任何步骤中工作。
- 或者在您当前的运行时步骤映像上安装 docker(或使用 Docker 作为步骤映像并在此映像上安装您需要的内容)-> 这会很困难,我不推荐这种方式。