如果您的架构使用多项服务,则这些服务可能需要使用异步或同步方式相互通信。其中许多服务可能是私有的,因此需要凭据才能访问。
对于异步通信,您可以使用以下 Google Cloud 服务:
- Cloud Tasks(用于一对一异步通信)
- Pub/Sub(用于一对多、一对一和多对一异步通信)
- Cloud Scheduler(用于定期安排的异步通信)
- Eventarc(用于基于事件的通信)
在所有这些情况下,使用的服务都会根据您设置的配置管理与接收服务的交互。
但对于同步通信,您的服务会使用其端点网址通过 HTTP 直接调用其他服务。对于此使用场景,您应确保每项服务只能向特定服务发出请求。例如,如果您拥有 login
服务,则该服务应该能够访问 user-profiles
服务,但不能访问 search
服务。
在这种情况下,Google 建议您使用基于每项服务的用户管理服务账号的 IAM 和服务身份,该服务账号已被授予执行其工作所需的一组最低权限
此外,该请求还必须提供发起调用的服务的身份证明。为此,请配置调用服务,以将 Google 签名的 OpenID Connect ID 令牌添加到请求中。
设置服务账号
如需设置服务账号,请将接收服务配置为接受来自调用服务的请求,方法是将调用服务的服务账号设为接收服务的主账号。然后,向该服务账号授予 Cloud Run Invoker (roles/run.invoker
) 角色。如需执行这两项任务,请按照相应标签页中的说明进行操作:
控制台界面
前往 Google Cloud 控制台:
选择接收方服务。
点击右上角的显示信息面板,以显示权限标签页。
点击添加主账号。
输入调用服务的身份。默认情况下,通常是一个电子邮件地址 (
PROJECT_NUMBER-compute@developer.gserviceaccount.com
)。从选择角色下拉菜单中选择
Cloud Run Invoker
角色。点击保存。
gcloud
使用 gcloud run services add-iam-policy-binding
命令:
gcloud run services add-iam-policy-binding RECEIVING_SERVICE \ --member='serviceAccount:CALLING_SERVICE_IDENTITY' \ --role='roles/run.invoker'
其中,RECEIVING_SERVICE
是接收服务的名称,CALLING_SERVICE_IDENTITY
是服务账号的电子邮件地址,默认情况下为 PROJECT_NUMBER-compute@developer.gserviceaccount.com
。
Terraform
如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令。
以下 Terraform 代码会创建要公开的初始 Cloud Run 服务。
将 us-docker.pkg.dev/cloudrun/container/hello
替换为对您的容器映像的引用。
以下 Terraform 代码将初始服务设为公开。
以下 Terraform 代码创建第二个将设为私有的 Cloud Run 服务。
将 us-docker.pkg.dev/cloudrun/container/hello
替换为对您的容器映像的引用。
以下 Terraform 代码将第二个服务设为私有。
以下 Terraform 代码会创建一个服务账号。
以下 Terraform 代码允许附加到服务账号的服务调用初始私有 Cloud Run 服务。
获取并配置 ID 令牌
为调用方服务账号授予适当的角色后,请按以下步骤操作:
使用以下部分中介绍的方法之一提取 Google 签名的 ID 令牌。将受众群体声明 (
aud
) 设置为接收服务的网址或已配置的自定义受众群体。 如果您未使用自定义受众群体,则aud
值必须保留为服务的网址,即使向特定流量标记发出请求时也是如此。将您在上一步中提取的 ID 令牌添加到对接收服务的请求中的以下标头之一:
Authorization: Bearer ID_TOKEN
标头。X-Serverless-Authorization: Bearer ID_TOKEN
标头。如果您的应用已使用Authorization
标头进行自定义授权,则可以使用此标头。这会移除签名,然后再将令牌传递给用户容器。
如需了解获取本页面上未介绍的 ID 令牌的其他方法,请参阅获取 ID 令牌的方法。
使用身份验证库
获取和配置 ID 令牌过程的最简单、最可靠的方法是使用身份验证库。此代码可在库可以获取服务账号身份验证凭据的任何环境中工作(甚至在 Google Cloud 外部),包括支持本地应用默认凭据的环境。如需设置应用默认凭据,请下载服务账号密钥文件,并将环境变量 GOOGLE_APPLICATION_CREDENTIALS
设置为服务账号密钥文件的路径。如需了解详情,请参阅应用默认凭据的工作原理。
此代码无法用于获取用户账号的身份验证凭据。
Node.js
Python
Go
Java
使用元数据服务器
如果您因某种原因而无法使用身份验证库,则可以当容器正在 Cloud Run 上运行时从 Compute 元数据服务器提取 ID 令牌。请注意,此方法在 Google Cloud 以外无法使用,包括在本地机器中。
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=[AUDIENCE]" \
-H "Metadata-Flavor: Google"
其中 AUDIENCE 是您要调用的服务的网址或已配置的自定义受众群体。
下表总结了元数据查询请求的主要部分:
组件 | 说明 |
---|---|
根网址 | 所有元数据值都会定义为以下根网址下面的子路径: http://metadata.google.internal/computeMetadata/v1 |
请求标头 | 每个请求中都必须包含以下标头: Metadata-Flavor: Google 此标头表明请求是为了检索元数据值而发出的(而非由不安全的来源意外发出),并且允许元数据服务器返回您请求的数据。如果您不提供此标头,则元数据服务器会拒绝您的请求。 |
对于使用服务到服务身份验证技术的应用的端到端演示,请遵循教程:保护 Cloud Run 服务安全。
从 Google Cloud 外部使用工作负载身份联合
如果您的环境使用工作负载身份联合支持的身份提供方,则可以使用以下方法从 Google Cloud 外部安全地向 Cloud Run 服务进行身份验证:
按照本页面上的设置服务账号中的说明设置您的服务账号。
按照配置工作负载身份联合中的说明,为您的身份提供商配置工作负载身份联合。
按照授予外部身份模拟服务账号的权限中的说明操作。
使用 REST API 获取短期有效的令牌,但不是调用
generateAccessToken
来获取访问令牌,而是调用generateIdToken
来获取 ID 令牌。例如,使用 cURL:
ID_TOKEN=$(curl -0 -X POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT:generateIdToken \ -H "Content-Type: text/json; charset=utf-8" \ -H "Authorization: Bearer $STS_TOKEN" \ -d @- <<EOF | jq -r .token { "audience": "SERVICE_URL" } EOF ) echo $ID_TOKEN
其中,
SERVICE_ACCOUNT
是工作负载身份池配置来访问的服务账号的电子邮件地址,SERVICE_URL
是您正在调用的 Cloud Run 服务的网址。此值应保留为服务的网址,即使向特定流量标记发出请求也是如此。$STS_TOKEN
是您在工作负载身份联合说明的上一步中收到的 Security Token Service 令牌。
您可以使用 Authorization: Bearer ID_TOKEN
标头或 X-Serverless-Authorization: Bearer ID_TOKEN
标头将上一步中的 ID 令牌添加到对服务的请求中。如果同时提供了这两个标头,则系统仅会检查 X-Serverless-Authorization
标头。
从 Google Cloud 外部使用下载的服务账号密钥
如果工作负载身份联合不适合您的环境,您可以使用下载的服务账号密钥从 Google Cloud 外部进行身份验证。更新客户端代码以将上文所述的身份验证库与应用默认凭据结合使用。
您可以使用自签名 JWT 来获取由 Google 签名的 ID 令牌,但这可能非常复杂且很容易出错。基本步骤如下:
对服务账号 JWT 进行自签名,并将
target_audience
声明设置为接收服务的网址或已配置的自定义受众群体。 如果不使用自定义网域,则target_audience
值应保留为服务的网址,即使向特定流量标记发出请求时也是如此。用自签名 JWT 换取 Google 签名的 ID 令牌,该令牌的
aud
声明应设置为上述网址。使用
Authorization: Bearer ID_TOKEN
标头或X-Serverless-Authorization: Bearer ID_TOKEN
标头将该 ID 令牌添加到对服务的请求中。如果同时提供了这两个标头,则系统仅会检查X-Serverless-Authorization
标头。
接收通过身份验证的请求
在接收专用服务中,您可以解析授权标头以接收不记名令牌发送的信息。
Python
后续步骤
- 详细了解 ID 令牌验证