如何在 VPC Service Controls 边界内安排 Cloud Run 作业

1. 简介

概览

如果您的 GCP 项目位于 VPC SC 边界内,则需要执行额外的步骤才能设置预定作业。由于 Cloud Scheduler 无法直接触发 VPC SC 边界内的作业,因此您需要通过其他组件代理请求。我们建议使用 Cloud Run 服务作为此代理。

架构如下所示:

Cloud Scheduler 触发执行 Cloud Run 作业的 Cloud Run 服务的示意图

学习内容

  • 如何在 VPC SC 边界内按计划运行 Cloud Run 作业
  • 如何使用 Cloud Run 客户端库创建可触发 Cloud Run 作业的 Cloud Run 服务
  • 如何配置 Cloud Scheduler 以按计划调用 Cloud Run 服务

2. 准备工作

首先,请确保您已按照相关步骤为 VPC Service Controls 设置 Cloud Run。

接下来,设置将在本 Codelab 中全程使用的环境变量。

PROJECT_ID=<YOUR_PROJECT_ID>
REGION=<YOUR_REGION>
AR_REPO=sample-job-repo
CLOUD_RUN_SERVICE=job-runner-service
CLOUD_RUN_JOB=sample-job
CLOUD_SCHEDULER=job-scheduler
SERVICE_ACCOUNT="cloud-run-invoker-sa"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com
NETWORK=default
SUBNET=default

3. 创建 Cloud Run 作业

此 Codelab 使用示例 Cloud Run 作业容器。

首先,为 Cloud Run 作业容器创建 Artifact Registry 代码库。

gcloud artifacts repositories create $AR_REPO --repository-format=docker --location=$REGION --description="codelab for Cloud Run jobs on schedule within VPC SC"

接下来,将示例 Cloud Run 作业容器复制到已配置 VPC SC 的项目中的 Artifact Registry。您可以按照这些安装说明使用 gcrane 工具来完成此操作。如需详细了解 gcrane,请参阅有关在代码库之间复制映像的文档

gcrane cp us-docker.pkg.dev/cloudrun/container/job:latest $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$CLOUD_RUN_JOB:latest

其次,部署符合 VPC Service Controls 要求的 Cloud Run 作业。

gcloud run jobs create $CLOUD_RUN_JOB --region $REGION \
 --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$CLOUD_RUN_JOB:latest \
 --network=$NETWORK \
 --subnet=$SUBNET \
 --vpc-egress=all-traffic

如需详细了解如何创建作业,请按照《Cloud Run 作业》文档中列出的步骤操作。

4. 创建服务账号

Cloud Run 将使用此服务账号来调用 Cloud Run 作业。

首先,运行以下命令创建服务账号:

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run to run a Cloud Run job"

其次,向该服务账号授予 Cloud Run Invoker 角色和 Cloud Run Viewer 角色。

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/run.invoker

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/run.viewer

5. 创建 Cloud Run 服务

在此步骤中,您将部署一个充当代理的 Cloud Run 服务。

mkdir job-runner-service && cd $_

创建一个名为 main.py 且包含以下代码的文件。

import os
from flask import Flask
app = Flask(__name__)

# pip install google-cloud-run
from google.cloud import run_v2

@app.route('/')
def hello():

    client = run_v2.JobsClient()

    # UPDATE TO YOUR JOB NAME, REGION, AND PROJECT ID
    job_name = 'projects/YOUR_PROJECT_ID/locations/YOUR_JOB_REGION/jobs/YOUR_JOB_NAME' 

    print("Triggering job...")
    request = run_v2.RunJobRequest(name=job_name)
    operation = client.run_job(request=request)
    response = operation.result()

    print(response)
    return "Done!"

if __name__ == '__main__':
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

创建一个名为 requirements.txt 且包含以下代码的文件。

google-cloud-run
flask

最后,创建一个 Dockerfile

FROM python:3.9-slim-buster
# for logging purposes
ENV PYTHONUNBUFFERED=True

WORKDIR /app

COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

COPY . .

CMD ["python3", "main.py"]

接下来,使用以下 Docker 命令构建容器。请注意,在 VPC SC 环境中设置基于源代码的部署可能很困难。如果您已有构建和部署流水线,请使用该流水线将源代码构建到容器中,并将该容器部署为 Cloud Run 服务。

docker build -t $CLOUD_RUN_SERVICE .

docker tag $CLOUD_RUN_SERVICE $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$CLOUD_RUN_SERVICE

docker push $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$CLOUD_RUN_SERVICE

现在,部署符合 VPC Service Controls 要求的 Cloud Run 服务。

gcloud run deploy $CLOUD_RUN_SERVICE --region $REGION \
 --image $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$CLOUD_RUN_SERVICE \
 --service-account $SERVICE_ACCOUNT_ADDRESS \
 --network=$NETWORK \
 --subnet=$SUBNET \
 --vpc-egress=all-traffic \
 --no-allow-unauthenticated \
 --ingress internal

运行以下命令,保存服务端点网址:

SERVICE_URL=$(gcloud run services describe $CLOUD_RUN_SERVICE --region $REGION --format 'value(status.url)')

6. 创建 Cloud Schedule 作业以触发服务

# create the Cloud Scheduler job
gcloud scheduler jobs create http $CLOUD_SCHEDULER \
  --location=$REGION \
  --schedule="0 0 1 * *" \
  --uri=$SERVICE_URL \
  --http-method=GET \
  --oidc-service-account-email=$SERVICE_ACCOUNT_ADDRESS

创建 Cloud Scheduler 作业后,您可以运行以下命令立即运行 Cloud Scheduler 作业,以进行测试:

gcloud scheduler jobs run $CLOUD_SCHEDULER --location=$REGION

注意:

您可能需要等待几分钟,作业执行才能完成。您可以在 Cloud Run 调度器页面上跟踪其状态。

运行以下命令,验证 Cloud Run 作业是否已成功运行:

EXECUTION_NAME=$(gcloud run jobs describe $CLOUD_RUN_JOB --region $REGION --format 'value(status.latestCreatedExecution.name)')

gcloud run jobs executions describe $EXECUTION_NAME --region $REGION

您应该会看到类似以下内容:

✔ Execution sample-job-w6hrj in region us-central1
1 task completed successfully
Elapsed time: 28 seconds

7. 恭喜!

恭喜您完成此 Codelab!

所学内容

  • 如何在 VPC SC 边界内按计划运行 Cloud Run 作业
  • 如何使用 Cloud Run 客户端库创建可触发 Cloud Run 作业的 Cloud Run 服务
  • 如何配置 Cloud Scheduler 以按计划调用 Cloud Run 服务

8. 清理

为避免产生意外费用(例如,如果 Cloud Run 服务被意外调用的次数超过了免费层级中每月 Cloud Run 调用次数的分配额度),您可以删除 GCP 服务,也可以删除您在第 2 步中创建的项目。

如需删除 Cloud Run 服务和 Cloud Run 作业,请前往 Cloud Run Cloud 控制台 (https://console.cloud.google.com/run) 并删除相应服务。

如果您选择删除整个项目,可以前往 https://console.cloud.google.com/cloud-resource-manager,选择您在第 2 步中创建的项目,然后选择“删除”。如果您删除项目,则需要在 Cloud SDK 中更改项目。您可以运行 gcloud projects list 查看所有可用项目的列表。