本頁說明 GKE 的 Workload Identity Federation,包括運作方式、啟用後對 GKE 叢集的影響,以及如何在 Identity and Access Management 政策中授予 Kubernetes 實體角色。在大多數情況下,建議您使用 Workload Identity Federation for GKE,讓在 GKE 上執行的工作負載以安全可控的方式存取 Google Cloud 服務。
本頁面適用於安全專家和作業人員,他們負責管理 GKE 上的工作負載,且這些工作負載需要存取其他 Google Cloud 服務。如要進一步瞭解 Google Cloud 內容中提及的常見角色和範例工作,請參閱常見的 GKE Enterprise 使用者角色和工作。
閱讀本頁面之前,請務必先熟悉下列資源:
- 如要瞭解其他環境中的 Workload Identity 聯盟,請參閱「Workload Identity 聯盟」。
- 如要啟用及使用 Workload Identity Federation for GKE,請參閱「從 GKE 工作負載存取 API」。 Google Cloud
- 如要為機群中的叢集提供 Workload Identity 聯盟支援,請使用機群 Workload Identity。
術語
本頁會區分 Kubernetes 服務帳戶和 Identity and Access Management (IAM) 服務帳戶。
- Kubernetes 服務帳戶
- Kubernetes 資源,可為在 GKE Pod 中執行的程序提供身分。
- IAM 服務帳戶
- Google Cloud 資源,可讓應用程式對Google Cloud API 發出授權呼叫。
什麼是 Workload Identity Federation for GKE?
在 GKE 上執行的應用程式可能需要存取 Google Cloud API,例如 Compute Engine API、BigQuery Storage API 或 Machine Learning API。
透過 GKE 適用的工作負載身分聯盟,您可以使用 IAM 政策,授權 GKE 叢集中的 Kubernetes 工作負載存取特定Google Cloud API,不必手動設定,也不必使用服務帳戶金鑰檔案等安全性較低的方法。使用 Workload Identity Federation for GKE,即可為叢集中的每個應用程式指派不重複的精細身分與授權。
Workload Identity Federation for GKE 取代了使用中繼資料隱藏功能的需求。由中繼資料隱藏功能保護的敏感中繼資料,也會受到 GKE 適用的 Workload Identity Federation 保護。
您可以使用 IAM Workload Identity Federation,為在環境內外 Google Cloud執行的工作負載提供身分。您可以使用 IAM Workload Identity Federation,從 AWS、Azure 和自行管理的 Kubernetes 等平台執行的工作負載,安全地向支援 Google Cloud 的 API 進行驗證。在 GKE 中,Google Cloud 會為您管理工作負載身分集區和提供者,且不需要外部身分提供者。
GKE 適用的工作負載身分聯盟運作方式
在叢集上啟用 Workload Identity Federation for GKE 時,GKE 會執行下列操作:
為叢集的 Google Cloud專案建立固定工作負載身分集區,格式如下:
PROJECT_ID.svc.id.goog
工作負載身分集區提供命名格式,讓 IAM 瞭解並信任 Kubernetes 憑證。即使您刪除專案中的所有叢集,GKE 也不會刪除這個工作負載身分集區。
將 GKE 叢集註冊為工作負載身分集區中的身分提供者。
在每個節點上部署 GKE 中繼資料伺服器,攔截工作負載的憑證要求。
在 Google Cloud 資源上建立 IAM 允許政策
如要透過 GKE 適用的工作負載身分聯盟提供存取權,請建立 IAM 允許政策,將特定 Google Cloud 資源的存取權授予與應用程式身分相應的主體。舉例來說,您可以將 Cloud Storage 值區的讀取權限授予使用 database-reader
Kubernetes ServiceAccount 的所有 Pod。
如需支援允許政策的資源清單,請參閱「接受允許政策的資源類型」。
在 IAM 政策中使用條件
您也可以在允許政策中設定條件,限制存取範圍。條件是一種可擴充的方法,用於指定何時應套用允許政策。舉例來說,您可以使用條件,將特定 Google Cloud 資源上工作負載的臨時存取權授予使用者,不必手動管理該存取權。
如果您是在專案、資料夾或機構層級設定允許政策,而非在 Secret Manager 密鑰或 Cloud Storage 值區等特定資源上設定,條件也可能很有用。
如要在允許政策中新增條件,請參閱下列資源:
- 管理條件式角色繫結: 新增、修改或移除條件式角色繫結。
- 設定暫時存取權:使用條件在允許政策中設定 Google Cloud 資源的存取權效期。
- 標記和條件存取權:使用條件,只在資源具有特定標記時套用允許政策。
以下範例運算式適用於您可能會使用條件的常見情境。如需可在運算式中使用的屬性清單,請參閱 IAM 條件的屬性參考資料。
條件運算式範例 | ||
---|---|---|
允許在指定時間前存取 | request.time < timestamp(' 將 |
|
如果要求中的資源具有指定標記,則允許存取 | resource.matchTag(' 更改下列內容:
|
在 IAM 政策中參照 Kubernetes 資源
在 IAM 政策中,您可以使用 IAM 主體 ID 選取 Kubernetes 資源。這個 ID 的語法如下:
PREFIX://iam.googleapis.com/projects/1234567890/locations/global/workloadIdentityPools/example-project.svc.id.goog/SELECTOR
在這個範例中,請考慮下列欄位:
PREFIX
:必須是principal
或principalSet
,視您選取的資源而定。principal
是指特定資源,例如單一 ServiceAccount。principalSet
適用於屬於指定資源的多個資源,例如特定叢集中的所有 Pod。SELECTOR
:選取主體類型的字串。例如,kubernetes.serviceaccount.uid/SERVICEACCOUNT_UID
會依據 UID 選取 ServiceAccount。
下表列出 GKE 支援的主體類型:
主體 ID 類型 | 語法 |
---|---|
使用特定 Kubernetes ServiceAccount 的所有 Pod | 依名稱選取 ServiceAccount:
principal://iam.googleapis.com/projects/ 更改下列內容:
Select the ServiceAccount by UID: principal://iam.googleapis.com/projects/ 更改下列內容:
|
命名空間中的所有 Pod,無論服務帳戶或叢集為何 | principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/namespace/NAMESPACE 更改下列內容:
|
特定叢集中的所有 Pod | principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/kubernetes.cluster/https://container.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/clusters/CLUSTER_NAME 更改下列內容:
|
憑證流程
工作負載傳送要求來存取 Google Cloud API 時 (例如使用 Google Cloud 用戶端程式庫時),會發生下列驗證步驟:
- 應用程式預設憑證 (ADC) 會向 VM 上執行的 Compute Engine 中繼資料伺服器要求 Google Cloud 存取權杖。
- GKE 中繼資料伺服器會攔截權杖要求,並向 Kubernetes API 伺服器要求 Kubernetes ServiceAccount 權杖,以識別提出要求的工作負載。這項憑證是由 API 伺服器簽署的 JSON Web Token (JWT)。
- GKE 中繼資料伺服器會使用安全權杖服務,將 JWT 換成參照 Kubernetes 工作負載身分的短期聯盟存取權杖。
如「支援的產品和限制」一文所述,嘗試存取部分 Google Cloud 服務時,安全權杖服務傳回的同盟存取權杖可能會有相關限制。如果所選 Google Cloud 服務有相關限制,您可以選擇設定服務帳戶模擬功能。這個方法會產生 IAM 服務帳戶的存取權權杖,工作負載可使用該權杖存取目標服務。詳情請參閱將 Kubernetes ServiceAccount 連結至 IAM。
工作負載隨後就能存取工作負載的 IAM 主體 ID 可存取的任何 Google Cloud API。
Security Token Service 中 Exchange Token API 的配額
Security Token Service 中的 Exchange Token API 配額上限為每分鐘 6,000 個要求。如果看到 QUOTA_EXCEEDED
錯誤,可以透過「配額與系統限制」頁面,要求增加 Token exchange requests per minute
配額。
身分相同
如果主體 ID 中的中繼資料相同,且多個叢集中的工作負載共用工作負載身分識別集區 (因為這些工作負載屬於同一個 Google Cloud 專案),IAM 會將這些工作負載視為相同。舉例來說,如果您在兩個叢集中都有相同的命名空間,並在 IAM 中授予該命名空間的存取權,則這兩個叢集中該命名空間的工作負載都會取得存取權。您可以使用 IAM 條件政策,將這項存取權限制在特定叢集。
舉例來說,請參考下圖。叢集 A 和 B 屬於同一個工作負載身分識別集區。 Google Cloud 會將使用叢集 A 和叢集 B 的 backend
命名空間中 back-ksa
ServiceAccount 的應用程式視為相同身分。IAM 不會區分發出呼叫的叢集。
身分識別相同也表示您必須信任特定工作負載身分識別集區中的每個叢集。舉例來說,如果上例中的新叢集 C 由不受信任的團隊擁有,他們可以建立 backend
命名空間,並使用 back-ksa
ServiceAccount 存取 API,就像叢集 A 和叢集 B 一樣。 Google Cloud
為避免不受信任的存取權,請將叢集放在不同的專案中,確保叢集取得不同的工作負載身分識別集區,或確保命名空間名稱互不相同,避免使用通用主體 ID。
GKE 中繼資料伺服器
啟用 Workload Identity Federation for GKE 後,GKE 中的每個節點都會將中繼資料儲存在 GKE 中繼資料伺服器上。GKE 中繼資料伺服器是 Kubernetes 工作負載所需的 Compute Engine 中繼資料伺服器端點子集。
GKE 中繼資料伺服器會以 DaemonSet 形式執行,每個 Linux 節點上都有一個 Pod,每個 Windows 節點上則都有一個原生 Windows 服務。中繼資料伺服器會攔截對 http://metadata.google.internal
(169.254.169.254:80
) 的 HTTP 要求。舉例來說,GET
/computeMetadata/v1/instance/service-accounts/default/token
要求會擷取 Pod 設定模擬的 IAM 服務帳戶權杖。前往 GKE 中繼資料伺服器的流量絕不會離開代管 Pod 的 VM 執行個體。
權杖有效期限
根據預設,傳回的存取權杖效期為 1 小時 (3,600 秒)。 為減少用戶端延遲,GKE 中繼資料伺服器會快取存取權杖。在某些情況下,中繼資料伺服器傳回的快取權杖可能即將到期。
Cloud 用戶端程式庫內建邏輯,預設會檢查存取權杖是否會在接下來的 3 分 45 秒內過期。如果權杖尚未過期,GKE 會重新整理權杖。後續 API 呼叫可以使用重新整理的權杖。
如果您使用自己的程式碼直接存取 Google Cloud API,請導入類似的邏輯來處理權杖到期問題。程式碼應執行下列操作:
- 確認存取權杖是否會在 3 分 45 秒後失效。權杖酬載中的
exp
參數表示權杖到期時間戳記。 - 如果權杖將在 3 分 45 秒內到期,請發出權杖要求。
下表說明 GKE 中繼資料伺服器提供的 Compute Engine 中繼資料伺服器端點子集。如需 Compute Engine 中繼資料伺服器提供的端點完整清單,請參閱預設 VM 中繼資料值。
執行個體中繼資料
執行個體中繼資料會儲存在下列目錄中。
http://metadata.google.internal/computeMetadata/v1/instance/
項目 | 說明 |
---|---|
hostname |
節點的主機名稱。 |
id |
節點的專屬 ID。 |
service-accounts/ |
與節點相關聯的服務帳戶目錄。每個服務帳戶都會提供下列資訊:
|
zone |
GKE 節點的 Compute Engine 區域。 |
執行個體屬性
執行個體屬性會儲存在下列目錄中。
http://metadata.google.internal/computeMetadata/v1/instance/attributes/
項目 | 說明 |
---|---|
cluster-location |
叢集的 Compute Engine 區域或地區。 |
cluster-name |
GKE 叢集名稱。 |
cluster-uid |
GKE 叢集的 UID。 |
表格中列出的屬性是唯一支援的屬性。如果您嘗試存取任何不支援的屬性,kube-system
命名空間中的 gke-metadata-server
Pod 會產生並記錄 404
錯誤。錯誤訊息類似如下:
HTTP/404: generic::not_found: no child "", Reason: "NOT_FOUND", UserMessage: "Not Found"
如果您使用 istio-proxy
,會看到類似下列內容的錯誤訊息:
Error fetching GCP Metadata property gcp_gce_instance_template: metadata: GCE metadata "instance/attributes/UNSUPPORTED_ATTRIBUTE" not defined
專案中繼資料
叢集專案中繼資料會儲存在下列目錄中。
http://metadata.google.internal/computeMetadata/v1/project/
項目 | 說明 |
---|---|
project-id |
您的 Google Cloud 專案 ID。 |
numeric-project-id |
您的 Google Cloud 專案編號。 |
GKE 適用的 Workload Identity 聯盟限制
GKE 為 Google Cloud 專案建立的工作負載身分集區名稱無法變更。
GKE 在節點集區上啟用 GKE 中繼資料伺服器後,Pod 就無法再存取 Compute Engine 中繼資料伺服器。而是攔截這些 Pod 對中繼資料端點提出的要求 (在主機網路上執行的 Pod 除外)。
新建立的 Pod 需要幾秒鐘的時間,GKE 中繼資料伺服器才會開始接受要求。因此,在 Pod 生命週期的前幾秒內,嘗試使用 Workload Identity Federation for GKE 進行驗證可能會失敗。重試呼叫即可解決問題。詳情請參閱「疑難排解」。
GKE 內建的記錄和監控代理程式會繼續使用節點的服務帳戶。
Workload Identity Federation for GKE 需要手動設定 Knative serving,才能繼續發布要求指標。
為避免記憶體問題,Workload Identity Federation for GKE 會將每個節點與 GKE 中繼資料伺服器的連線數設為 200。如果節點超過這個上限,可能會發生逾時問題。
適用於 Windows Server 節點的 GKE Workload Identity Federation 已在 GKE 1.18.16-gke.1200、1.19.8-gke.1300、 1.20.4-gke.1500 以上版本推出。
GKE 中繼資料伺服器使用的記憶體資源,與叢集中的 Kubernetes 服務帳戶總數成正比。如果叢集有超過 3000 個 Kubernetes 服務帳戶,kubelet 可能會終止中繼資料伺服器 Pod。如需解決方法,請參閱「疑難排解」。
Workload Identity Federation for GKE 會在 VPC Service Controls 範圍內運作,因此可存取範圍內的資源。不過,VPC Service Controls 不會根據這些同盟身分,對跨範圍要求強制執行存取控制。您可以使用服務帳戶模擬功能,存取不同安全防護範圍內的資源。
Workload Identity Federation for GKE 的替代方案
您可以透過下列任一替代方案,使用 Workload Identity Federation for GKE 從 GKE 存取 API。Google Cloud 建議您使用 GKE 適用的 Workload Identity Federation,因為這些替代方案需要您做出某些安全性妥協。
使用節點的 Compute Engine 預設服務帳戶。您可以將節點集區做為專案中的任何 IAM 服務帳戶執行。如果您在建立節點集區時未指定服務帳戶,GKE 會使用專案的 Compute Engine 預設服務帳戶。在該節點上部署的所有工作負載都會共用 Compute Engine 服務帳戶。這可能會導致權限過度佈建,違反最低權限原則,且不適用於多租戶叢集。
匯出服務帳戶金鑰,並將金鑰儲存為 Kubernetes 密鑰,然後以磁碟區的形式掛接至 Pod。