將服務帳戶金鑰儲存在 Hashicorp Vault

在 Hashicorp Vault 中儲存服務帳戶密鑰

這項功能可讓您將 Apigee Hybrid 的 Google 服務帳戶憑證儲存在外部密碼管理工具 Hashicorp Vault 中。外部密鑰管理工具可讓您管理資料在 Kubernetes 中的儲存方式,包括管理資料落地和精細的存取控制。

如果您未使用 GKE 叢集上的 Workload IdentityEKS 和 AKS 上的 Workload Identity Federation,Apigee Hybrid 元件必須驗證 Google 服務帳戶,才能執行工作。在 Apigee Hybrid 中儲存及參照 Google 服務帳戶金鑰的方法有三種:

  • 儲存在硬碟上的服務帳戶 JSON 金鑰檔案 (.json 檔案)。在覆寫中,使用 serviceAccountPath 設定屬性參照這些項目。例如:
    logger:
      serviceAccountPath: service-accounts/myhybridorg-apigee-logger.json
    
  • 儲存在硬碟上的服務帳戶 JSON 金鑰檔案 (.json 檔案)。在覆寫中,使用 serviceAccountPath 設定屬性參照這些項目。請參閱「關於服務帳戶」。
  • 儲存在 Kubernetes 密鑰中的服務帳戶憑證。在覆寫中,使用 serviceAccountRef 設定屬性參照這些項目。請參閱「將服務帳戶金鑰儲存在 Kubernetes 密鑰中」。
  • 儲存在 Hashicorp Vault 中的服務帳戶憑證,如本指南所述。在覆寫中,使用 serviceAccountSecretProviderClass 設定屬性參照這些項目。

設定在 Vault 中儲存服務帳戶密鑰

安裝 CSI 驅動程式和 Vault 供應商

如果尚未在叢集上使用 Helm 安裝 CSI 驅動程式,請按照「Secrets Store CSI Driver: Installation」一文中的指示操作。詳情請參閱 Vault 說明文件中的「安裝 Vault CSI 供應商」。

如要瞭解 Apigee Hybrid 支援的最低 CSI 驅動程式版本,請參閱「Apigee Hybrid 支援的平台和版本」。

建立 Vault 密鑰、政策和角色

使用 Vault UI 或 API 建立密鑰,並授予 Apigee Hybrid 使用的 Kubernetes 服務帳戶讀取這些密鑰的權限。

  1. 以以下格式建立機構和環境專屬的密鑰:
    密鑰密鑰資料
    secret/data/apigee/orgsakeys
    {
      "cassandraBackup": "***",
      "cassandraRestore": "***",
      "connectAgent": "***",
      "logger": "***",
      "mart": "***",
      "metrics": "***",
      "mint": "***",
      "udca": "***",
      "watcher": "***"
    }
    secret/data/apigee/envsakeys-ENV_NAME
    {
      "runtime": "***",
      "synchronizer": "***",
      "udca": "***"
    }

    將每對 "***" 中的內容,替換為對應 Apigee 元件的 Google 服務帳戶 .json 檔案內容。apigee-cassandra-backupapigee-cassandra-restore 都使用 apigee-cassandra 服務帳戶。例如:

    {
      "cassandraBackup": "{
        "type": "service_account",
        "project_id": "my-project",
        "private_key_id": "PRIVATE_KEY_ID",
        "private_key": "-----BEGIN PRIVATE KEY-----\nPRIVATE_KEY_TEXT\n-----END PRIVATE KEY-----\n",
        "client_email": "apigee-cassandra@myhybridorg.iam.gserviceaccount.com",
        "client_id": "123456789012345678901",
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://oauth2.googleapis.com/token",
        "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
        "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/apigee-cassandra%40myhybridorg.iam.gserviceaccount.com",
        "universe_domain": "googleapis.com"
      }",
      "cassandraRestore":...
    ...
    }
        
  2. 授予機構密鑰的存取權。建立名為 orgsakeys-auth-policy.txt 的文字檔,並在其中加入下列內容:
    path "secret/data/apigee/orgsakeys" {
      capabilities = ["read"]
    }
  3. 在 Vault 中建立政策,授予機構密鑰的存取權:
    vault policy write apigee-orgsakeys-auth orgsakeys-auth-policy.txt
  4. 為每個環境建立名為 envsakeys-ENV_NAME-auth-policy.txt 的文字檔案,並在其中加入下列內容:
    path "secret/data/apigee/envsakeys-ENV_NAME" {
      capabilities = ["read"]
    }

    針對每個環境重複這個步驟。

  5. 在 Vault 中建立政策,授予環境密碼的存取權:
    vault policy write apigee-envsakeys-ENV_NAME-auth envsakeys-ENV_NAME-auth-policy.txt

    針對每個環境重複這個步驟。

  6. 建立名為 generate-encoded-sas.sh 的指令碼,內容如下:
    # generate-encoded-sas.sh
    
    ORG=$APIGEE_ORG            # Apigee organization name
    ENVS=$APIGEE_ENV_LIST      # comma separated env names, for example: dev,prod
    
    ORG_SHORT_NAME=$(echo $ORG | head -c 15)
    ENCODE=$(echo -n $ORG | shasum -a 256 | head -c 7)
    ORG_ENCODE=$(echo "$ORG_SHORT_NAME-$ENCODE")
    NAMES=apigee-manager,apigee-cassandra-default,apigee-cassandra-backup-sa,apigee-cassandra-restore-sa,apigee-cassandra-schema-setup-${ORG_ENCODE},apigee-cassandra-schema-val-${ORG_ENCODE},apigee-cassandra-user-setup-${ORG_ENCODE},apigee-mart-${ORG_ENCODE},apigee-mint-task-scheduler-${ORG_ENCODE},apigee-connect-agent-${ORG_ENCODE},apigee-watcher-${ORG_ENCODE},apigee-udca-${ORG_ENCODE},apigee-metrics-apigee-telemetry,apigee-open-telemetry-collector-apigee-telemetry,apigee-logger-apigee-telemetry
    
    for ENV in ${ENVS//,/ }
    do
      ENV_SHORT_NAME=$(echo $ENV | head -c 15)
      ENCODE=$(echo -n $ORG:$ENV | shasum -a 256 | head -c 7)
      ENV_ENCODE=$(echo "$ORG_SHORT_NAME-$ENV_SHORT_NAME-$ENCODE")
      NAMES+=,apigee-synchronizer-${ENV_ENCODE},apigee-runtime-${ENV_ENCODE}
    done
    
    echo $NAMES
    
  7. 執行指令碼,產生要繫結政策的服務帳戶名稱清單:
    ./generate-encoded-sas.sh

    輸出內容應為以半形逗號分隔的 Kubernetes 服務帳戶名稱清單,類似於以下範例:

    ./generate-encoded-sas.sh
    apigee-manager,apigee-cassandra-default,apigee-cassandra-backup-sa,
    apigee-cassandra-restore-sa,apigee-cassandra-schema-setup-myhybrido
    rg-5b044c1,apigee-cassandra-schema-val-myhybridorg-5b044c1,apigee-c
    assandra-user-setup-myhybridorg-5b044c1,apigee-mart-myhybridorg-5b0
    44c1,apigee-mint-task-scheduler-myhybridorg-5b044c1,apigee-connect-
    agent-myhybridorg-5b044c1,apigee-watcher-myhybridorg-5b044c1,apigee
    -udca-myhybridorg-5b044c1,apigee-metrics-apigee-telemetry,apigee-op
    en-telemetry-collector-apigee-telemetry,apigee-logger-apigee-teleme
    try,apigee-synchronizer-myhybridorg-dev-ee52aca,apigee-runtime-myhy
    bridorg-dev-ee52aca,apigee-synchronizer-myhybridorg-prod-2d0221c,ap
    igee-runtime-myhybridorg-prod-2d0221c
  8. 將輸出文字複製到並分成清單,一個清單用於 org 服務帳戶名稱,另一個清單用於每個環境的 env 服務帳戶名稱。輸出清單中會先列出 org 服務帳戶,最多 apigee-logger-apigee-telemetry 個。

    上一個範例中的 org 服務名稱清單:

    apigee-manager,apigee-cassandra-default,apigee-cassandra-backup-sa,
    apigee-cassandra-restore-sa,apigee-cassandra-schema-setup-myhybrido
    rg-5b044c1,apigee-cassandra-schema-val-myhybridorg-5b044c1,apigee-c
    assandra-user-setup-myhybridorg-5b044c1,apigee-mart-myhybridorg-5b0
    44c1,apigee-mint-task-scheduler-myhybridorg-5b044c1,apigee-connect-
    agent-myhybridorg-5b044c1,apigee-watcher-myhybridorg-5b044c1,apigee
    -udca-myhybridorg-5b044c1,apigee-metrics-apigee-telemetry,apigee-op
    en-telemetry-collector-apigee-telemetry,apigee-logger-apigee-teleme
    try

    env 服務帳戶名稱的模式為 apigee-synchronizer-ORG_NAME-ENV_NAME-HASH_TEXTapigee-runtime-ORG_NAME-ENV_NAME-HASH_TEXT。請為每個環境分別建立清單。舉例來說,上一個範例的輸出內容可以分成以下兩個清單:

    dev 環境:

    apigee-synchronizer-myhybridorg-dev-ee52aca,apigee-runtime-myhybrid
    org-dev-ee52aca

    prod 環境:

    apigee-synchronizer-myhybridorg-prod-2d0221c,apigee-runtime-myhybri
    dorg-prod-2d0221c
  9. 使用這項政策建立保管箱角色,繫結機構專屬的 Apigee 服務帳戶:
    vault write auth/kubernetes/role/apigee-orgsakeys \
        bound_service_account_names=LIST_OF_ORG_SA_NAMES \
        bound_service_account_namespaces=apigee \
        policies=apigee-orgsakeys-auth \
        ttl=1m
    
  10. 為每個環境的服務帳戶金鑰建立 Vault 角色:
    vault write auth/kubernetes/role/apigee-envsakeys-ENV_NAME \
        bound_service_account_names=LIST_OF_ENV_NAME_SA_NAMES \
        bound_service_account_namespaces=apigee \
        policies=apigee-envsakeys-ENV_NAME-auth \ 
        ttl=1m
    

    針對每個環境重複這個步驟。

建立 SecretProviderClass 物件

SecretProviderClass 資源會告知 CSI 驅動程式,要求密碼時要與哪個供應商通訊。服務帳戶金鑰必須透過這個物件設定。下表顯示 Apigee Hybrid 預期的檔案名稱 (objectNames):

服務帳戶預期的密鑰檔案名稱
Cassandra 備份 cassandraBackup
還原 Cassandra cassandraRestore
Connect 代理程式 connectAgent
Logger logger
MART mart
指標 metrics
營利
(如果使用 Monetization for Apigee Hybrid)
mint
執行階段 runtime
同步處理工具 synchronizer
UDCA udca
Watcher watcher
  1. 請使用下列 SecretProviderClass 範本,為機構專屬密鑰設定這項資源:
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: apigee-orgsakeys-spc
    spec:
      provider: vault
      parameters:
        roleName: apigee-orgsakeys
        vaultAddress: VAULT_ADDRESS
        # "objectName" is an alias used within the SecretProviderClass to reference
        # that specific secret. This will also be the filename containing the secret.
        # Apigee Hybrid expects these exact values so they must not be changed.
        # "secretPath" is the path in Vault where the secret should be retrieved.
        # "secretKey" is the key within the Vault secret response to extract a value from.
        objects: |
          - objectName: "cassandraBackup"
            secretPath: ""
            secretKey: ""
          - objectName: "cassandraRestore"
            secretPath: ""
            secretKey: ""
          - objectName: "connectAgent"
            secretPath: ""
            secretKey: ""
          - objectName: "logger"
            secretPath: ""
            secretKey: ""
          - objectName: "mart"
            secretPath: ""
            secretKey: ""
          - objectName: "metrics"
            secretPath: ""
            secretKey: ""
          - objectName: "mint"
            secretPath: ""
            secretKey: ""
          - objectName: "udca"
            secretPath: ""
            secretKey: ""
          - objectName: "watcher"
            secretPath: ""
            secretKey: ""
    

    VAULT_ADDRESS 是 Vault 伺服器的執行端點。如果 Vault 與 Apigee 位於同一叢集,格式通常為 http://vault.APIGEE_NAMESPACE.svc.cluster.local:VAULT_SERVICE_PORT

    將範本儲存至名為 spc-org.yaml 的檔案。

  2. 將機構專屬的 SecretProviderClass 套用至 apigee 命名空間:
    kubectl -n APIGEE_NAMESPACE apply -f spc-org.yaml
  3. 針對每個環境,請使用下列 SecretProviderClass 範本,為環境專屬的密鑰設定這項資源。針對每個環境重複這個步驟:
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: apigee-envsakeys-ENV_NAME-spc
    spec:
      provider: vault
      parameters:
        roleName: apigee-envsakeys-ENV_NAME
        vaultAddress: VAULT_ADDRESS
        # "objectName" is an alias used within the SecretProviderClass to reference
        # that specific secret. This will also be the filename containing the secret.
        # Apigee Hybrid expects these exact values so they must not be changed.
        # "secretPath" is the path in Vault where the secret should be retrieved.
        # "secretKey" is the key within the Vault secret response to extract a value from.
        objects: |
          - objectName: "runtime"
            secretPath: ""
            secretKey: ""
          - objectName: "synchronizer"
            secretPath: ""
            secretKey: ""
          - objectName: "udca"
            secretPath: ""
            secretKey: ""
    

    VAULT_ADDRESS 是 Vault 伺服器的執行端點。如果 Vault 與 Apigee 位於同一個叢集和命名空間,格式通常為 http://vault.APIGEE_NAMESPACE.svc.cluster.local:VAULT_SERVICE_PORT

    將範本儲存至名為 spc-env-ENV_NAME.yaml 的檔案。

  4. 針對每個環境,將環境專屬的 SecretProviderClass 套用至 apigee 命名空間:
    kubectl -n APIGEE_NAMESPACE apply -f spc-env-ENV_NAME.yaml

    針對每個環境重複這個步驟。

為 Google 服務帳戶啟用外部密鑰

  1. 在覆寫檔案中,新增 serviceAccountSecretProviderClassenvs[].serviceAccountSecretProviderClass 設定屬性,為 Google 服務帳戶啟用外部密鑰。您可以移除或註解掉 serviceAccountPathserviceAccountPaths 設定屬性:
    serviceAccountSecretProviderClass: apigee-orgsakeys-spc
    
    envs:
      - name: ENV_NAME
        serviceAccountSecretProviderClass: apigee-envsakeys-ENV_NAME-spc
  2. 套用每個 Helm 資訊套件:
    helm upgrade datastore apigee-datastore/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade telemetry apigee-telemetry/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade redis apigee-redis/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade ORG_NAME apigee-org/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
  3. 針對每個環境套用 apigee-env 圖表:
    helm upgrade ENV_NAME apigee-env/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --set env=ENV_NAME \
        --atomic \
        -f overrides.yaml
    

改回使用服務帳戶 JSON 檔案

如要還原使用儲存的 Google 服務帳戶 JSON 檔案,請按照下列程序操作:

  1. 更新覆寫檔案:
    1. 移除或註解 serviceAccountSecretProviderClassenvs:serviceAccountSecretProviderClass 行。
    2. 新增 serviceAccountPathserviceAccountPaths 設定屬性,並提供適當服務帳戶的路徑。

    例如:

    # serviceAccountSecretProviderClass: apigee-orgsakeys-spc - (commented out)
    
    cassandra:
      backup:
        serviceAccountPath: service-accounts/myhybridorg-apigee-cassandra.json
      restore:
        serviceAccountPath: service-accounts/myhybridorg-apigee-cassandra.json
    
    connectAgent:
      serviceAccountPath: service-accounts/myhybridorg-apigee-mart.json
    
    envs:
      - name: test
      # serviceAccountSecretProviderClass: apigee-envsakeys-spc - (commented out)
        serviceAccountPaths:
          runtime: service-accounts/myhybridorg-apigee-runtime.json
          synchronizer: service-accounts/myhybridorg-apigee-synchronizer.json
    
    logger:
      serviceAccountPath: service-accounts/myhybridorg-apigee-logger.json
    
    mart:
      serviceAccountPath: service-accounts/myhybridorg-apigee-mart.json
    
    metrics:
      serviceAccountPath: service-accounts/myhybridorg-apigee-metrics.json
    
    mint: # Required if using Monetization for Apigee hybrid (v1.15.1 and later)
      serviceAccountPath: service-accounts/myhybridorg-apigee-mint-task-scheduler.json
    
    udca:
      serviceAccountPath: service-accounts/myhybridorg-apigee-udca.json
    
    watcher:
      serviceAccountPath: service-accounts/myhybridorg-apigee-watcher.json
    
  2. 套用每個 Helm 資訊套件:
    helm upgrade datastore apigee-datastore/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade telemetry apigee-telemetry/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade redis apigee-redis/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
    helm upgrade ORG_NAME apigee-org/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --atomic \
        -f overrides.yaml
    
  3. 針對每個環境套用 apigee-env 圖表:
    helm upgrade ENV_NAME apigee-env/ \
        --install \
        --namespace APIGEE_NAMESPACE \
        --set env=ENV_NAME \
        --atomic \
        -f overrides.yaml
    

    針對每個環境重複這個步驟。