本指南說明如何使用 Workload Identity Federation,讓在 Azure Kubernetes Service (AKS)、Amazon Elastic Kubernetes Service 或自架 Kubernetes 叢集上執行的工作負載,向 Google Cloud進行驗證。
您可以設定叢集,讓工作負載從投影磁碟區取得 Kubernetes ServiceAccount 權杖。設定 Workload Identity 聯盟後,工作負載就能使用這些 Kubernetes ServiceAccount 權杖向 Google Cloud進行驗證。
如果您使用 GKE,請使用 Workload Identity Federation for GKE,而非設定 Workload Identity Federation。
事前準備
設定 Workload Identity 聯盟之前,請確認 Kubernetes 叢集符合下列條件:
GKE
Google Kubernetes Engine (GKE) 使用者請參閱「從 GKE 工作負載向 API 進行驗證 Google Cloud 」。
AKS
確認叢集符合下列條件:
您已啟用 OIDC 簽發者功能。
您必須啟用這項功能,Workload Identity Federation 才能存取叢集的 OpenID Connect 中繼資料和 JSON Web Key Set (JWKS)。
EKS
您不需要變更 EKS 設定。
Kubernetes
確認叢集符合下列條件:
您執行的是 Kubernetes 1.20 以上版本。
舊版 Kubernetes 使用的 ServiceAccount 權杖格式不同,與本文件中的操作說明不相容。
您已設定
kube-apiserver
,支援ServiceAccount
權杖量預測。
叢集不需要透過網際網路存取。
設定 Workload Identity 聯盟
每個 Kubernetes 叢集只需要執行一次這些步驟。然後,您就可以將相同的工作負載身分識別集區和提供者用於多個 Kubernetes Pod,以及多個 Google Cloud 專案。
如要開始設定 Workload Identity 聯盟,請按照下列步驟操作:
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
建議您
使用專案管理工作負載身分集區和供應商。
-
Make sure that billing is enabled for your Google Cloud project.
Enable the IAM, Resource Manager, Service Account Credentials, and Security Token Service APIs.
定義屬性對應和條件
Kubernetes ServiceAccount 權杖包含多項聲明,包括:
sub
:包含 ServiceAccount 的命名空間和名稱,例如system:serviceaccount:NAMESPACE:KSA_NAME
,其中NAMESPACE
是 ServiceAccount 的命名空間,KSA_NAME
則是 ServiceAccount 的名稱。"kubernetes.io".namespace
:包含 ServiceAccount 的命名空間。"kubernetes.io".serviceaccount.name
:包含 ServiceAccount 的名稱。"kubernetes.io".pod.name
:包含 Pod 的名稱。
如要在 Google Cloud中使用 sub
做為主體 ID (google.subject
),請使用下列對應:
google.subject=assertion.sub
你也可以視需要對應其他屬性。 然後,您可以在授予資源存取權時參照這些屬性。 例如:
google.subject=assertion.sub, attribute.namespace=assertion['kubernetes.io']['namespace'], attribute.service_account_name=assertion['kubernetes.io']['serviceaccount']['name'], attribute.pod=assertion['kubernetes.io']['pod']['name']
視需要定義屬性條件。
屬性條件是 CEL 運算式,可檢查判斷結果屬性和目標屬性。如果屬性條件評估為特定憑證的 true
,系統就會接受該憑證。否則系統會拒絕認證。
您可以使用屬性條件,限制哪些 Kubernetes ServiceAccount 可以使用 Workload Identity Federation 取得短期 Google Cloud權杖。舉例來說,下列條件會限制從 backend
和 monitoring
命名空間存取 Kubernetes ServiceAccount:
assertion['kubernetes.io']['namespace'] in ['backend', 'monitoring']
建立工作負載身分集區和提供者
必要的角色
如要取得設定 Workload Identity 聯盟所需的權限,請要求管理員授予您專案的下列 IAM 角色:
-
Workload Identity Pool Admin (
roles/iam.workloadIdentityPoolAdmin
) -
服務帳戶管理員 (
roles/iam.serviceAccountAdmin
)
如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。
或者,IAM 擁有者 (roles/owner
) 基本角色也包含設定身分識別聯盟的權限。您不應在正式版環境中授予基本角色,但可以在開發或測試環境中授予。如要建立 workload identity pool 和提供者,請按照下列步驟操作:
AKS
判斷 AKS 叢集的簽發者網址:
az aks show -n NAME -g RESOURCE_GROUP --query "oidcIssuerProfile.issuerUrl" -otsv
更改下列內容:
NAME
:叢集名稱RESOURCE_GROUP
:叢集的資源群組
這個指令會輸出簽發者網址。您將在下方其中一個步驟中用到簽發者網址。
如果指令未傳回簽發者網址,請確認您已啟用 OIDC 簽發者功能。
建立新的 workload identity pool:
gcloud iam workload-identity-pools create POOL_ID \ --location="global" \ --description="DESCRIPTION" \ --display-name="DISPLAY_NAME"
更改下列內容:
POOL_ID
:集區的專屬 ID。DISPLAY_NAME
:集區名稱。DESCRIPTION
:所選集區的說明。授予集區身分的存取權時會顯示這段說明。
將 AKS 叢集新增為工作負載身分集區提供者:
gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \ --location="global" \ --workload-identity-pool="POOL_ID" \ --issuer-uri="ISSUER" \ --attribute-mapping="MAPPINGS" \ --attribute-condition="CONDITIONS"
更改下列內容:
EKS
判斷 EKS 叢集的簽發者網址:
aws eks describe-cluster --name NAME --query "cluster.identity.oidc.issuer" --output text
將
NAME
替換為叢集名稱。這個指令會輸出簽發者網址。您將在下方其中一個步驟中用到簽發者網址。
建立新的 workload identity pool:
gcloud iam workload-identity-pools create POOL_ID \ --location="global" \ --description="DESCRIPTION" \ --display-name="DISPLAY_NAME"
更改下列內容:
POOL_ID
:集區的專屬 ID。DISPLAY_NAME
:集區名稱。DESCRIPTION
:所選集區的說明。授予集區身分的存取權時會顯示這段說明。
將 EKS 叢集新增為工作負載身分集區提供者:
gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \ --location="global" \ --workload-identity-pool="POOL_ID" \ --issuer-uri="ISSUER" \ --attribute-mapping="MAPPINGS" \ --attribute-condition="CONDITIONS"
更改下列內容:
Kubernetes
連線至 Kubernetes 叢集,並使用
kubectl
判斷叢集的簽發者網址:kubectl get --raw /.well-known/openid-configuration | jq -r .issuer
您將在下方其中一個步驟中用到簽發者網址。
下載叢集的 JSON Web Key Set (JWKS):
kubectl get --raw /openid/v1/jwks > cluster-jwks.json
在後續步驟中,您會上傳 JWKS,以便 Workload Identity Federation 驗證叢集核發的 Kubernetes ServiceAccount 權杖是否為真。
建立新的 workload identity pool:
gcloud iam workload-identity-pools create POOL_ID \ --location="global" \ --description="DESCRIPTION" \ --display-name="DISPLAY_NAME"
更改下列內容:
POOL_ID
:集區的專屬 ID。DISPLAY_NAME
:集區名稱。DESCRIPTION
:所選集區的說明。授予集區身分的存取權時會顯示這段說明。
將 Kubernetes 叢集新增為工作負載身分集區提供者,並上傳叢集的 JWKS:
gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \ --location="global" \ --workload-identity-pool="POOL_ID" \ --issuer-uri="ISSUER" \ --attribute-mapping="MAPPINGS" \ --attribute-condition="CONDITIONS" \ --jwk-json-path="cluster-jwks.json"
更改下列內容:
授予 Kubernetes 工作負載的存取權
本節說明如何設定 Kubernetes 工作負載,以使用 Workload Identity 聯盟直接資源存取或服務帳戶模擬功能,存取Google Cloud API。
針對每個需要存取 Google Cloud的 Kubernetes 工作負載,您必須執行一次這些步驟。
建議使用 Workload Identity 聯盟。不過,使用身分聯盟時,某些 API 方法可能會受到限制。如需限制清單,請參閱「身分聯盟:產品和限制」。
如果工作負載使用的方法有這類限制,您可以改用 IAM 模擬。
使用 Workload Identity 聯盟授予資源的直接存取權
在本節中,您會使用 Workload Identity 聯盟,將 IAM 角色授予 Kubernetes ServiceAccount,以便直接存取 Google Cloud 資源。
如要建立 Kubernetes ServiceAccount 並授予角色,請按照下列步驟操作:
建立 Kubernetes ServiceAccount:
kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
更改下列內容:
KSA_NAME
:ServiceAccount 的名稱。NAMESPACE
:要建立 ServiceAccount 的命名空間。
將 IAM 存取權授予Google Cloud 資源的 Kubernetes ServiceAccount。
請遵循最低權限原則,只授予應用程式必須存取的資源專屬角色。
在下列範例中,指令會將 Kubernetes Engine 叢集檢視者 (
roles/container.clusterViewer
) 角色授予您建立的 ServiceAccount。這個指令會使用您稍早對應的主體。gcloud projects add-iam-policy-binding projects/PROJECT_ID \ --role=roles/container.clusterViewer \ --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT \ --condition=None
更改下列內容:
PROJECT_NUMBER
:與專案 ID 相關聯的數字Google Cloud 專案編號。POOL_ID
:工作負載身分集區 ID。MAPPED_SUBJECT
:ID 權杖中您對應至google.subject
的 Kubernetes ServiceAccount。舉例來說,如果您對應google.subject=assertions.sub
,且 ID 權杖包含"sub": "system:serviceaccount:default:my-kubernetes-serviceaccount"
,則MAPPED_SUBJECT
為system:serviceaccount:default:my-kubernetes-serviceaccount
。
您可以在任何支援 IAM 允許政策的 Google Cloud 資源上授予角色。主體 ID 的語法取決於 Kubernetes 資源。如需支援的 ID 清單,請參閱「Principal identifiers for Workload Identity Federation for GKE」。
您現在可以部署工作負載,使用 Kubernetes ServiceAccount 存取您授予存取權的 Google Cloud 資源。
替代做法:使用 IAM 服務帳戶模擬功能授予存取權
如要將 Kubernetes ServiceAccount 設定為使用 IAM 服務帳戶模擬,請執行下列操作:
如果還沒有 Kubernetes ServiceAccount,請建立一個:
kubectl create serviceaccount KSA_NAME --namespace NAMESPACE
更改下列內容:
KSA_NAME
:ServiceAccount 的名稱NAMESPACE
:要建立 ServiceAccount 的命名空間
建立代表工作負載的 IAM 服務帳戶。
服務帳戶不一定要與工作負載身分集區位於同一個專案,但您必須在參照服務帳戶時,指定包含該帳戶的專案。
gcloud iam service-accounts create IAM_SA_NAME \ --project=IAM_SA_PROJECT_ID
更改下列內容:
IAM_SA_NAME
:服務帳戶名稱IAM_SA_PROJECT_ID
:服務帳戶的專案 ID
授予 IAM 服務帳戶存取權,存取您要 Kubernetes 工作負載存取的特定 Google Cloud 資源。
gcloud projects add-iam-policy-binding IAM_SA_PROJECT_ID \ --member="serviceAccount:IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com" \ --role="ROLE"
更改下列內容:
IAM_SA_PROJECT_ID
:您建立服務帳戶的專案 IDIAM_SA_NAME
:服務帳戶名稱ROLE
:角色名稱,例如:roles/container.clusterViewer
授予 Kubernetes ServiceAccount 模擬 IAM 服務帳戶的權限:
gcloud iam service-accounts add-iam-policy-binding \ IAM_SA_NAME@IAM_SA_PROJECT_ID.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
更改下列內容:
IAM_SA_NAME
:服務帳戶名稱PROJECT_ID
:執行 Kubernetes 的專案 IDIAM_SA_PROJECT_NUMBER
:您建立服務帳戶的專案專案編號POOL_ID
:工作負載身分集區 ID。MAPPED_SUBJECT
:ID 權杖中您對應至google.subject
的 Kubernetes ServiceAccount。舉例來說,如果您對應google.subject=assertions.sub
,且 ID 權杖包含"sub": "system:serviceaccount:default:my-kubernetes-serviceaccount"
,則MAPPED_SUBJECT
為system:serviceaccount:default:my-kubernetes-serviceaccount
。
如要瞭解如何授權身分與存取權管理服務帳戶存取Google Cloud API,請參閱「瞭解服務帳戶」一文。
您現在可以部署工作負載,使用 Kubernetes ServiceAccount 和 IAM 服務帳戶存取您授予存取權的 Google Cloud資源。
部署 Kubernetes 工作負載
如要部署可存取資源的 Kubernetes 工作負載,請執行下列步驟: Google Cloud
建立憑證設定檔:
gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/WORKLOAD_PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --credential-source-file=/var/run/service-account/token \ --credential-source-type=text \ --output-file=credential-configuration.json
更改下列內容:
PROJECT_NUMBER
:包含 workload identity pool 的專案專案編號POOL_ID
:工作負載身分集區的 IDWORKLOAD_PROVIDER_ID
:workload identity pool 提供者的 IDSERVICE_ACCOUNT_EMAIL
:服務帳戶的電子郵件地址 (如果您已將 Kubernetes ServiceAccount 設為使用 IAM 服務帳戶模擬)。如果您已將 Kubernetes ServiceAccount 設定為使用直接資源存取權,請省略這個旗標。
憑證設定檔可讓 Cloud 用戶端程式庫、gcloud CLI 和 Terraform 判斷下列事項:
- 如何取得外部憑證
- 要使用的 workload identity pool 和提供者
- 要模擬哪個服務帳戶
將憑證設定檔匯入為 ConfigMap
kubectl create configmap CONFIGMAP_NAME \ --from-file credential-configuration.json \ --namespace NAMESPACE
更改下列內容:
CONFIGMAP_NAME
:ConfigMap 的名稱。NAMESPACE
:要建立 ConfigMap 的命名空間。
部署工作負載,並讓工作負載使用 Kubernetes ServiceAccount 和 ConfigMap。
建立資訊清單並設定如下:
- 掛接投影權杖磁碟區,讓工作負載可從本機檔案取得 Kubernetes ServiceAccount 權杖。設定磁碟區,讓 Kubernetes ServiceAccount 權杖使用工作負載身分集區提供者預期的對象。
- 掛接含有憑證設定檔的 ConfigMap,讓工作負載能存取使用 Workload Identity 聯盟所需的設定。
- 新增環境變數
GOOGLE_APPLICATION_CREDENTIALS
,其中包含憑證設定檔的路徑,以便工作負載找到該檔案。
以下是資訊清單範例,使用 Kubernetes ServiceAccount 和 ConfigMap,讓 Google Cloud CLI 向 Google Cloud進行驗證:
apiVersion: v1 kind: Pod metadata: name: example namespace: NAMESPACE spec: containers: - name: example image: google/cloud-sdk:alpine command: ["/bin/sh", "-c", "gcloud auth login --cred-file $GOOGLE_APPLICATION_CREDENTIALS && gcloud auth list && sleep 600"] volumeMounts: - name: token mountPath: "/var/run/service-account" readOnly: true - name: workload-identity-credential-configuration mountPath: "/etc/workload-identity" readOnly: true env: - name: GOOGLE_APPLICATION_CREDENTIALS value: "/etc/workload-identity/credential-configuration.json" serviceAccountName: KSA_NAME volumes: - name: token projected: sources: - serviceAccountToken: audience: https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/WORKLOAD_PROVIDER_ID expirationSeconds: 3600 path: token - name: workload-identity-credential-configuration configMap: name: CONFIGMAP_NAME
您可以採用相同方法,讓使用下列其中一個用戶端程式庫的工具和工作負載自動尋找憑證:
C++
自 v2.6.0 版起,Google Cloud C++ 用戶端程式庫支援 Workload Identity Federation。如要使用 Workload Identity 聯盟,您必須使用 1.36.0 以上版本的 gRPC 建構用戶端程式庫。
Go
如果 Go 的用戶端程式庫使用
golang.org/x/oauth2
模組的 v0.0.0-20210218202405-ba52d332ba99 以上版本,即可支援 Workload Identity Federation。如要查看用戶端程式庫使用的這個模組版本,請執行下列指令:
cd $GOPATH/src/cloud.google.com/go go list -m golang.org/x/oauth2
Java
如果 Java 適用的用戶端程式庫使用
com.google.auth:google-auth-library-oauth2-http
構件 0.24.0 以上版本,即可支援 Workload Identity 聯盟。如要查看用戶端程式庫使用的構件版本,請在應用程式目錄中執行下列 Maven 指令:
mvn dependency:list -DincludeArtifactIds=google-auth-library-oauth2-http
Node.js
如果 Node.js 適用的用戶端程式庫使用
google-auth-library
套件 7.0.2 以上版本,即可支援 Workload Identity Federation。如要查看用戶端程式庫使用的套件版本,請在應用程式目錄中執行下列指令:
npm list google-auth-library
建立
GoogleAuth
物件時,您可以指定專案 ID,也可以允許GoogleAuth
自動尋找專案 ID。如要自動找出專案 ID,設定檔中的服務帳戶必須在專案中具備「瀏覽器」角色 (roles/browser
),或是其他具備同等權限的角色。詳情請參閱google-auth-library
套件的README
。Python
如果 Python 適用的用戶端程式庫使用
google-auth
套件 1.27.0 以上版本,即可支援 Workload Identity Federation。如要查看用戶端程式庫使用的套件版本,請在安裝套件的環境中執行下列指令:
pip show google-auth
如要為驗證用戶端指定專案 ID,可以設定
GOOGLE_CLOUD_PROJECT
環境變數,也可以允許用戶端自動尋找專案 ID。如要自動尋找專案 ID,設定檔中的服務帳戶必須在專案中具備「瀏覽器」角色 (roles/browser
),或具備同等權限的角色。詳情請參閱google-auth
套件的使用者指南。gcloud
如要使用 Workload Identity 聯盟進行驗證,請使用
gcloud auth login
指令:gcloud auth login --cred-file=FILEPATH.json
將
FILEPATH
替換為憑證設定檔的路徑。gcloud CLI 363.0.0 以上版本支援 gcloud CLI 中的 Workload Identity Federation。
Terraform
如果您使用 3.61.0 以上版本,Google Cloud 供應商支援工作負載身分聯盟:
terraform { required_providers { google = { source = "hashicorp/google" version = "~> 3.61.0" } } }
bq
如要使用 Workload Identity 聯盟進行驗證,請使用
gcloud auth login
指令,如下所示:gcloud auth login --cred-file=FILEPATH.json
將
FILEPATH
替換為憑證設定檔的路徑。如要在 bq 中使用 Workload Identity Federation,請使用 gcloud CLI 390.0.0 以上版本。
您也可以執行下列指令,確認驗證作業是否正常運作:
kubectl exec example --namespace NAMESPACE -- gcloud auth print-access-token
後續步驟
- 進一步瞭解 Workload Identity 聯盟。
- 瞭解使用 Workload Identity Federation 的最佳做法。
- 瞭解如何管理 workload identity pool 和提供者。