使用 External Secrets Operator

本頁說明如何使用 External Secrets Operator (ESO),將 Secret Manager 中的 Secret 同步處理至 Google Distributed Cloud 連結網路方案。

External Secrets Operator 是開放原始碼的 Kubernetes 運算子,可整合外部密鑰管理系統。運算子會從外部 API 讀取資訊,並自動將值注入 Kubernetes 密鑰。

必要條件

使用 External Secrets Operator 前,請先完成下列步驟:

  • 建立可運作的 Distributed Cloud 連線叢集。
  • 確認專案已啟用下列 API。 Google Cloud 如要瞭解如何啟用 API,請參閱「啟用服務」:
    • secretmanager.googleapis.com
    • iamcredentials.googleapis.com
  • 確認您已安裝下列指令列工具:

    如果您使用 Cloud Shell 做為與Google Cloud互動的殼層環境,系統會為您安裝這些工具。

  • 確認您已初始化 gcloud CLI,以便搭配專案使用。

  • 在叢集上啟用Workload Identity Federation。Workload Identity Pool 會自動提供,格式為 PROJECT_ID.svc.id.goog

  • 在叢集上安裝 External Secrets Operator。如需安裝操作說明,請參閱 External Secrets Operator 說明文件。建議您在專屬命名空間 (例如 external-secrets) 中安裝運算子。請勿在系統管理的命名空間 (例如 kube-systemgke-system) 中安裝。

Distributed Cloud 連線叢集會自動註冊至建立所在專案的機群。

驗證

External Secrets Operator 需要驗證,才能存取 Secret Manager。Distributed Cloud Connected 會使用機群 Workload Identity Federation,允許工作負載向Google Cloud API 驗證身分。

如要為 External Secrets Operator 設定驗證,請按照下列步驟操作:

  1. 按照「Workload Identity 叢集驗證」一文中的操作說明,在叢集和 Google Cloud 之間建立信任關係。
  2. 確認 External Secrets Operator 使用的 Google 服務帳戶,在您要存取的 Secret 上具有 Secret Manager Secret Accessor (roles/secretmanager.secretAccessor) 角色。
  3. 按照「設定工作負載」的說明,設定 External Secrets Operator Pod 使用 Workload Identity Federation。

    大多數客戶都使用 Workload Identity 聯盟進行驗證。如要設定 Workload Identity Federation,您必須使用 Google 服務帳戶為運算子使用的 Kubernetes ServiceAccount 加上註解。如要新增這個註解,請執行 kubectl annotate 指令:

    kubectl annotate serviceaccount KSA_NAME \
        --namespace OPERATOR_NAMESPACE \
        iam.gke.io/gcp-service-account=GSA_EMAIL
    

    或者,您也可以在 ServiceAccount YAML 中加入註解:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      annotations:
        iam.gke.io/gcp-service-account: GSA_EMAIL
      name: KSA_NAME
      namespace: OPERATOR_NAMESPACE
    

    替換下列值:

    • KSA_NAME:運算子使用的 Kubernetes ServiceAccount 名稱
    • OPERATOR_NAMESPACE:安裝運算子的命名空間
    • GSA_EMAIL:Google 服務帳戶的電子郵件地址
  4. 將憑證設定檔提供給運算子 Pod。詳情請參閱「設定工作負載」。

建立 ESO 資源來同步處理密鑰

設定驗證後,即可建立 External Secrets Operator 資源,同步處理密鑰。

建立 SecretStore

SecretStore 會指定如何存取外部密鑰管理系統。您可以在與 External Secrets Operator 相同的命名空間或應用程式命名空間中建立 SecretStore 資源。詳情請參閱 Kubernetes 說明文件中的「SecretStore」。

  1. 建立名為 secret-store.yaml 的檔案,並加入以下內容:

    apiVersion: external-secrets.io/v1
    kind: SecretStore
    metadata:
      name: gcp-store
      namespace: NAMESPACE
    spec:
      provider:
        gcpsm:
          projectID: PROJECT_ID
    

    替換下列值:

    • NAMESPACE:您要建立 SecretStore 的命名空間
    • PROJECT_ID:儲存密鑰的 Google Cloud 專案 ID
  2. 使用 kubectl apply 指令套用資訊清單:

    kubectl apply -f secret-store.yaml
    

建立 ClusterSecretStore

ClusterSecretStore 是叢集範圍內的資源,ExternalSecret資源可在任何命名空間中使用。詳情請參閱 Kubernetes 說明文件中的ClusterSecretStore

  1. 建立名為 cluster-secret-store.yaml 的檔案,並加入以下內容:

    apiVersion: external-secrets.io/v1
    kind: ClusterSecretStore
    metadata:
      name: gcp-cluster-store
    spec:
      provider:
        gcpsm:
          projectID: PROJECT_ID
    

    PROJECT_ID 替換為儲存密鑰的 Google Cloud 專案 ID。

  2. 套用資訊清單:

    kubectl apply -f cluster-secret-store.yaml
    

建立 ExternalSecret

ExternalSecret 會宣告要擷取的資料,以及在叢集中的儲存位置。在應用程式 Pod 會使用產生的 Kubernetes Secret 的命名空間中,建立 ExternalSecret 資源。詳情請參閱 Kubernetes 說明文件中的「ExternalSecret」。

  1. 建立名為 external-secret.yaml 的檔案,並加入以下內容:

    apiVersion: external-secrets.io/v1
    kind: ExternalSecret
    metadata:
      name: EXTERNAL_SECRET
      namespace: NAMESPACE
    spec:
      refreshInterval: 1h
      secretStoreRef:
        kind: SecretStore
        name: gcp-store
      target:
        name: K8S_SECRET_NAME
        creationPolicy: Owner
      data:
      - secretKey: K8S_SECRET_KEY
        remoteRef:
          key: SECRET_NAME
    

    替換下列值:

    • EXTERNAL_SECRETExternalSecret 資源的名稱。
    • NAMESPACE:您建立 SecretStore 的命名空間。
    • K8S_SECRET_NAME:ESO 要建立的 Kubernetes Secret 名稱。
    • K8S_SECRET_KEY:Kubernetes Secret 資料中的金鑰。
    • SECRET_NAME:Secret Manager 中的密鑰名稱。Google Cloud

    如果您使用 ClusterSecretStore,請設定 kind: ClusterSecretStore,並在 secretStoreRef 中更新 name

  2. 套用資訊清單:

    kubectl apply -f external-secret.yaml
    

從 JSON 密鑰同步多個金鑰

如果 Secret Manager 中的密鑰包含 JSON 字串,您可以將所有金鑰擷取為 Kubernetes 密鑰中的個別項目。

  1. 建立名為 external-secret-json.yaml 的檔案,並加入以下內容:

    apiVersion: external-secrets.io/v1
    kind: ExternalSecret
    metadata:
      name: EXTERNAL_SECRET
      namespace: NAMESPACE
    spec:
      refreshInterval: 1h
      secretStoreRef:
        kind: SecretStore
        name: gcp-store
      target:
        name: K8S_SECRET_NAME
        creationPolicy: Owner
      dataFrom:
      - extract:
          key: SECRET_NAME
    
  2. 套用資訊清單:

    kubectl apply -f external-secret-json.yaml
    

JSON 密鑰中的每個鍵/值組合,都會對應至產生的 Kubernetes 密鑰中的鍵/值組合。

疑難排解

如果密碼未同步,請按照下列步驟排解問題:

  1. 使用 kubectl get 指令檢查 ExternalSecret 資源的狀態:

    kubectl get externalsecret EXTERNAL_SECRET -n NAMESPACE -o yaml
    

    檢查「status」部分是否有任何錯誤訊息或失敗條件。

  2. 使用 kubectl logs 指令檢查 External Secrets Operator 控制器 Pod 的記錄:

    kubectl logs -l app.kubernetes.io/name=external-secrets -n OPERATOR_NAMESPACE
    
  3. 確認運算子使用的 Kubernetes ServiceAccount 已正確註解 Google 服務帳戶電子郵件地址。詳情請參閱「叢集上的 Workload Identity Federation」。

  4. 確認 Google 服務帳戶具備必要權限,且工作負載身分聯盟設定正確無誤。詳情請參閱「叢集上的 Workload Identity Federation」。

後續步驟