在 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 聯盟可以存取叢集的 OpenID Connect 中繼資料和 JSON Web 金鑰集 (JWKS)。

設定叢集以使用 Workload Identity Federation。

  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 集區和提供者,請按照下列步驟操作:

    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 金鑰集 (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 服務帳戶建立憑證設定檔:

    正式發布階段

    正式環境:

    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:包含工作負載身分識別池的專案專案編號。請務必輸入專案編號,而非專案 ID。
    • POOL_ID:工作負載身分集區的 ID
    • WORKLOAD_PROVIDER_ID:工作負載身分集區提供者的 ID
    • SERVICE_ACCOUNT_EMAIL:如果您將 Kubernetes 服務帳戶設為使用身分與存取權管理服務帳戶冒用功能,則為服務帳戶的電子郵件地址。

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

    • 外部憑證的取得來源
    • 要使用的 Workload Identity 集區和提供者
    • 要模擬哪個服務帳戶

    設定 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_NAME abdENV_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:您建立工作負載身分池的專案編號
      • POOL_ID:工作負載身分集區 ID。
      • MAPPED_SUBJECT:您已對應至 google.subject 的 ID 權杖中的憑證所屬的 Kubernetes 服務帳戶。舉例來說,如果您已對應 google.subject=assertions.sub,且 ID 權杖包含 "sub": "system:serviceaccount:default:my-kubernetes-serviceaccount",則 MAPPED_SUBJECT 就是 system:serviceaccount:default:my-kubernetes-serviceaccount

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