Google Distributed Cloud (GDC) 空气隔离环境中的服务身份可为工作负载或服务提供专用身份,以便以编程方式安全地访问资源和微服务。这些是应用或工作负载(而非人员)使用的特殊身份,不能用于人工登录。与用户账号类似,您可以向服务身份授予权限和角色,以定义其获授权可访问的内容。
您可能会注意到,此概念使用了两个术语。GDC 控制台主要使用“服务身份”一词,而 gdcloud 命令和 API 交互通常使用“服务账号。后者反映了底层 Kubernetes 自定义资源 ProjectServiceAccount 的名称。这两个术语指的是同一事物:工作负载的非人类身份。本文档主要使用“服务身份”一词。
服务身份有助于管理 GDC 基础架构,例如:
- 内部 Distributed Cloud 服务和工作负载,用于安全访问 Distributed Cloud 控制平面应用编程接口 (API)。例如,数据库服务与 Kubernetes API 交互以创建和删除数据库。
- Distributed Cloud 中的客户工作负载,用于访问 Distributed Cloud 服务并进行授权的应用编程接口 (API) 调用。例如,服务身份可以使用 Vertex AI Workbench 笔记本电脑通过 Speech-to-Text API 转写音频文件来管理客户。
- 要与 Distributed Cloud 联合的外部工作负载。例如,服务身份可以管理 Distributed Cloud 外部的应用,该应用可将文档数字化,但希望使用光学字符识别 (OCR) API 来替换其当前的 OCR 引擎。
- Distributed Cloud 服务或系统控制器,用于安全地访问客户资源或用户集群。例如,服务身份可以管理身份验证和授权工作流,其中在管理员集群中运行的服务控制器需要在客户管理的用户集群中运行工作负载。
管理服务身份涉及服务身份(由 ProjectServiceAccount 资源表示)及其关联的凭据(公钥/私钥对)。您可以使用 GDC 控制台、gdcloud CLI 或 API 管理服务身份的账号。借助 gcloud CLI,服务身份功能基于全局 ProjectServiceAccount API 构建。由于 ProjectServiceAccount 资源是全局配置的,因此可在 gdcloud 领域中的所有可用区内运行。
准备工作
如需完成本文档中的任务,您必须拥有一个项目。如需了解如何创建项目,请参阅创建项目。
您还必须拥有必要的权限并准备好环境。
申请 IAM 角色
如需在项目中创建、更新和删除服务身份,请与您的组织 IAM 管理员或项目 IAM 管理员联系,请求授予 Project IAM Admin (project-iam-admin) 角色。
组织 IAM 管理员可以为组织内的任何项目授予此角色。Project IAM Admin 可以在其特定项目的范围内授予此角色。
准备环境
如需使用命令行工具管理服务身份,请完成以下设置:
如果您尚未下载并安装 gdcloud CLI,请执行此操作。
如需将 API 与
kubectl搭配使用,还需要进行其他设置:- 安装 kubectl CLI。
- 为全局 API 服务器生成 kubeconfig 文件,以配置
kubectl访问权限。
创建服务身份
创建服务身份包括创建账号及其关联的凭据。
创建账号
如需为服务身份创建账号,请使用 GDC 控制台、gdcloud CLI 或 API 在项目中创建 ProjectServiceAccount 资源。
控制台
- 登录 GDC 控制台。
- 在导航菜单中,选择身份和访问权限 > 服务身份。
- 点击创建服务身份。 系统会打开服务身份详细信息页面。
- 在服务身份名称字段中,输入服务身份的名称。例如:
testserviceidentity。 - 点击创建。
gdcloud
创建账号:
gdcloud iam service-accounts create NAME \
--project=PROJECT
替换以下值:
- NAME:
ProjectServiceAccount的名称。该名称在项目命名空间中必须是唯一的。 - PROJECT:要在其中创建服务身份的项目。如果已设置
gdcloud init,请省略--project标志。
此命令会在 Management API 服务器上的项目命名空间中创建 ProjectServiceAccount。
API
创建
ProjectServiceAccount自定义资源 YAML 文件,例如my-project-sa.yaml:apiVersion: resourcemanager.global.gdc.goog/v1 kind: ProjectServiceAccount metadata: name: NAME namespace: PROJECT spec: keys: - algorithm: ALGORITHM id: KEY_ID key: BASE64_ENCODED_KEY validAfter: "START_TIME" validBefore: "EXPIRATION_TIME"执行以下变量替换操作:
NAME:ProjectServiceAccount资源的名称。该名称在项目命名空间中必须是唯一的。PROJECT:要在其中创建服务身份的项目。ALGORITHM:密钥的算法。仅支持 ES256 密钥。KEY_ID:密钥的唯一标识符。该 ID 用于确定要验证的密钥。BASE64_ENCODED_KEY:用于验证的 PEM 格式的 base64 编码公钥。用于生成此公钥的私钥应采用 ECDSA P256 PEM 格式。START_TIME:密钥生效的开始时间,例如2025-02-07T00:59:34Z。EXPIRATION_TIME:密钥的过期时间,例如2026-02-07T00:59:34Z。
将
ProjectServiceAccount自定义资源应用于全局 API 服务器:kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG apply -f my-project-sa.yaml将
GLOBAL_API_SERVER_KUBECONFIG变量替换为全局 API 服务器的 kubeconfig 文件的路径。
创建凭据
如需让工作负载或应用以服务身份(由您创建的账号表示)进行身份验证,您需要生成凭据。创建凭据涉及生成加密私钥和公钥对,并将公钥与服务身份相关联。
如需为服务身份创建凭据,请使用 GDC 控制台、gdcloud CLI 或 API。
控制台
- 登录 GDC 控制台。
- 在导航菜单中,选择身份和访问权限 > 服务身份。
- 点击要在密钥中添加的服务身份的名称。
- 点击创建新密钥。
- 新密钥会显示在密钥列表中,并且系统会显示一个对话框,确认您已成功创建密钥。
gdcloud
gdcloud 命令会创建应用默认凭据 JSON 文件以及公钥/私钥对:
gdcloud iam service-accounts keys create APPLICATION_DEFAULT_CREDENTIALS_FILENAME \
--project=PROJECT \
--iam-account=NAME \
--ca-cert-path=CA_CERTIFICATE_PATH
替换以下值:
- APPLICATION_DEFAULT_CREDENTIALS_FILENAME:JSON 文件的名称。
- PROJECT:选择要为其创建密钥的项目。
如果已设置
gdcloud init,则可以省略--project标志。 - NAME:要为其添加密钥的服务身份的名称。
- CA_CERTIFICATE_PATH:可选:用于验证身份验证端点的证书授权机构 (CA) 证书路径。如果您未指定此路径,系统会使用系统 CA 证书。 您必须在系统 CA 证书中安装 CA。
Distributed Cloud 会将公钥添加到您用于验证私钥签名的 JSON Web 令牌 (JWT) 的密钥中。ProjectServiceAccount私钥会写入应用默认凭据 JSON 文件。
以下示例展示了应用默认凭据 JSON 文件:
{
"type": "gdch_service_account",
"format_version": "1",
"project": "project_name",
"private_key_id": "abcdef1234567890",
"private_key": "-----BEGIN PRIVATE KEY-----\nETC\n-----END PRIVATE KEY-----\n",
"name": "service_identity_name",
"ca_cert_path": "/path/to/ca.crt",
"token_uri": "https://service-identity.<Domain>/authenticate"
}
此示例使用以下值:
project:组织中的项目命名空间。private_key_id:分配给密钥的 ID。private_key:CLI 生成的 PEM 格式的 ECDSA P256 私钥。name:服务身份的名称。ca_cert_path:用于验证身份验证端点的证书授权机构 (CA) 证书的路径。token_uri:身份验证端点的地址。
API
生成公钥和私钥对。以下命令以
openssl为例,这是一个常用的此类工具。openssl ecparam -name prime256v1 -genkey -noout -out "key.pem" openssl ec -in "key.pem" -pubout > "pub.pem"对公钥进行 Base64 编码并检索其密钥 ID:
KEY_ID=$(openssl pkey -in key.pem -pubout -outform der | openssl dgst -sha256 | sed 's/^.* //') BASE64_ENCODED_KEY=$(cat pub.pem | base64)创建或更新
ProjectServiceAccount自定义资源 YAML 文件,包括上一步中生成的密钥信息:apiVersion: resourcemanager.global.gdc.goog/v1 kind: ProjectServiceAccount metadata: name: NAME namespace: PROJECT spec: keys: - algorithm: ALGORITHM id: KEY_ID key: BASE64_ENCODED_KEY validAfter: "START_TIME" validBefore: "EXPIRATION_TIME"执行以下变量替换操作:
NAME:ProjectServiceAccount资源的名称。该名称在项目命名空间中必须是唯一的。PROJECT:您要在其中创建密钥的项目。ALGORITHM:密钥的算法。仅支持 ES256 密钥。KEY_ID:密钥的唯一标识符。该 ID 用于确定要验证的密钥。BASE64_ENCODED_KEY:用于验证的 PEM 格式的 base64 编码公钥。用于生成此公钥的私钥应采用 ECDSA P256 PEM 格式。START_TIME:密钥生效的开始时间,例如2025-02-07T00:59:34Z。EXPIRATION_TIME:密钥的过期时间,例如2026-02-07T00:59:34Z。
将
ProjectServiceAccount自定义资源应用到全局 API 服务器:kubectl --kubeconfig GLOBAL_API_SERVER_KUBECONFIG apply -f my-project-sa.yaml将
GLOBAL_API_SERVER_KUBECONFIG变量替换为全局 API 服务器的 kubeconfig 文件的路径。创建包含私钥的应用默认凭据 JSON 文件。确保 JSON 文件中的
KEY_ID变量设置为与您在ProjectServiceAccount规范中使用的KEY_ID变量相同的值。cat <<EOF > "key_file.json" { "format_version": "1", "name": "NAME", "private_key": "$(tr '\n' '\t' < "key.pem" | sed 's/\t/\\n/g')", "private_key_id": "KEY_ID", "project": "PROJECT", "token_uri": "AUTH_URL", "type": "gdch_service_account" } EOF执行以下变量替换操作:
NAME:服务身份的名称。KEY_ID:密钥的唯一标识符。该 ID 用于确定要验证的密钥,并且必须与ProjectServiceAccount规范中使用的KEY_ID值一致。PROJECT:组织中的项目命名空间。AUTH_URL:身份验证端点的地址。
如需详细了解如何使用生成的密钥文件以该服务身份进行身份验证,请参阅对服务身份进行身份验证并使用服务身份。本部分介绍了如何将密钥与 gdcloud CLI 搭配使用,以及如何通过客户端库以程序化方式使用密钥。
查看服务身份
本部分介绍了如何查看服务身份及其关联的公钥。
查看服务身份列表
如需查看项目中的服务身份列表,请使用 GDC 控制台或 gdcloud CLI。
控制台
- 登录 GDC 控制台。
- 选择一个项目。
- 在导航菜单中,依次点击身份和访问权限 > 服务身份,查看项目的服务身份列表。
gdcloud
列出项目中的服务身份账号:
gdcloud iam service-accounts list \
--project=PROJECT
将 PROJECT 替换为项目 ID。
查看服务身份的公钥列表
列出项目中向服务身份账号注册的公钥:
gdcloud iam service-accounts keys list \
--project=PROJECT \
--iam-account=NAME
替换以下内容:
- PROJECT:项目 ID。
- NAME:要使用的服务身份账号的名称。
授予服务身份权限
如需向服务身份授予权限,请使用 GDC 控制台或 gdcloud CLI 创建角色绑定,为其分配一个或多个角色。
控制台
- 登录 GDC 控制台。
- 选择一个项目。
- 在导航菜单中,依次选择身份和访问权限 > 访问权限。
- 在成员列表中,点击 添加成员。 系统会显示用户和角色页面。
- 在成员类型列表中,选择服务身份。
- 在服务身份列表中,选择要为其分配角色绑定的服务身份。
- 在角色列表中,选择要分配给服务身份的角色,例如 Backup Creator。
- 可选:如需添加其他角色,请点击添加其他角色。 选择其他角色。
- 点击 Add(添加)。
gdcloud
您可以将服务身份账号绑定到项目命名空间内的角色,也可以绑定到其他命名空间中的角色。
将账号绑定到项目命名空间中的角色:
gdcloud iam service-accounts add-iam-policy-binding \ --project=PROJECT \ --role=ROLE \ --iam-account=NAME替换以下内容:
- PROJECT:要在其中创建角色绑定的项目。如果已设置
gdcloud init,则可以省略--project标志。 - ROLE:要分配给账号的预定义角色。以
Role/name格式指定角色,其中 Role 是 Kubernetes 类型IAMRole,name 是预定义角色的名称。例如,如需分配 Project Viewer 角色,请将角色设置为IAMRole/project-viewer。 - NAME:要使用的服务身份账号的名称。
- PROJECT:要在其中创建角色绑定的项目。如果已设置
将账号绑定到其他命名空间中的角色:
gdcloud iam service-accounts add-iam-policy-binding \ --role=ROLE \ --role-namespace=ROLE_NAMESPACE \ --iam-account=NAME替换以下内容:
- ROLE:要分配给账号的预定义角色。以
Role/name格式指定角色,其中 Role 是 Kubernetes 类型IAMRole,name 是预定义角色的名称。例如,如需分配 Project Viewer 角色,请将角色设置为IAMRole/project-viewer。 - ROLE_NAMESPACE:要与账号绑定的角色的命名空间(项目命名空间除外)。
- NAME:要使用的服务身份账号的名称。
- ROLE:要分配给账号的预定义角色。以
进行身份验证并使用服务身份
创建服务身份并生成其密钥文件后,您可以使用该密钥文件向 GDC 服务和集群进行身份验证。通过身份验证,您可以获取用于 API 调用的短期有效的访问令牌,或配置集群访问权限。
您可以通过以下两种方式使用服务身份进行身份验证:
使用 gdcloud CLI 进行身份验证
如需使用服务身份执行操作,您必须先激活其密钥文件。激活后,您可以使用 gdcloud CLI 获取令牌或生成 kubeconfig 文件。
使用密钥授权服务身份
gdcloud auth activate-service-account 命令使用服务身份对 gcloud CLI 进行身份验证。这样一来,您就可以使用服务身份账号权限(而非用户账号)对 Distributed Cloud 资源执行操作。
使用密钥授权服务身份:
如果您还没有凭据密钥文件,请创建一个。
运行以下命令以激活服务身份:
gdcloud auth activate-service-account --key-file=KEY_FILE将 KEY_FILE 替换为凭据密钥文件的路径,该文件通常采用 JSON 格式。
成功激活后,
gdcloud会使用服务身份的凭据,而不是您的用户凭据。
使用 gdcloud CLI 获取访问令牌
授权服务身份后,您可以使用 gdcloud 打印访问令牌。您可以使用此令牌作为不记名令牌来验证 HTTP 请求。该令牌授予对 AUDIENCES 参数中定义的服务的访问权限。
为指定的服务身份账号打印身份令牌:
gdcloud auth print-identity-token --audiences=AUDIENCES
将 AUDIENCES 替换为令牌的预期收件人或服务。只能指定一个受众群体。
生成 kubeconfig 文件
授权服务身份后,您可以生成 kubeconfig 文件以向 Kubernetes 集群进行身份验证。
设置 gdcloud
core/organization_console_url属性:gdcloud config set core/organization_console_url https://GDC_URL将
GDC_URL替换为贵组织的网址。生成 kubeconfig 文件以使用有效的服务身份访问集群:
对于可用区级集群:
export KUBECONFIG=KUBECONFIG_PATH gdcloud clusters get-credentials CLUSTER_NAME --zone ZONE替换以下内容:
- KUBECONFIG_PATH:您要保存生成的 kubeconfig 文件的路径。
CLUSTER_NAME:可用区级集群的名称。
ZONE:集群所在可用区的名称。
对于全局 API 服务器:
export KUBECONFIG=KUBECONFIG_PATH gdcloud clusters get-credentials global-api将
KUBECONFIG_PATH替换为您要保存生成的 kubeconfig 文件的路径。
系统会生成一个 kubeconfig 文件,并将其配置为以服务身份进行身份验证。以下示例展示了一个 YAML 文件:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <REDACTED>
server: <REDACTED>
name: cluster-name
contexts:
- context:
cluster: cluster-name
user: gdch_console-<REDACTED>_cluster-name
name: cluster-name-gdch_console-<REDACTED>_cluster-name
current-context: cluster-name-gdch_console-gdc1-staging-gpcdemolabs-com_cluster-name
kind: Config
preferences: {}
users:
- name: gdch_console-<REDACTED>_cluster-name
user:
exec:
apiVersion: client.authentication.k8s.io/v1
args:
- --audience=<REDACTED>
command: gdcloud-k8s-auth-plugin
env: null
installHint: Run 'gdcloud components install gdcloud-k8s-auth-plugin' to use
plugin
interactiveMode: Never
provideClusterInfo: false
以程序化方式使用客户端库进行身份验证
以下示例展示了如何使用标准 Google Cloud 客户端库以程序化方式为 GDC 管理 API 生成安全令牌服务 (STS) 访问令牌。这些库使用生成的服务账号密钥文件进行身份验证并获取令牌。此方法不需要任何预先gdcloud授权。
Python
import google.auth
from google.auth.transport import requests
import requests as reqs
api_endpoint = "https://console.org-1.zone1.google.gdch.test"
# Load the GDC credentials (via GOOGLE_APPLICATION_CREDENTIALS or default path)
creds, project_id = google.auth.default()
# Apply the required audience for the GDC Management API
creds = creds.with_gdch_audience(api_endpoint)
def fetch_gdch_token():
sesh = reqs.Session()
# Note: Set verify to False only if bypassing self-signed cert verification.
# Otherwise, rely on the "ca_cert_path" present in your gdch_credentials.json
sesh.verify = False
req = requests.Request(session=sesh)
# Refresh the credentials to fetch the STS access token
creds.refresh(req)
print("Access Token:", creds.token)
fetch_gdch_token()
Java
import com.google.auth.oauth2.GdchCredentials;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.FileInputStream;
import java.io.InputStream;
public class GdchAuthExample {
public static void main(String[] args) throws Exception {
// Path to your service account JSON file
String credentialsPath = "/path/to/gdch/credentials.json";
String apiAudience = "https://console.org-1.zone1.google.gdch.test";
try (InputStream credentialsStream = new FileInputStream(credentialsPath)) {
// Load the generic Google credentials from the stream
GoogleCredentials credentials = GoogleCredentials.fromStream(credentialsStream);
// Verify it loaded as GdchCredentials
if (credentials instanceof GdchCredentials) {
// Cast and attach the targeted GDC audience
GdchCredentials gdch = ((GdchCredentials) credentials).createWithGdchAudience(apiAudience);
// Force negotiation with the GDC Auth Server to fetch the token
gdch.refreshIfExpired();
System.out.println("Access Token: " + gdch.getAccessToken().getTokenValue());
} else {
System.err.println("The provided file is not a valid GdchCredentials format.");
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"cloud.google.com/go/auth/credentials"
)
func main() {
ctx := context.Background()
apiEndpoint := "https://console.org-1.zone1.google.gdch.test"
// Load default credentials. The STSAudience parameter is specifically
// required for the GDC auth flow to correctly negotiate the token.
creds, err := credentials.DetectDefault(&credentials.DetectOptions{
STSAudience: apiEndpoint,
})
if err != nil {
log.Fatalf("Failed to detect credentials: %v", err)
}
// Fetch an access token
token, err := creds.Token(ctx)
if err != nil {
log.Fatalf("Failed to retrieve token: %v", err)
}
fmt.Printf("Access Token: %s\n", token.Value)
}
删除服务身份
删除服务身份后,ProjectServiceAccount 及其关联的公钥会被删除,现有私钥会失效,应用将无法再通过该服务身份访问项目资源。
如需删除服务身份,请使用 GDC 控制台或 gdcloud CLI。
控制台
- 登录 GDC 控制台。
- 在导航菜单中,选择身份和访问权限 > 服务身份。
- 选中要删除的服务身份对应的复选框。
- 点击删除。
- 系统会显示确认对话框。在请在下面输入以下内容进行确认字段中,输入
remove。 - 点击删除。
gdcloud
运行以下命令可删除服务身份账号:
gdcloud iam service-accounts delete NAME \
--project=PROJECT
替换以下内容:
- NAME:要删除的服务身份账号的名称。
- PROJECT:项目 ID。
删除凭据
如果您想停用特定密钥对,但不想删除整个服务身份账号,可以从服务身份账号中删除其公钥。此操作会使相应的私钥失效。
如需删除公钥,请使用 GDC 控制台或 gdcloud CLI。
控制台
- 登录 GDC 控制台。
- 在导航菜单中,选择身份和访问权限 > 服务身份。
- 点击包含要删除的密钥的服务身份的名称。
- 点击删除。
- 在确认对话框中点击删除。
gdcloud
从项目中的服务身份账号中移除具有相应密钥 ID 的公钥:
gdcloud iam service-accounts keys delete KEY_ID \
--project=PROJECT \
--iam-account=NAME
替换以下内容:
- KEY_ID:密钥的唯一标识符。
- PROJECT:项目 ID。
- NAME:服务身份账号的名称。