examlab .net 用最有效率的方法,考取最有價值的證照
本篇導覽 約 18 分鐘

工作負載身分:保護 GKE 與多雲端應用程式

3,500 字 · 約 18 分鐘閱讀 ·

掌握消除應用程式對靜態 JSON 金鑰依賴的技術。學習為 GKE 實施工作負載身分 (Workload Identity),以及為 AWS、Azure 和地端環境實施聯合驗證 (Federation)。

立即做 20 題練習 → 免費 · 不用註冊 · PSE

工作負載身分簡介

對於 GCP 專業雲端安全工程師 (PSE) 來說,管理機密資訊 (Secrets) 是風險最高的活動之一。傳統的應用程式驗證依賴於下載服務帳戶的 JSON 金鑰,並將其作為「機密 (Secrets)」掛載到容器中。這在安全性上是一場噩夢:金鑰經常被提交到 Git、在記錄中洩漏,或從遭到入侵的 Pod 中被盜。

工作負載身分 (Workload Identity) (針對 GKE) 和工作負載身分聯合 (Workload Identity Federation) (針對外部雲端) 代表了現代安全性的「黃金標準」。它們允許你的應用程式使用其「現有的」身分 (如 K8s 服務帳戶、AWS IAM 角色等) 向 Google Cloud 服務進行驗證,而無需任何靜態、長效的機密金鑰。

白話文解釋

1. 自動識別證製卡機 (工作負載身分)

想像一個高安全性的實驗室。與其給每個研究員一把永久的實體鑰匙,不如在入口處設置一台「自動識別證製卡機」。當一名研究員 (GKE Pod) 走近時,機器會驗證他們的實驗袍和 ID (K8s 服務帳戶),然後吐出一張臨時的、效期 1 小時的識別證。識別證過期後就失效了。這就是 GKE 元資料伺服器 (Metadata Server) 在運作。

2. 貨幣兌換處 (工作負載身分聯合)

想像你正從英國前往美國旅行。你無法在紐約使用英鎊,但你可以去貨幣兌換處。你出示有效的英鎊 (AWS 權杖),辦事員會根據預先商定的匯率 (屬性對應) 給你等值的美金 (Google 存取權杖)。你不需要「全球通用信用卡」(JSON 金鑰)。

3. 受信任的特使 (OIDC 聯合驗證)

想像兩個王國之間簽署了和平協議。A 王國不認識 B 王國的士兵,但他們信任 B 王國的國王。如果一名士兵攜帶有 B 王國國王簽署的信件 (OIDC 權杖),A 王國就會將他們視為賓客。Google Cloud 信任「簽發者」(如 AWS/Azure/Okta) 來聲明工作負載的身分。

針對 GKE 的工作負載身分 (Workload Identity)

這是運行在 GKE 上的應用程式存取 Google Cloud 服務的推薦方式。

運作方式

  1. 你建立一個具有所需 IAM 角色的 Google 服務帳戶 (GSA)
  2. 你在 GKE 叢集中建立一個 Kubernetes 服務帳戶 (KSA)
  3. 你透過授予 GSA 針對該 KSA 的 roles/iam.workloadIdentityUser 角色,將兩者「繫結」在一起。
  4. GKE 元資料伺服器會攔截來自 Pod 的請求,並將 KSA 的權杖交換為 GSA 的存取權杖。

工作負載身分 (Workload Identity) 是一項 GKE 功能,它橋接了 Kubernetes 身分與 Google Cloud IAM 身分,消除了在叢集內管理服務帳戶金鑰的需求。

針對外部工作負載的工作負載身分聯合

這將「無金鑰」概念擴展到在 Google Cloud 之外運行的工作負載 (如 AWS、Azure、GitHub Actions、地端環境)。

關鍵組件

  • 工作負載身分集區 (Workload Identity Pool): 外部身分的容器 (例如 "AWS-Production-Pool")。
  • 工作負載身分提供者 (Workload Identity Provider): 定義 Google 與外部 IdP (如 AWS、Azure 或 OIDC/SAML) 之間的關係。
  • 屬性對應 (Attribute Mapping): 將外部宣告 (Claims,例如 aws:PrincipalArn) 對應到 Google 內部屬性。

AWS/Azure 的聯合驗證

與其在 AWS Secrets Manager 中儲存 Google JSON 金鑰,你的 AWS Lambda 或 EC2 執行個體會使用其原生的 執行個體設定檔 (Instance Profile) 來請求 Google 權杖。

工作負載身分聯合是 PSE 唯一推薦用於 CI/CD 流程中 GitHub Actions 向 Google Cloud 進行驗證的方式。

將 K8s 服務帳戶對應到 GSA

繫結是雙向的:

  • K8s 註解 (Annotation): KSA 必須使用 GSA 的電子郵件進行註解。
  • IAM 繫結: GSA 必須有一個政策繫結,允許特定的 KSA (透過命名空間和名稱識別) 冒充它。

K8s 註解範例

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    iam.gke.io/gcp-service-account: [email protected]
  name: my-app-ksa
  namespace: default

KSA 與 GSA 的繫結是雙向的,PSE 場景題常考這一點。光是在 KSA 上加 iam.gke.io/gcp-service-account 註解並不足夠 — 你還必須在 GSA 上授予 roles/iam.workloadIdentityUser,成員為 serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]。任何一邊缺失,GKE Metadata Server 都會回傳靜默的 403。

消除對靜態 JSON 金鑰的需求

為什麼這是 PSE 的核心要求?

  • 更換 (Rotation): 短期權杖每小時自動更換。
  • 撤銷: 如果 Pod 遭到入侵,刪除 KSA 或 IAM 繫結會立即撤銷存取權。
  • 合規性: 稽核更加清晰,因為沒有需要追蹤的「機密檔案」。

屬性對應與條件

在聯合驗證中,你可能不希望信任來自 AWS 帳戶的「每個」工作負載。

宣告對應 (Mapping Claims)

你將傳入的 AWS 宣告 (如 arn:aws:sts::123456789012:assumed-role/MyRole) 對應到 Google 屬性 (如 google.subject)。

條件式存取

你可以在身分提供者中新增 CEL 條件: assertion.arn.startsWith('arn:aws:iam::123456789012:role/Production') 結果:只有帶有 'Production' 角色的 AWS 工作負載才能交換權杖。

在 Workload Identity Provider 上加 CEL attribute_condition (例如 assertion.arn.startsWith('arn:aws:iam::123456789012:role/Production'),或 GitHub Actions 場景的 assertion.repository == 'my-org/my-repo'),可在 STS 簽發聯合權杖之前就過濾掉不該進來的身分。這比只在 IAM 政策層做過濾更早收斂影響範圍,能擋住不該存取的 AWS 角色或被 fork 的儲存庫,避免它們進到 google.subject

GKE 元資料伺服器保護

元資料伺服器是 GKE 工作負載身分的「核心」。

  • GKE 沙箱 (GKE Sandbox): 對於高安全性環境,使用 GKE 沙箱將元資料伺服器與 Pod 的核心進一步隔離。
  • 元資料隱藏 (Metadata Concealment): 在舊版 GKE 中用於向 Pod 隱藏預設的 GCE 元資料;工作負載身分取代並改進了這一功能。

如果你不啟用工作負載身分,Pod 可能會退而使用節點的預設服務帳戶,這通常擁有廣泛的「編輯者 (Editor)」權限。這是 PSE 考試中常見的陷阱。

排除身分權杖交換故障

  1. 檢查註解: KSA 是否已正確註解?
  2. 驗證 IAM 繫結: GSA 是否擁有針對該 KSA 的 roles/iam.workloadIdentityUser 權限?
  3. STS 記錄: 對於聯合驗證,檢查安全性權杖服務 (STS) 記錄,查看外部權杖是否被拒絕。
  4. 權杖格式: 確保 OIDC 提供者發送的是有效的 JWT (JSON Web Token)。

多雲端工作負載身分的最佳實務

  1. 每個環境一個集區:DevStageProd 使用獨立的身分集區。
  2. 最小權限對應: 只對應 IAM 決策實際需要的屬性。
  3. 使用短期權杖:expiresIn 參數設定為任務所需的最小值。
  4. 監控權杖交換: 稽核 iam.googleapis.com/WorkloadIdentityPool 資源的使用情況。

工作負載身分的 CLI 指令

建立工作負載身分集區

gcloud iam workload-identity-pools create "my-aws-pool" \
    --location="global" \
    --display-name="AWS Production Pool"

新增 AWS 提供者

gcloud iam workload-identity-pools providers create-aws "my-aws-provider" \
    --workload-identity-pool="my-aws-pool" \
    --account-id="123456789012" \
    --location="global"

授予 KSA 冒充 GSA 的權限

gcloud iam service-accounts add-iam-policy-binding \
    [email protected] \
    --role="roles/iam.workloadIdentityUser" \
    --member="serviceAccount:my-project.svc.id.goog[my-namespace/my-ksa]"

GKE 工作負載身分的成員格式為: serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]

PSE 安全性最佳實務

  1. 禁用節點元資料: 確保所有節點集區都設定了 workload-metadata-configuration=GKE_METADATA
  2. 使用受控識別 (Managed Identities): 在 Azure 中,使用「系統指派的受控識別」進行聯合驗證。
  3. 稽核權杖使用: 定期檢查成功與失敗的 GenerateAccessToken 呼叫。
  4. 命名空間隔離: 如果 Pod 需要不同的 GSA 權限,切勿跨命名空間共用 KSA。

故障排除場景

場景:Pod 在呼叫 BigQuery 時收到 "403 Forbidden"。

診斷: KSA 已註解,但 GSA 缺少 BigQuery Data Viewer 角色,或者 GSA 沒有針對該 KSA 的工作負載身分繫結。 修正: 在 GSA 上執行 gcloud iam service-accounts get-iam-policy 並驗證 id.goog 成員繫結。

場景:GitHub Actions 無法向 Google Cloud 進行驗證。

診斷: 工作負載身分提供者中的 issuer 與 GitHub 的 OIDC URL 不匹配,或者 subject 對應不正確。 修正: 根據 GitHub 官方 OIDC 文件驗證提供者設定。

PSE 考試場景

場景 1:減少金鑰管理

「你的公司在 3 個雲端平台上有 500 個微服務。管理它們 Google Cloud 憑證最安全的方法是什麼?」 答案: 為所有 3 個雲端實施工作負載身分聯合 (Workload Identity Federation),以消除儲存、更換和管理 500 個 JSON 金鑰的需求。

場景 2:GKE 多租戶

「兩個不同的團隊在同一個 GKE 叢集但不同的命名空間中運行 Pod。你如何確保 A 團隊的 Pod 無法使用 B 團隊的權限?」 答案: 在每個命名空間中建立獨立的 KSA,並將它們繫結到不同的 GSA。使用 Kubernetes 網路政策 (Network Policies) 進一步隔離命名空間。

常見問題 (FAQ)

Q1:工作負載身分是否適用於 Autopilot 叢集? A1:是的,工作負載身分在 GKE Autopilot 中預設為啟用。

Q2:我可以與地端的 LDAP 伺服器進行聯合驗證嗎? A2:不能直接進行。你必須使用符合 OIDC 標準的包裝器 (如 Okta、Keycloak 或 Ping Identity) 作為橋樑。

Q3:工作負載身分聯合的費用是多少? A3:Google Cloud 不對聯合驗證服務本身收費,但適用標準的 API 使用費用。

總結檢查清單

  • 解釋 GKE 工作負載身分中的權杖交換流程。
  • 列出為 AWS 設定工作負載身分聯合的步驟。
  • 定義「工作負載身分集區」及其用途。
  • 為工作負載身分註解 KSA。
  • 描述短期權杖優於 JSON 金鑰的安全性優勢。

官方資料來源

更多 PSE 主題