External Secrets

External Secrets はCNCFサンドボックスプロジェクトであり、TAG Securityのスポンサーのもとで2022年に受け入れられました。

について

外部シークレットオペレーターESO は、シークレットのストレージをKubernetes自分自身から分離することにより、シークレット管理を強化するKubernetesオペレーターです。これにより、外部シークレット管理システムとネイティブKubernetes Secret リソース間のシームレスな同期が可能になります。

ESOは、以下を含む幅広いバックエンドをサポートしています。

…その他にもたくさん。サポートされているプロバイダーの完全な最新のリストについては、

official External Secrets documentation を参照してください。

PostgreSQLおよびCloudNativePGとの統合

PostgreSQLデータベースに関しては、外部シークレットは2つの主要なユースケースで CloudNativePG とシームレスに統合します。

  • 自動パスワード管理 ESOは、Kubernetes Secret リソースに保存されているデータベースユーザーパスワードの自動生成とローテーションを処理でき、クラスター内で実行されているアプリケーションが常に最新の資格情報にアクセスできるようにします。

  • クロスプラットフォームのシークレットアクセス SecretStore リソースを介して外部キー管理サービスKMSとこれらのパスワードの透過的な同期が有効になります。これにより、Kubernetesクラスターの外部のアプリケーションと開発者Kubernetesシークレットにアクセスできない場合があり、外部KMSからデータベース資格情報を直接取得できます。

例 外部シークレットを使用した自動パスワード管理

quickstart guide からcluster-example Postgresクラスターでapp ユーザーのパスワードを24時間ごとに自動的にローテーションする方法を説明します。

注釈

続行する前に、cluster-example Postgresクラスターが環境で稼働していることを確認してください。

デフォルトでは、CloudNativePGはcluster-example-app という名前のKubernetes Secret を生成および管理します。これには、cluster-example クラスターのapp ユーザーの資格情報が含まれています。これについては、 “Connecting from an application” section で読むことができます。

外部シークレットを使用する場合、目標は次のことです。

  1. パスワードの生成方法を指定するPassword ジェネレーターを定義します。

  2. password およびpgpass フィールドのみを更新することにより、cluster-example-app シークレットの同期を維持するExternalSecret リソースを作成します。

パスワードジェネレーターの作成

次の例では、 Password

default 名前空間のpg-password-generator という名前のリソース。ニーズに合わせて名前とプロパティをカスタマイズできます。

apiVersion: generators.external-secrets.io/v1alpha1
kind: Password
metadata:
  name: pg-password-generator
spec:
  length: 42
  digits: 5
  symbols: 5
  symbolCharacters: "-_$@"
  noUpper: false
  allowRepeat: true

この仕様は、生成されるパスワードの長さ、数字、記号、大文字の包含などの特性を定義します。

外部シークレットの作成

次の例では、 時間ごとにパスワードを更新する cluster-example-app-secret という名前のExternalSecret リソースを作成します。 Merge ポリシーを使用して、cluster-example-app シークレットの指定されたフィールドpasswordpgpassjdbc-uri 、およびuri のみを更新します。

apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: cluster-example-app-secret
spec:
  refreshInterval: "24h"
  target:
    name: cluster-example-app
    creationPolicy: Merge
    template:
      metadata:
        labels:
          cnpg.io/reload: "true"
      data:
        password: "{{ .password }}"
        pgpass: "cluster-example-rw:5432:app:app:{{ .password }}"
        jdbc-uri: "jdbc:postgresql://cluster-example-rw.default:5432/app?password={{ .password }}&user=app"
        uri: "postgresql://app:{{ .password }}@cluster-example-rw.default:5432/app"
  dataFrom:
    - sourceRef:
        generatorRef:
          apiVersion: generators.external-secrets.io/v1alpha1
          kind: Password
          name: pg-password-generator

ラベル cnpg.io/reload: "true" により、シークレットが変更されたときにCloudNativePGがデータベースのユーザーパスワードのリロードをトリガーします。

構成の検証

ExternalSecret が正しく同期していることを確認するには

kubectl get es cluster-example-app-secret

リアルタイムで更新されるパスワードを観察するには、一時的にrefreshInterval30s に減らし、次のコマンドを繰り返し実行します。

kubectl get secret cluster-example-app \
  -o jsonpath="{.data.password}" | base64 -d

30秒ごとにパスワードが変更され、ローテーションが正しく機能していることを確認します。

他にもあります

上記の例では、CloudNativePGによって作成されたデフォルトのcluster-example-app シークレットに焦点を当てていますが、同じアプローチを拡張して、カスタムシークレットまたはパスワードを定期的にローテーションするように作成するPostgreSQLユーザーを管理できます。

例外部KMSとの統合

CNCFエコシステムで最も広く使用されているキー管理サービスKMSプロバイダーの1つが HashiCorp Vault です。 VaultはビジネスソースライセンスBUSLに基づいてライセンスされていますが、完全な互換性がありアクティブにメンテナンスされているオープンソースの代替品 OpenBao が利用できます。 OpenBaoは、HashCorp Vaultと同じインターフェイスをすべてサポートしているため、真のドロップイン代替品となります。

この例では、CloudNativePG、外部シークレットオペレーター、およびHashCorp Vaultを統合して、PostgreSQLパスワードを自動的にローテーションし、Vaultに安全に保存する方法を示します。

注釈

この例では、 HashiCorp Vaultが既にインストールされ、環境に適切に構成されており、チームがそれを操作するために必要な専門知識があることを前提としています。 Vaultを展開するにはさまざまな方法があり、それらの詳細についてはCloudNativePGの範囲外です。 Kubernetes内でVaultを実行することは可能ですが、外部に展開されるのがより一般的です。詳細な手順については、 HashiCorp Vault documentation を参照してください。

前の例から続けて、必要なSecretStore およびPushSecret リソースを作成して、Vaultとの統合を完了します。

SecretStore の作成

この例では、 HashiCorp Vaultがhttp://vault.vault.svc:8200 の名前空間内からアクセスでき、 vault-token という名前のKubernetes Secret が同じ名前空間に存在し、Vaultでの認証に使用されるトークンを含むことを前提としています。

apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
  name: vault-backend
spec:
  provider:
    vault:
      server: "http://vault.vault.svc:8200"
      path: "secrets"
      # Specifies the Vault KV secret engine version ("v1" or "v2").
      # Defaults to "v2" if not set.
      version: "v2"
      auth:
        # References a Kubernetes Secret that contains the Vault token.
        # See: https://www.vaultproject.io/docs/auth/token
        tokenSecretRef:
          name: "vault-token"
          key: "token"
- --
apiVersion: v1
kind: Secret
metadata:
  name: vault-token
data:
  token: aHZzLioqKioqKio= # hvs. ****  ***

この構成は、 vault-backend という名前のSecretStore リソースを作成します。

注釈

この例では、基本的なトークンベースの認証を使用します。これは、APIおよびCLIのユースケースをテストするのに適しています。これはVaultで有効になっているデフォルトの方法ですが、運用環境にはお勧めできません。実稼働環境では、より安全な認証方法の使用を検討します。

External Secrets Operator documentation を参照してください

サポートされている認証メカニズムの完全なリストについては、

注釈

HashiCorp Vaultは、バージョン`v2` の`secrets` パスでKVシークレットエンジンを有効にする必要があります。 Vaultインスタンスが別のパスまたはバージョンを使用している場合、それに応じて`path` および`version` フィールドを更新してください。

PushSecret の作成

PushSecret リソースは、Kubernetes Secret をHashCorp Vaultにプッシュするために使用されます。この単純化された例では、サンプルクラスターcluster-exampleapp ユーザーの資格情報をプッシュします。

PushSecret の構成の詳細については、

External Secrets Operator documentation を参照してください。

apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
  name: pushsecret-example
spec:
  deletionPolicy: Delete
  refreshInterval: 24h
  secretStoreRefs:
    - name: vault-backend
      kind: SecretStore
  selector:
    secret:
      name: cluster-example-app
  data:
    - match:
        remoteRef:
          remoteKey: cluster-example-app

この例では、 PushSecret リソースは、 cluster-example-app という名前のKubernetes Secret をHashCorp Vaultにプッシュするように外部シークレットオペレーターに指示します。前の例から。 remoteKey は、 vault-backend という名前のSecretStore を使用して、シークレットをVaultに保存する名前を定義します。

構成の検証

PushSecret が正常に機能していることを確認するには、 HashiCorp Vault UIに移動します。パスsecretskv シークレットエンジンで、上記で定義したremoteKey に対応するcluster-example-app という名前のシークレットを見つけます。