このページでは、外部シークレット オペレーター(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.comiamcredentials.googleapis.com
次のコマンドライン ツールがインストールされていることを確認します。
- Google Cloud CLI の最新バージョン。 Google Cloudとやり取りするためのコマンドライン ツールである
gcloudが含まれています。 kubectl
Google Cloudを操作するシェル環境として Cloud Shell を使用している場合は、これらのツールがインストールされています。
- Google Cloud CLI の最新バージョン。 Google Cloudとやり取りするためのコマンドライン ツールである
プロジェクトで使用する 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 の認証を構成するには:
- Workload Identity クラスタ認証の手順に沿って、クラスタと Google Cloud の間に信頼関係を設定します。
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 プロジェクト IDPROJECT_NUMBER: 数値の Google Cloudプロジェクト番号OPERATOR_NAMESPACE: オペレーターをインストールした NamespaceKUBERNETES_SERVICEACCOUNT: オペレーターが使用する Kubernetes ServiceAccount の名前
ワークロードを構成するの手順に沿って、Workload Identity 連携を使用するように External Secrets Operator Pod を構成し、認証情報の構成ファイルをオペレータ Pod に提供します。
シークレットを同期する ESO リソースを作成する
認証を構成したら、External Secrets Operator リソースを作成してシークレットを同期できます。
SecretStore を作成する
SecretStore は、外部シークレット管理システムにアクセスする方法を指定します。SecretStore リソースは、External Secrets Operator と同じ Namespace またはアプリケーション Namespace に作成できます。詳細については、Kubernetes ドキュメントの SecretStore をご覧ください。
次の内容で
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
kubectl apply コマンドを使用して、マニフェストを適用します。
kubectl apply -f secret-store.yaml
ClusterSecretStore を作成する
ClusterSecretStore は、ExternalSecret リソースが任意の Namespace で使用できるクラスタ スコープのリソースです。詳細については、Kubernetes ドキュメントの ClusterSecretStore をご覧ください。
次の内容で
cluster-secret-store.yamlという名前のファイルを作成します。apiVersion: external-secrets.io/v1 kind: ClusterSecretStore metadata: name: gcp-cluster-store spec: provider: gcpsm: projectID: PROJECT_IDPROJECT_IDは、シークレットが保存されている Google Cloud プロジェクト ID に置き換えます。次のようにマニフェストを適用します。
kubectl apply -f cluster-secret-store.yaml
ExternalSecret を作成します。
ExternalSecret は、取得するデータと、クラスタ内の保存場所を宣言します。アプリケーション Pod が結果の Kubernetes Secret を使用する Namespace に ExternalSecret リソースを作成します。詳細については、Kubernetes ドキュメントの ExternalSecret をご覧ください。
次の内容で
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を更新します。次のようにマニフェストを適用します。
kubectl apply -f external-secret.yaml
JSON シークレットから複数のキーを同期する
Secret Manager のシークレットに JSON 文字列が含まれている場合は、すべてのキーを Kubernetes シークレットの個別のエントリとして抽出できます。
次の内容で
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次のようにマニフェストを適用します。
kubectl apply -f external-secret-json.yaml
JSON シークレット内の各 Key-Value ペアは、結果の Kubernetes シークレット内の Key-Value ペアにマッピングされます。
トラブルシューティング
シークレットが同期されない場合は、次の手順でトラブルシューティングを行います。
kubectl get コマンドを使用して、
ExternalSecretリソースのステータスを確認します。kubectl get externalsecret EXTERNAL_SECRET -n NAMESPACE -o yamlstatusセクションで、エラー メッセージまたは失敗した条件を確認します。kubectl logs コマンドを使用して、External Secrets Operator コントローラ Pod のログを確認します。
kubectl logs -l app.kubernetes.io/name=external-secrets -n OPERATOR_NAMESPACEオペレーターで使用される Kubernetes ServiceAccount に Secret Manager のシークレット アクセサー ロール(
roles/secretmanager.secretAccessor)が付与されており、Workload Identity 連携がオペレーター Pod で正しく構成されていることを確認します。詳細については、クラスタでの Workload Identity 連携をご覧ください。