External Secrets Operator を使用する

このページでは、外部シークレット オペレーター(ESO)を使用して、Secret Manager から Google Distributed Cloud コネクテッド クラスタに Secret を同期する方法について説明します。

External Secrets Operator は、外部シークレット管理システムを統合するオープンソースの Kubernetes オペレーターです。オペレーターは外部 API から情報を読み取り、値を Kubernetes Secret に自動的に挿入します。

前提条件

External Secrets Operator を使用する前に、次の操作を行う必要があります。

  • 機能する Distributed Cloud コネクテッド クラスタを作成します。
  • Google Cloud プロジェクトで次の API が有効になっていることを確認します。API の有効化については、サービスの有効化をご覧ください。
    • secretmanager.googleapis.com
    • iamcredentials.googleapis.com
  • 次のコマンドライン ツールがインストールされていることを確認します。

    • Google Cloud CLI の最新バージョン。 Google Cloudとやり取りするためのコマンドライン ツールである gcloud が含まれています。
    • kubectl

    Google Cloudを操作するシェル環境として Cloud Shell を使用している場合は、これらのツールがインストールされています。

  • プロジェクトで使用する gcloud CLI が初期化されていることを確認します。

  • クラスタで Workload Identity 連携を有効にします。Workload Identity プールは自動的に使用可能になり、PROJECT_ID.svc.id.goog 形式になります。

  • クラスタに External Secrets Operator をインストールします。インストール手順については、External Secrets Operator のドキュメントをご覧ください。オペレータは、external-secrets などの専用の Namespace にインストールすることをおすすめします。kube-system や gke-system などのシステム管理 Namespace にインストールしないでください。

Distributed Cloud 接続クラスタは、作成されたプロジェクトのフリートに自動的に登録されます。

認証

External Secrets Operator が Secret Manager にアクセスするには、認証が必要です。Distributed Cloud Connected は、フリート Workload Identity 連携を使用して、ワークロードがGoogle Cloud APIs に対して認証できるようにします。

External Secrets Operator の認証を構成するには:

  1. Workload Identity クラスタ認証の手順に沿って、クラスタと Google Cloud の間に信頼関係を設定します。
  2. External Secrets Operator が使用する Kubernetes ServiceAccount に、シークレットに対する Secret Manager のシークレット アクセサー ロール(roles/secretmanager.secretAccessor)を付与します。

    gcloud secrets add-iam-policy-binding SECRET_NAME \
        --project=PROJECT_ID \
        --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/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: オペレーターをインストールした Namespace
    • KUBERNETES_SERVICEACCOUNT: オペレーターが使用する Kubernetes ServiceAccount の名前
  3. ワークロードを構成するの手順に沿って、Workload Identity 連携を使用するように External Secrets Operator Pod を構成し、認証情報の構成ファイルをオペレータ Pod に提供します。

シークレットを同期する ESO リソースを作成する

認証を構成したら、External Secrets Operator リソースを作成してシークレットを同期できます。

SecretStore を作成する

SecretStore は、外部シークレット管理システムにアクセスする方法を指定します。SecretStore リソースは、External Secrets Operator と同じ Namespace またはアプリケーション Namespace に作成できます。詳細については、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 リソースが任意の Namespace で使用できるクラスタ スコープのリソースです。詳細については、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 を使用する Namespace に 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 を作成した Namespace。
    • 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 シークレット内の各 Key-Value ペアは、結果の Kubernetes シークレット内の Key-Value ペアにマッピングされます。

トラブルシューティング

シークレットが同期されない場合は、次の手順でトラブルシューティングを行います。

  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 のシークレット アクセサー ロール(roles/secretmanager.secretAccessor)が付与されており、Workload Identity 連携がオペレーター Pod で正しく構成されていることを確認します。詳細については、クラスタでの Workload Identity 連携をご覧ください。

次のステップ