在 AKS 和 EKS 上啟用 Workload Identity Federation

本主題說明如何為 AKSEKS 平台上的 Apigee Hybrid 安裝啟用 Workload Identity Federation。

如要在 GKE 上安裝,請按照「在 GKE 上啟用 Workload Identity」一文中的操作說明進行。

總覽

工作負載身分聯盟可讓在 Google Cloud 外部執行的應用程式,使用外部身分識別提供者的憑證模擬 Google Cloud Platform 服務帳戶。

使用工作負載身分聯盟可讓應用程式使用外部環境提供的驗證機制,有助於提升安全性,並取代服務帳戶金鑰

如需總覽,請參閱「使用 Workload Identity 聯盟的最佳做法」。

設定 Workload Identity 聯盟

如要透過 Apigee Hybrid 使用 Workload Identity Federation,請先設定叢集,然後將這項功能套用至 Apigee Hybrid 安裝作業。

事前準備

這些操作說明假設您已設定 Apigee Hybrid 安裝作業。系統會在初始安裝期間建立 IAM 服務帳戶和 Kubernetes 服務帳戶。如要瞭解如何安裝 Apigee Hybrid,請參閱「大方向」。

如要在 AKS 上安裝,請務必啟用 OpenID Connect (OIDC) 簽發者。您必須啟用這項功能,Workload Identity Federation 才能存取叢集的 OpenID Connect 中繼資料和 JSON Web Key Set (JWKS)。

設定叢集以使用 Workload Identity 聯盟。

  1. 使用下列指令,確認目前的 gcloud 設定已設為您的 Google Cloud 專案 ID:
    gcloud config get project
  2. 視需要設定目前的 gcloud 設定:

    gcloud config set project PROJECT_ID
  3. 啟用 Security Token Service API:

    使用下列指令,確認已啟用 Security Token Service API:

    gcloud services list --enabled --project PROJECT_ID | grep sts.googleapis.com

    如果 API 未啟用:

    控制台

    Enable the Security Token Service API.

    Enable the API

    指令列

    使用下列指令啟用 API:

    gcloud services enable sts.googleapis.com --project PROJECT_ID
  4. 建立工作負載身分集區和提供者。

    必要的角色

    如要取得設定 Workload Identity 聯盟所需的權限,請要求管理員授予您專案的下列 IAM 角色:

    如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」。

    您或許還可透過自訂角色或其他預先定義的角色取得必要權限。

    或者,IAM 擁有者 (roles/owner) 基本角色也包含設定身分識別聯盟的權限。您不應在正式版環境中授予基本角色,但可以在開發或測試環境中授予。

    如要建立 workload identity pool 和提供者,請執行下列操作:

    1. 判斷 AKS 叢集的簽發者網址:

      AKS

      az aks show -n NAME -g RESOURCE_GROUP --query "oidcIssuerProfile.issuerUrl" -otsv

      取代下列項目:

      • NAME:叢集名稱。
      • RESOURCE_GROUP:叢集的資源群組。

      這個指令會輸出簽發者網址。您將在後續步驟中用到簽發者網址。

      如果指令未傳回簽發者網址,請確認您已啟用 OIDC 簽發者功能。

      EKS

      aws eks describe-cluster --name NAME --query "cluster.identity.oidc.issuer" --output text
      

      NAME 替換為叢集名稱。

      這個指令會輸出簽發者網址。您會在後續步驟中用到簽發者網址。

      其他 Kubernetes

      1. 連線至 Kubernetes 叢集,並使用 `kubectl` 判斷叢集的簽發者網址:
        kubectl get --raw /.well-known/openid-configuration | jq -r .issuer
        

        您會在後續步驟中用到簽發者網址。

    2. 選用:如果 OIDC 簽發者無法公開存取,請下載叢集的 JSON Web Key Set (JWKS):
      kubectl get --raw /openid/v1/jwks > cluster-jwks.json
      

      如要檢查 OIDC 供應商是否公開,您應該可以使用 CURL 指令存取供應商網址,並收到 200 回應。

    3. 建立新的 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:(選用) 所選集區的說明。授予集區身分的存取權時會顯示這項說明。

      例如:

      gcloud iam workload-identity-pools create my-wi-pool --display-name="My workload pool" --description="My workload pool description"
    4. 將叢集新增為工作負載身分集區提供者。根據 OIDC 核發者是否可公開存取,選擇建立供應商的指令:

      可公開存取

      如果 OIDC 簽發者可公開存取,請使用下列指令建立供應商:

      gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --attribute-mapping="google.subject=assertion.sub"

      不公開

      如果 OIDC 簽發者無法公開存取,請使用下列指令建立供應商:

        gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="ISSUER" \
        --jwks-file="cluster-jwks.json" \
        --attribute-mapping="google.subject=assertion.sub"

      取代下列項目:

      • WORKLOAD_PROVIDER_ID:您選擇的不重複 workload identity pool 提供者 ID。
      • POOL_ID:您先前建立的工作負載身分集區 ID。
      • ISSUER:使用您先前決定的核發者網址做為核發者 URI。

      attribute-mapping="google.subject=assertion.sub" 將 Kubernetes 主體對應至 IAM 主體。

建立憑證設定檔

如要部署可存取 Google Cloud 資源的 Kubernetes 工作負載,請先為每個 IAM 服務帳戶建立憑證設定檔:

  1. 使用下列指令列出 IAM 服務帳戶 (也稱為「Google 服務帳戶」):
    gcloud iam service-accounts list --project PROJECT_ID

    您需要為下列 IAM 服務帳戶建立憑證設定檔:

    Prod

    正式環境:

    DISPLAY NAME         EMAIL                                                      DISABLED
    apigee-cassandra     apigee-cassandra@my_project_id.iam.gserviceaccount.com     False
    apigee-mart          apigee-mart@my_project_id.iam.gserviceaccount.com          False
    apigee-metrics       apigee-metrics@my_project_id.iam.gserviceaccount.com       False
    apigee-runtime       apigee-runtime@my_project_id.iam.gserviceaccount.com       False
    apigee-synchronizer  apigee-synchronizer@my_project_id.iam.gserviceaccount.com  False
    apigee-udca          apigee-udca@my_project_id.iam.gserviceaccount.com          False
    apigee-watcher       apigee-watcher@my_project_id.iam.gserviceaccount.com       False
    

    非正式環境

    非正式環境:

    DISPLAY NAME         EMAIL                                                      DISABLED
    apigee-non-prod      apigee-non-prod@my_project_id.iam.gserviceaccount.com      False
    
  2. 為上述清單中的每個 IAM 服務帳戶建立憑證設定檔。您需要這些憑證設定檔,才能將 Apigee Hybrid 設定為使用 Workload Identity Federation:

    程式碼

    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/
      --credential-source-type=text \
      --output-file=SERVICE_ACCOUNT_NAME-credential-configuration.json
      

    範例

    gcloud iam workload-identity-pools create-cred-config \
      projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider \
      --service-account=apigee-cassandra@myhybridporg.iam.gserviceaccount.com \
      --credential-source-file=/var/
      --credential-source-type=text \
      --output-file=apigee-cassandra-credential-configuration.json
      

    其中:

    • PROJECT_NUMBER:含有 workload identity pool 的專案專案編號。請務必輸入專案編號,而非專案 ID。
    • POOL_ID:工作負載身分集區的 ID
    • WORKLOAD_PROVIDER_ID:workload identity pool 提供者的 ID
    • SERVICE_ACCOUNT_EMAIL:服務帳戶的電子郵件地址 (如果您已將 Kubernetes ServiceAccount 設為使用 IAM 服務帳戶模擬)。

    憑證設定檔可讓 [Cloud 用戶端程式庫](/apis/docs/cloud-client-libraries)、gcloud CLI 和 Terraform 判斷下列事項:

    • 如何取得外部憑證
    • 要使用的 workload identity pool 和提供者
    • 要模擬哪個服務帳戶

    設定 Apigee Hybrid 使用 Workload Identity 聯盟

    1. 將每個輸出檔案 (SERVICE_ACCOUNT_NAME-credential-configuration.json) 複製或移動到下列圖表目錄 (或其子目錄)。這些是您在「建立憑證設定檔」步驟中建立的檔案。

      正式環境

      服務帳戶 Apigee Helm 資訊套件目錄
      apigee-cassandra apigee-datastore/
      apigee-mart apigee-org/
      apigee-metrics apigee-telemetry/
      apigee-runtime apigee-env/
      apigee-synchronizer apigee-env/
      apigee-udca apigee-org/
      apigee-env/
      apigee-watcher apigee-org/

      非正式環境

      服務帳戶 Apigee Helm 圖表
      apigee-non-prod apigee-datastore/
      apigee-telemetry/
      apigee-org/
      apigee-env/
    2. 對叢集的覆寫檔案進行下列全域變更:

      程式碼

      gcp:
        workloadIdentity:
          enabled: false # must be set to false to use Workload Identity Federation
        federatedWorkloadIdentity:
          enabled: true
          audience: "AUDIENCE"
          credentialSourceFile: "/var/run/service-account/token"
      

      範例

      gcp:
        workloadIdentity:
          enabled: false
        federatedWorkloadIdentity:
          enabled: true
          audience: "//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider"
          credentialSourceFile: "/var/run/service-account/token"
      

      其中:AUDIENCE 是 Workload Identity 提供者允許的目標對象。如要找出這個值,請在任一憑證設定檔中搜尋「audience: 」一詞。每個憑證設定檔中的目標對象值都相同。

      舉例來說,在下列範例 apigee-udca-credential-configuration.json 檔案中:

      {
        "universe_domain": "googleapis.com",
        "type": "external_account:,"
        "audience": "//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider",
        "subject_token_type": "urn:ietf:params:oauth: token-type:jwt",
        "token_url": "https://sts.googleapis.com/v1/token",
        "service
        "impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/apigee-udca@myhybridproject.iam.gserviceaccount.com:generateAccessToken",
        "credential_source": {
          "file": "/var/run/service-account/token",
          "format": {
            "type": "text"
          }
        }
      }

      目標對象值為 //iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider

    3. 使用 Workload Identity 聯盟,為每個元件設定覆寫。請根據安裝方式,選取憑證檔案、Kubernetes 密鑰或 Vault 的操作說明。

      認證檔案

      serviceAccountPath 的值替換為對應 IAM 服務帳戶的憑證來源檔案。這必須是相對於圖表目錄的路徑。例如:

      envs:
      - name: ENVIRONMENT_NAME
        serviceAccountPaths:
          synchronizer: apigee-synchronizer-credential-configuration.json
          runtime: apigee-runtime-credential-configuration.json
          udca: apigee-udca-credential-configuration.json
      
      mart:
        serviceAccountPath: apigee-mart-credential-configuration.json
      
      connectAgent:
        serviceAccountPath: apigee-mart-credential-configuration.json
      
      metrics:
        serviceAccountPath: apigee-metrics-credential-configuration.json
      
      udca:
        serviceAccountPath: apigee-udca-credential-configuration.json
      
      watcher:
        serviceAccountPath: apigee-watcher-credential-configuration.json
      

      K8s 密鑰

      1. 為每個憑證設定檔,使用憑證來源檔案建立新的 Kubernetes 密鑰。
        kubectl create secret -n APIGEE_NAMESPACE generic SECRET_NAME --from-file="client_secret.json=CREDENTIAL_CONFIGURATION_FILE"

        例如:

        kubectl create secret -n apigee generic udca-workoad-identity-secret --from-file="client_secret.json=./apigee-udca-credential-configuration.json"
      2. serviceAccountRef 的值替換成新密鑰。例如:
        udca:
          serviceAccountRef: udca-workoad-identity-secret
        

      保管箱

      使用對應的憑證來源檔案,更新 Vault 中每個服務帳戶的服務帳戶金鑰 SAKEY。所有元件的程序都類似。舉例來說,UDCA 的

      SAKEY=$(cat .apigee-udca-credential-configuration.json); kubectl -n APIGEE_NAMESPACE exec vault-0 -- vault kv patch secret/apigee/orgsakeys udca="$SAKEY"

      詳情請參閱Storing service account keys in Hashicorp Vault

    4. 使用 helm upgrade 指令,將變更套用至每個受影響的元件:

      如果您更新了 Vault 服務帳戶金鑰,請更新 apigee-operator 圖表。

      helm upgrade operator apigee-operator/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      

      按照下列順序更新其餘受影響的圖表:

      helm upgrade datastore apigee-datastore/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      
      helm upgrade telemetry apigee-telemetry/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      
      helm upgrade $ORG_NAME apigee-org/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
      

      更新每個環境的 apigee-env 圖表,每次都取代 $ENV_RELEASE_NAMEENV_NAME

      helm upgrade $ENV_RELEASE_NAME apigee-env/ \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        --set env=$ENV_NAME \
        -f overrides.yaml
      

      如需元件清單和對應的圖表,請參閱 Apigee Hybrid Helm 參考資料

    授予 Kubernetes 服務帳戶存取權

    1. 使用下列指令列出 Kubernetes 服務帳戶
      kubectl get sa -n APIGEE_NAMESPACE
    2. 如要授予 Kubernetes 服務帳戶模擬相關聯 IAM 服務帳戶的權限,請參閱下表。下表列出預設的 Apigee IAM 服務帳戶名稱。如果您使用自訂服務帳戶名稱,請使用對應的 IAM 服務帳戶:
      Kubernetes 服務帳戶 IAM 服務帳戶
      機構層級 Kubernetes 服務帳戶
      apigee-connect-agent-ORG_NAME-ORG_HASH_ID apigee-mart
      apigee-mart-ORG_NAME-ORG_HASH_ID apigee-mart
      apigee-metrics-apigee-telemetry apigee-metrics
      apigee-open-telemetry-collector-apigee-telemetry apigee-metrics
      apigee-udca-ORG_NAME-ORG_HASH_ID apigee-udca
      apigee-watcher-ORG_NAME-ORG_HASH_ID apigee-watcher
      環境層級 Kubernetes 服務帳戶
      apigee-runtime-ORG_NAME-ENV_NAME-ENV_HASH_ID apigee-runtime
      apigee-synchronizer-ORG_NAME-ENV_NAME-ENV_HASH_ID apigee-synchronizer
      Cassandra 備份與還原 (如已啟用)
      apigee-cassandra-backup-sa apigee-cassandra
      apigee-cassandra-restore-sa apigee-cassandra

      其中:

      • ORG_NAME:機構名稱的前 15 個字元。
      • ORG_HASH_ID:機構全名的專屬雜湊 ID。
      • ENV_NAME:環境名稱的前 15 個字元。
      • ENV_HASH_ID:機構和環境名稱的專屬雜湊 ID。

      例如:

      • apigee-connect-agent-myhybridorg-123abcd
      • apigee-runtime-myhybridorg-prodenv-234bcde

      使用下列指令,授予每個 Kubernetes 服務帳戶模擬適當 IAM 服務帳戶的權限:

      gcloud iam service-accounts add-iam-policy-binding \
        IAM_SA_NAME@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:與 Apigee 機構相關聯的專案 ID。
      • PROJECT_NUMBER:您建立 workload identity pool 的專案專案編號
      • POOL_ID:工作負載身分集區 ID。
      • MAPPED_SUBJECT:ID 權杖中您對應至 google.subject 的聲明,是 Kubernetes ServiceAccount。舉例來說,如果您對應 google.subject=assertions.sub,且 ID 權杖包含 "sub": "system:serviceaccount:default:my-kubernetes-serviceaccount",則 MAPPED_SUBJECTsystem:serviceaccount:default:my-kubernetes-serviceaccount

    如要進一步瞭解 Workload Identity 聯盟和最佳做法,請參閱「使用 Workload Identity 聯盟的最佳做法」。