如何为 Cloud Build 用于 Cloud Run 部署的 Cloud Storage 存储分区指定区域?

Posted

技术标签:

【中文标题】如何为 Cloud Build 用于 Cloud Run 部署的 Cloud Storage 存储分区指定区域?【英文标题】:How can I specify a region for the Cloud Storage buckets used by Cloud Build for a Cloud Run deployment? 【发布时间】:2020-07-13 20:42:35 【问题描述】:

在将 docker 容器镜像部署到 Cloud Run 时,我可以选择一个区域,这很好。 Cloud Run 将构建委托给 Cloud Build,后者显然会创建两个存储桶来实现这一点。出乎意料的行为是未在 Cloud Run 部署的区域中创建存储桶,而是默认为多区域美国。

如何将区域指定为“us-east1”,以便“始终免费”层吸收存储成本?(显然,美国多区域存储桶将数据存储在外部区域免费层限制,这导致了一个意外的账单 - 我试图避免这个账单。)

如果重要的话,我也在这个项目中使用 Firebase。我在 us-east1 区域创建了 Firebase 默认存储桶,希望它也可能成为其他桶的默认存储桶,但事实并非如此。最终的存储桶列表如下所示,您可以在其中看到使用不受欢迎的多区域设置自动创建的两个存储桶。

这是我用来构建和部署的 shell 脚本:

#!/bin/sh

project_id=$1
service_id=$2

if [ -z "$project_id" ]; then
    echo "First argument must be the Google Cloud project ID" >&2
    exit 1
fi

if [ -z "$service_id" ]; then
    echo "Second argument must be the Cloud Run app name" >&2
    exit 1
fi

echo "Deploying $service_id to $project_id"

tag="gcr.io/$project_id/$service_id"

gcloud builds submit \
    --project "$project_id" \
    --tag "$tag" \
&& \
gcloud run deploy "$service_id" \
    --project "$project_id" \
    --image "$tag" \
    --platform managed \
    --update-env-vars "GOOGLE_CLOUD_PROJECT=$project_id" \
    --region us-central1 \
    --allow-unauthenticated

【问题讨论】:

我认为这是 ***.com/questions/51595900/… 的副本。您应该仍然可以发送电子邮件至 cloud-build-contact@google.com 以访问抢先体验计划。 根本不是,实际上问题是关于工件存储在哪个区域或区域。 @DustinIngram 这只是关于存储工件的区域。我不在乎处理构建的计算资源在哪里,甚至它们如何工作。我只是在运行 gcloud 命令来构建和部署。我已将问题编辑为具体说明。 @FernandoRV 是的,这只是关于工件。我看到了一些关于使用 yaml 文件的说明,这些文件让您可以指定容器注册表,但这似乎有点过头了,而且似乎没有任何简单的 gcloud CLI 选项来讨论如何管理这些存储桶。 明白了,抱歉我看错了! 【参考方案1】:

正如您所提到的,Cloud Build 创建了一个或多个具有多区域的存储桶,因为在 Cloud Run 中创建服务时,只添加了部署服务所需的标志和参数。

命令gcloud builds submit 的documentation 提到标志--gcs-source-staging-dir 的以下内容:

--gcs-source-staging-dir=GCS_SOURCE_STAGING_DIR

Google Cloud Storage 中的一个目录,用于复制用于暂存构建的源代码。如果指定的存储桶不存在,Cloud Build 将创建一个。如果不设置此字段,则使用 gs://[PROJECT_ID]_cloudbuild/source。

由于未设置此标志,因此在 multi-regionus 中创建存储桶。此行为也适用于标志 --gcs-log-dir

现在,在您想要的双区域、区域或多区域中使用存储桶的必要步骤是使用 cloudbuild.yaml 并使用标志 --gcs-source-staging-dir。您可以执行以下操作:

    在您可能需要的区域、双区域或多区域中创建存储桶。例如,我在australia-southeast1 中创建了一个名为“example-bucket”的存储桶。 创建一个cloudbuild.yaml 文件。这是将构建的工件存储在您想要的存储桶中所必需的,如here 所述。一个例子如下:
steps:
- name: 'gcr.io/cloud-builders/gcloud'
    args:
    - 'run'
    - 'deploy'
    - 'cloudrunservice'
    - '--image'
    - 'gcr.io/PROJECT_ID/IMAGE'
    - '--region'
    - 'REGION_TO_DEPLOY'
    - '--platform'
    - 'managed'
    - '--allow-unauthenticated'
artifacts:
    objects:
    location: 'gs://example-bucket'
    paths: ['*']
    最后你可以运行以下命令:
gcloud builds submit --gcs-source-staging-dir="gs://example-bucket/cloudbuild-custom" --config cloudbuild.yaml

前面提到的步骤可以适应您的脚本。请试一试 :) 你会发现即使 Cloud Run 服务部署在亚洲、欧洲或美国,之前指定的存储桶也可以在其他位置。

【讨论】:

好的,完美。我浏览了那个手册页,完全错过了最好的东西。听起来这里需要创建一个 yaml 文件?如果我提前手动创建了具有预期名称的存储桶怎么办?看起来在我的案例中创建了两个存储桶——“staging”和“artifacts”。 有趣的事实:我删除了两个存储桶,重新创建了 _cloudbuild 后缀一个 OK,但无法重新创建工件,因为它需要域名验证。但是一个新的部署再次使桶(我们多区域)。是否可以在不需要 yaml 文件的情况下指定目标存储桶? 是的,实际上Bucket and object naming guidelines 中提到包含点的名称需要验证,因为它们是appspot.com 域的一部分。在多区域中创建的存储桶似乎是 GCP 创建最靠近资源位置的存储桶的逻辑的一部分。例如,如果我在eu.gcr.io 中部署和映像,则将在eu 中创建一个多区域存储桶。如果图像位于 gcr.ioasia.gcr.io 以及它们各自的多区域存储桶中,则此行为类似。 因此,总而言之,目前没有 yaml 文件来设置 artifacts 存储桶是不可能的,并且可以是 feature request 以供 Cloud Build 选择设置工件位置使用标志。只有staging 存储桶才可以使用标志。 忘了提到 [PROJECT_ID]_cloudbuild 存储桶可以在任何位置创建,Cloud Build 将毫无问题地使用该存储桶。【参考方案2】:

看起来这只有通过执行您在 cmets 中提到的操作才能实现:

    us-east1中创建一个存储桶作为源桶($SOURCE_BUCKET); 在 us-east1 中创建 Artifact Registry 存储库; 创建以下cloudbuild.yaml
    steps:
    - name: 'gcr.io/cloud-builders/docker'
      args: ['build', '-t', 'us-east1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image', '.']
    images:
    - 'us-east1-docker.pkg.dev/$PROJECT_ID/my-repo/my-image'
    
    部署:
    $ gcloud builds submit --config cloudbuild.yaml --gcs-source-staging-dir=gs://$SOURCE_BUCKET/source
    

更多详情:https://cloud.google.com/artifact-registry/docs/configure-cloud-build

我认为至少应该可以使用 --tag 选项指定 Artifact Registry 存储库并自动创建它,但它目前拒绝任何不是 gcr.io 的域。

【讨论】:

而且我无法创建默认的工件注册表存储桶,因为它包含一个点并且需要域名验证。希望完全避免使用 yaml,只使用默认值。 当我尝试这个时,它根本没有创建第二个存储桶,因为 cloudbuild.yaml 没有配置为上传构建工件,只有生成的图像(不进入 GCS 存储桶显然)。

以上是关于如何为 Cloud Build 用于 Cloud Run 部署的 Cloud Storage 存储分区指定区域?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Firebase 取消部署 Cloud Functions?

如何为测试、暂存和生产配置 Google Cloud Pub/Sub?

Spring Cloud,配置服务器无法启动,如何为git配置uri

您如何为 Google Cloud 平台签署 HIPAA BAA?

如何为开发目的禁用 Spring Cloud Stream 绑定?

如何为 Google Cloud Messaging 实现服务器以发送推送通知 android studio