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

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

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

如果您未使用 GKE 叢集中的工作負載身分EKS 和 AKS 上的工作負載身分聯盟,Apigee 混合元件就必須驗證 Google 服務帳戶,才能執行其任務。在 Apigee hybrid 中,有三種方法可用來儲存及參照 Google 服務帳戶金鑰:

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

設定服務帳戶金鑰在保管箱中

安裝 CSI 驅動程式和保險庫提供者

如果您尚未使用 Helm 在叢集中安裝 CSI 驅動程式,請按照「Secrets Store CSI 驅動程式:安裝」中的指示操作。詳情請參閱保管箱說明文件中的「安裝保管箱 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": "myhybridorg",
        "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
營利 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
    

改回使用服務帳戶憑證檔案

如果您需要回溯使用儲存的 Google 服務帳戶憑證檔案,請按照下列程序操作:

  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
    
    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
    

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