如果您设置了具有适当凭据的关联服务账号,则 Cloud Scheduler 可以调用需要身份验证的 HTTP 目标。
设置服务账号
服务账号通常供应用或计算工作负载使用,由其专属的邮箱标识。
应用可以使用服务账号来执行已获授权的 API 调用,方法是以服务账号本身的身份进行身份验证,并访问该服务账号有权访问的所有资源。
若要让应用使用服务账号证明其身份,最常见的方法是将服务账号关联到运行该应用的资源。然后,您可以向服务账号授予 Identity and Access Management (IAM) 角色,让该服务账号可以访问相应的 Google Cloud 资源。
如果您还没有要用于具有 HTTP 目标的 Cloud Scheduler 作业的服务账号,请创建一个新的服务账号。请注意以下几点:
服务账号必须属于在其中创建 Cloud Scheduler 作业的项目。
请勿使用 Cloud Scheduler 服务代理 (
service-PROJECT_NUMBER@gcp-sa-cloudscheduler.)。它不能用于此目的。请勿从项目中的 Cloud Scheduler 服务代理撤消 Cloud Scheduler Service Agent 角色 (
roles/cloudscheduler.serviceAgent)。这样做会导致对需要身份验证的端点产生403响应,即使作业的服务账号具有适当的角色也是如此。
如果您的目标位于 Google Cloud中,请向您的服务账号授予必要的 IAM 角色。 Google Cloud 中的每项服务都需要特定角色,接收服务会自动验证生成的令牌。
例如,对于 Cloud Run 和 Cloud Run functions,您必须授予 Cloud Run Invoker (
roles/run.invoker) 角色,而对于 Cloud Functions(第 1 代),您必须授予 Cloud Functions Invoker (roles/cloudfunctions.invoker) 角色。如需获得将服务账号关联到资源所需的权限,请让您的管理员为您授予服务账号的 Service Account User (
roles/iam.serviceAccountUser) IAM 角色。此预定义角色可提供将服务账号关联到资源所需的iam.serviceAccounts.actAs权限。(如果您创建了服务账号,则会自动获得此权限。)在上一步中,如果您专门创建了一个服务账号来调用 Cloud Scheduler 作业定位的服务,则可以遵循最小权限原则,将该账号及其调用者权限绑定到目标服务:
控制台
在 Google Cloud 控制台的项目选择器页面上,选择一个Google Cloud 项目。
前往您要调用的资源类型的页面。例如,如果您要调用 Cloud Run 服务,请前往列出 Cloud Run 服务的页面。
选中要调用的服务左侧的复选框。(请勿点击服务本身。)
点击 权限标签页。
如果未显示信息窗格,您可能需要点击显示信息面板 > 权限。
点击 添加主账号。
在新的主账号字段中,输入您创建的服务账号的电子邮件地址。
从选择角色列表中,选择要授予的角色。
遵循最小权限原则,选择仅包含主账号所需权限的角色。
点击保存。
gcloud
gcloud RESOURCE_TYPE add-iam-policy-binding RESOURCE_ID \ --member=PRINCIPAL \ --role=ROLE替换以下内容:
RESOURCE_TYPE:目标的资源类型。 例如,对于 Cloud Run 服务目标,请使用run services。RESOURCE_ID:目标的标识符。例如,Cloud Run 服务的名称。PRINCIPAL:服务账号的标识符。其格式如下:serviceAccount:SERVICE_ACCOUNT_EMAIL_ADDRESS。例如,serviceAccount:my-service-account@my-project.。ROLE:目标服务调用所需的角色名称。例如,对于 Cloud Run 服务目标,为roles/run.invoker。对于 Cloud Run functions 目标,我们建议使用add-invoker-policy-binding命令。
示例:
使用
gcloud run services add-iam-policy-binding命令向 Cloud Run 服务my-service上的服务账号my-service-account@my-project.授予 Cloud Run Invoker (roles/run.invoker) IAM 角色:gcloud run services add-iam-policy-binding my-service \ --region=REGION \ --member=serviceAccount:my-service-account@my-project. \ --role=roles/run.invoker使用
gcloud functions add-invoker-policy-binding命令向 Cloud Run 函数my-cloud-function上的服务账号my-service-account@my-project.授予适当的角色。对于 Cloud Run functions,这会将 Cloud Run Invoker (
roles/run.invoker) 绑定添加到指定函数的底层 Cloud Run 服务的 IAM 政策中。对于 Cloud Functions(第 1 代),这会将 Cloud Functions Invoker (roles/cloudfunctions.invoker) 绑定添加到指定函数的 IAM 政策:gcloud functions add-invoker-policy-binding my-cloud-function \ --region=REGION \ --member=serviceAccount:my-service-account@my-project.
如需查看使用 Terraform 创建有权调用 Cloud Run 服务的服务账号的示例,请参阅为 Cloud Scheduler 创建服务账号。
如果您的目标位于 Google Cloud之外,则接收服务必须手动验证令牌。
当您启用 Cloud Scheduler API 时,系统会自动设置默认 Cloud Scheduler 服务代理,除非您在 2019 年 3 月 19 日之前启用了该 API,在这种情况下,您必须授予 Cloud Scheduler Service Agent 角色。这样,它就可以代表您的服务账号生成标头令牌,以便向目标进行身份验证。
创建使用身份验证的 Cloud Scheduler 作业
为了在 Cloud Scheduler 和 HTTP 目标之间进行身份验证,Cloud Scheduler 会根据您的客户端服务账号(由其电子邮件地址标识)创建一个标头令牌,并使用 HTTPS 将其发送到目标。您可以使用 ID (OIDC) 令牌或 OAuth(访问)令牌。通常使用 OIDC,但 *.googleapis.com 上托管的 Google API 除外:这些 API 需要 OAuth 令牌,并且 Cloud Scheduler 仅接受 *.googleapis.com 上托管的目标网址的 OAuth 令牌。
如需创建使用身份验证的 Cloud Scheduler 作业,您必须在创建作业时添加令牌类型和标识客户端服务账号的电子邮件地址:
控制台
在 Google Cloud 控制台中,前往 Cloud Scheduler 页面。
点击 创建作业。
在名称字段中,为作业输入一个在项目和区域中唯一的名称。删除关联的作业后,您可以重复使用作业名称。
在区域列表中,为您的作业选择一个区域。
为作业指定频率和时区。 您在此处提供的字符串可以是任何与 unix-cron 兼容的字符串。
点击继续。
在目标类型列表中,选择 HTTP。
指定以
https://开头的网址和 HTTP 方法。可选:在 HTTP 标头部分中,添加任何 HTTP 请求标头。如果目标端点要求在请求标头中提供 API 密钥,请使用目标服务所需的标头名称,例如 API Gateway 和 Cloud Endpoints 的
x-api-key,或Google Cloud REST API 的X-Goog-Api-Key。使用api_key作为标头名称可能会导致身份验证失败。如需了解详情,请参阅使用 API 密钥访问 API 和使用 API 密钥(在 API Gateway 中)。在Auth 标头列表中,选择令牌类型。通常使用 OIDC 令牌,但
*.googleapis.com上托管的 Google API 除外,因为这些 API 需要 OAuth 令牌。在服务账号列表中,选择您的服务账号电子邮件地址。
可选:指定受众群体,以限制 OIDC 令牌的接收者;通常是指作业的目标网址(不带任何网址参数)。如果未指定,则整个网址(包括请求参数)将用作目标对象。
配置任何可选设置。
点击创建。
gcloud
gcloud scheduler jobs create http JOB_ID \ --location=LOCATION \ --schedule="FREQUENCY" \ --uri=URI \ --oidc-service-account-email=SERVICE_ACCOUNT_EMAIL
替换以下内容:
JOB_ID:作业的名称,在项目和区域中是唯一的。删除关联的作业后,您可以重复使用作业名称。LOCATION:作业的位置(区域)。FREQUENCY:作业运行的时间间隔或频率;例如every 3 hours或every 10 mins。 您在此处提供的字符串可以是任何与 unix-cron 兼容的字符串。URI:端点的完全限定 HTTPS 网址(必须以https://开头)。SERVICE_ACCOUNT_EMAIL:服务账号的邮箱。通常使用 OIDC 令牌,但*.googleapis.com上托管的 Google API 除外,因为这些 API 需要 OAuth 令牌。(请改用--oauth-service-account-email标志来定义 OAuth 令牌类型。)
gcloud 命令行参考文档中介绍了其他可选参数。例如,您可以使用 --headers 标志来包含 HTTP 请求标头。如果目标端点要求在请求标头中提供 API 密钥,请使用目标服务所需的标头名称,例如 API Gateway 和 Endpoints 的 x-api-key,或 Google Cloud REST API 的 X-Goog-Api-Key。使用 api_key 作为标头名称可能会导致身份验证失败。如需了解详情,请参阅使用 API 密钥访问 API 和使用 API 密钥(在 API Gateway 中)。
授予 Cloud Scheduler Service Agent 角色
某些 Google Cloud 服务需要访问您的资源才能代表您执行操作。为了满足这一需求, Google Cloud 会创建和管理称为服务代理的服务账号,这些账号会在您启用和使用 Google Cloud服务时自动创建并被授予角色。
Cloud Scheduler 服务代理需要 Cloud Scheduler Service Agent (roles/cloudscheduler.serviceAgent) 角色。如果没有此角色,需要服务代理的 Cloud Scheduler 作业(例如使用身份验证的 HTTP 目标作业和 Pub/Sub 目标作业)将会失败。您可以手动向 Cloud Scheduler 服务代理授予该角色,该代理的电子邮件地址采用以下格式:
service-PROJECT_NUMBER@gcp-sa-cloudscheduler.
仅在以下任一情况成立时,您才需要手动授予该角色:
- 您在 2019 年 3 月 19 日之前启用了 Cloud Scheduler API
- 您已从服务代理中移除 Cloud Scheduler Service Agent 角色
您可以通过查看项目的当前访问权限,验证您的项目中是否设置了 Cloud Scheduler 服务代理,以及该代理是否已被授予 Cloud Scheduler Service Agent 角色。请注意,如果您使用 Google Cloud 控制台查看项目的访问权限,请务必选中包括 Google 提供的角色授权复选框。
如需了解如何向服务代理授予角色,请参阅创建服务代理并授予角色。