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,管理服務身分的帳戶。使用 gdcloud CLI 時,服務身分功能是以全域 ProjectServiceAccount API 為基礎。由於 ProjectServiceAccount 資源是在全域層級設定,因此會在 gdcloud 宇宙的所有可用區中運作。
事前準備
您必須擁有專案,才能完成本文件中的工作。如要瞭解如何建立專案,請參閱「建立專案」。
此外,您必須具備必要權限,並準備好環境。
要求 IAM 角色
如要在專案中建立、更新及刪除服務身分,請與 IAM 機構組織管理員或 IAM 專案管理員聯絡,要求取得IAM 專案管理員 (project-iam-admin) 角色。
IAM 機構組織管理員可以為組織內的任何專案授予這個角色。IAM 專案管理員可以在特定專案範圍內授予這個角色。
準備環境
如要使用指令列工具管理服務身分,請完成下列設定:
如要搭配
kubectl使用 API,請完成下列額外設定:- 安裝 kubectl CLI。
- 產生全域 API 伺服器的 kubeconfig 檔案,設定
kubectl存取權。
建立服務身分
建立服務身分時,也需要建立帳戶和相關聯的憑證。
建立帳戶
如要為服務身分建立帳戶,請使用 GDC 控制台、gdcloud CLI 或 API,在專案中建立 ProjectServiceAccount 資源。
控制台
- 登入 GDC 控制台。
- 在導覽選單中,依序選取「Identity & Access」>「Service identities」。
- 按一下「Create Service Identity」(建立服務身分)。「Service Identity details」(服務身分詳細資料) 頁面隨即開啟。
- 在「Service identity name」(服務身分名稱) 欄位中,輸入服務身分的名稱。例如:
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。ID 用於判斷要驗證哪個金鑰。BASE64_ENCODED_KEY:採用 Base64 編碼的 PEM 格式公開金鑰,用於驗證。用於產生這個公開金鑰的私密金鑰應為 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 控制台。
- 在導覽選單中,依序選取「Identity & Access」>「Service Identities」。
- 按一下要新增至金鑰的服務身分名稱。
- 按一下「 建立新金鑰」。
- 新金鑰會顯示在「Keys」(金鑰) 清單中,並會顯示對話方塊,確認您已成功建立金鑰。
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 會將公開金鑰新增至 ProjectServiceAccount 金鑰,用於驗證私密金鑰簽署的 JSON Web Token (JWT)。私密金鑰會寫入應用程式預設憑證 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。ID 用於判斷要驗證哪個金鑰。BASE64_ENCODED_KEY:採用 Base64 編碼的 PEM 格式公開金鑰,用於驗證。用於產生這個公開金鑰的私密金鑰應為 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。ID 用於判斷要驗證的金鑰,且必須與ProjectServiceAccount規格中使用的KEY_ID值相符。PROJECT:組織中的專案命名空間。AUTH_URL:驗證端點的位址。
如要瞭解如何使用產生的金鑰檔案,以這個服務身分進行驗證,請參閱「驗證及使用服務身分」。本節說明如何透過 gdcloud CLI 使用金鑰,以及如何透過用戶端程式庫以程式輔助方式使用金鑰。
查看服務身分
本節說明如何查看服務身分和相關聯的公開金鑰。
查看服務身分清單
如要查看專案中的服務身分清單,請使用 GDC 控制台或 gdcloud CLI。
控制台
- 登入 GDC 控制台。
- 選取專案。
- 在導覽選單中,依序點選「Identity & Access」(身分與存取權) >「Service Identities」(服務身分),即可查看專案的服務身分清單。
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 控制台。
- 選取專案。
- 在導覽選單中,依序選取「Identity & Access」>「Access」。
- 在「Member」(成員) 清單中,按一下「Add member」(新增成員)。「使用者與角色」頁面隨即顯示。
- 在「Member type」(成員類型) 清單中,選取「Service identity」(服務身分)。
- 在「Service identity」(服務身分) 清單中,選取要指派角色繫結的服務身分。
- 在「Role」(角色) 清單中,選取要指派給服務身分的角色,例如「Backup Creator」(備份建立者)。
- 選用:如要新增其他角色,請按一下「 Add another role」(新增其他角色)。選取其他角色。
- 按一下「新增」。
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 則是預先定義角色的名稱。例如,如要指派專案檢視者角色,請將角色設為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 則是預先定義角色的名稱。例如,如要指派專案檢視者角色,請將角色設為IAMRole/project-viewer。 - ROLE_NAMESPACE:要與帳戶繫結的角色命名空間,而非專案命名空間。
- NAME:要使用的服務身分帳戶名稱。
- ROLE:要指派給帳戶的預先定義角色。請以
驗證及使用服務身分
建立服務身分並產生金鑰檔案後,您可以使用金鑰檔案向 GDC 服務和叢集進行驗證。驗證身分後,您就能取得短期存取權杖,用於 API 呼叫或設定叢集存取權。
使用服務身分進行驗證的方法有兩種:
使用 gdcloud CLI 驗證
如要使用服務身分執行動作,必須先啟用其金鑰檔案。啟用後,您可以使用 gdcloud CLI 取得權杖或產生 kubeconfig 檔案。
使用金鑰授權服務身分
gdcloud auth activate-service-account 指令會使用服務身分驗證 gdcloud 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 進行驗證。這些程式庫會使用產生的服務帳戶金鑰檔案,產生 Security Token Service (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)
}
C++
[](std::string const& keyfile, std::string const& audience) {
auto is = std::ifstream(keyfile);
is.exceptions(std::ios::badbit); // Minimal error handling in examples
auto contents = std::string(std::istreambuf_iterator<char>(is.rdbuf()), {});
auto options =
google::cloud::Options{}.set<google::cloud::UnifiedCredentialsOption>(
google::cloud::MakeGDCHServiceAccountCredentials(contents, audience));
return google::cloud::speech_v1::AdaptationClient(
google::cloud::speech_v1::MakeAdaptationConnection(options));
}
刪除服務身分
刪除服務身分後,ProjectServiceAccount 和相關聯的公開金鑰會一併刪除,現有的私密金鑰也會失效,應用程式將無法再透過該服務身分存取專案資源。
如要刪除服務身分,請使用 GDC 控制台或 gdcloud CLI。
控制台
- 登入 GDC 控制台。
- 在導覽選單中,依序選取「Identity & Access」>「Service Identities」。
- 勾選要刪除的服務身分核取方塊。
- 點選「刪除」。
- 確認對話方塊隨即顯示。在「Confirm by typing the following below」(在下方輸入以下內容以確認) 欄位中,輸入
remove。 - 點選「刪除」。
gdcloud
執行下列指令,刪除服務身分帳戶:
gdcloud iam service-accounts delete NAME \
--project=PROJECT
更改下列內容:
- NAME:要刪除的服務身分帳戶名稱。
- PROJECT:專案 ID。
刪除憑證
如要停用特定金鑰組,但不想刪除整個服務身分帳戶,可以從服務身分帳戶中刪除公開金鑰。這項操作會使對應的私密金鑰失效。
如要刪除公開金鑰,請使用 GDC 控制台或 gdcloud CLI。
控制台
- 登入 GDC 控制台。
- 在導覽選單中,依序選取「Identity & Access」>「Service Identities」。
- 按一下服務身分名稱,找出要刪除的金鑰。
- 按一下「 刪除」。
- 在確認對話方塊中點按「刪除」。
gdcloud
從專案中的服務身分帳戶,移除具有金鑰 ID 的公開金鑰:
gdcloud iam service-accounts keys delete KEY_ID \
--project=PROJECT \
--iam-account=NAME
更改下列內容:
- KEY_ID:金鑰的專屬 ID。
- PROJECT:專案 ID。
- NAME:服務身分帳戶的名稱。