使用 External Secrets Operator

本頁說明如何使用外部密鑰運算子 (ESO),將 Secret Manager 中的 Secret 同步至 Google Distributed Cloud 連結網路方案叢集。

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

必要條件

如要使用 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.。

  • 在叢集上安裝 External Secrets Operator。如需安裝操作說明,請參閱「External Secrets Operator 說明文件」。建議您在專用命名空間 (例如 external-secrets) 中安裝運算子。請勿安裝在系統管理的命名空間中,例如 kube-system 或 gke-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. 將 Secret Manager 密鑰存取者角色 (roles/secretmanager.secretAccessor) 授予 External Secrets Operator 使用的 Kubernetes ServiceAccount:

    gcloud secrets add-iam-policy-binding SECRET_NAME \
        --project=PROJECT_ID \
        --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID./subject/ns/OPERATOR_NAMESPACE/sa/KUBERNETES_SERVICEACCOUNT" \
        --role="roles/secretmanager.secretAccessor" \
        --condition=None
    

    替換下列值:

    • SECRET_NAME:Secret Manager 中的密鑰名稱
    • PROJECT_ID:您的 Google Cloud 專案 ID
    • PROJECT_NUMBER:您的數值 Google Cloud 專案編號
    • OPERATOR_NAMESPACE:安裝運算子的命名空間
    • KUBERNETES_SERVICEACCOUNT:運算子使用的 Kubernetes ServiceAccount 名稱
  3. 按照「設定工作負載」的說明,設定 External Secrets Operator Pod 使用 Workload Identity Federation,並將憑證設定檔提供給 Operator 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_SECRET:ExternalSecret 資源的名稱。
    • NAMESPACE:您建立 SecretStore 的命名空間。
    • K8S_SECRET_NAME:ESO 要建立的 Kubernetes Secret 名稱。
    • K8S_SECRET_KEY:Kubernetes Secret 資料中的金鑰。
    • SECRET_NAME: Google Cloud Secret Manager 中的密鑰名稱。

    如果您使用 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 具有 Secret Manager Secret Accessor 角色 (roles/secretmanager.secretAccessor),且運算子 Pod 已正確設定 Workload Identity Federation。詳情請參閱「叢集上的 Workload Identity 聯盟」。

後續步驟