Certificates
============

KubernetesのEDB Postgresは、
TLS証明書をネイティブにサポートするように設計されました。クラスターをセットアップするには、オペレーターに以下が必要です。

- サーバー認証局CA証明書

- サーバーCAによって署名されたサーバーTLS証明書

- クライアントCA証明書

- クライアントCAによって生成されたストリーミングレプリケーションクライアント証明書

..  Note::
   クラスターが使用するすべてのシークレットとその有効期限は、クラスターのステータスで見つけることができます。

KubernetesのEDB
Postgresは、TLS証明書に関して非常に柔軟です。主に2つのモードで動作します。

1. :ref:`オペレーター管理モード <オペレーター管理モード>` 
   –証明書は完全に自動化された方法でオペレーターによって内部管理され、Kubernetes用のEDB
   Postgresによって作成されたCAを使用して署名されます。

2. :ref:`ユーザー提供の証明書モード <ユーザー提供の証明書モード>`  –
   証明書はオペレーターの外部で生成され、シークレットとしてクラスター定義にインポートされます。
   KubernetesのEDB Postgresは `cert-manager <https://cert-manager.io/>`_ と自分自身を統合します

:ref:`Cert-managerの例 <Cert-managerの例>` を参照してください。

証明書の一部のみがCNP外部で生成されるハイブリッドアプローチを選択することもできます。

..  Note::
   オペレーターとインスタンスは、DNS名を無視して、CAのみに対してサーバー証明書を検証します。このアプローチは、クラスター内の通信に使用される`<cluster>-rw` サービスのユーザー指定証明書にDNS名が一般的に欠如しているためです。

オペレーター管理モード
----------------------

デフォルトでは、オペレーターは単一の認証局CAを自動的に生成して、クライアントとサーバーの証明書の両方を発行します。これらの証明書は事業者によって継続的に管理され、有効期限の7日前に自動更新されます90日の有効期間内。

..  Note::
   `CERTIFICATE_DURATION` および`EXPIRING_CHECK_THRESHOLD` 環境変数を構成することにより、このデフォルトの動作を調整できます。詳細なガイダンスについては、 :ref:`Operator configuration <Operator configuration>`  を参照してください。

..  Important::
   単純なリロード操作で十分であるため、証明書の更新はPostgreSQLサーバーのダウンタイムを発生させません。ただし、KubernetesのEDB Postgresによって制御されていないユーザー管理証明書は、更新プロセスの後に再発行する必要があります。

サーバー証明書
^^^^^^^^^^^^^^

サーバーCAシークレット
^^^^^^^^^^^^^^^^^^^^^^

オペレーターは、自己署名CAを生成し、次のキーを含む汎用シークレットに保存します。

- ``ca.crt`` –
  サーバー証明書の検証に使用されるCA証明書。クライアントの接続文字列で\ ``sslrootcert``
  として使用されます。

- ``ca.key`` – サーバーSSL証明書に自動的に署名するために使用されるキー。

サーバーTLSシークレット
^^^^^^^^^^^^^^^^^^^^^^^

オペレーターは、生成された自己署名CAを使用して、サーバーTLS証明書に署名します。これは\ ``kubernetes.io/tls``
タイプのシークレットに保存され、インスタンスによって\ ``ssl_cert_file``
および\ ``ssl_key_file``
として使用されるように構成されます。このアプローチにより、クライアントは自分のIDを確認し、安全に接続できます。

サーバー代替DNS名
^^^^^^^^^^^^^^^^^

デフォルトのものに加えて、生成されたサーバーTLSシークレットの一部としてDNSサーバーの代替名を指定できます。

クライアント証明書
^^^^^^^^^^^^^^^^^^

クライアントCAシークレット
^^^^^^^^^^^^^^^^^^^^^^^^^^

デフォルトでは、サーバーCAと同じ自己署名CAが使用されます。パブリック部分は\ ``ssl_ca_file``
としてすべてのインスタンスに渡されるため、署名したクライアント証明書を検証できます。プライベートキーは同じシークレットに保存され、
``kubectl cnp``
プラグインによって生成されたクライアント証明書の署名に使用されます。

クライアント\ ``streaming_replica`` 証明書
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

オペレーターは、生成された自己署名CAを使用して、ユーザー\ ``streaming_replica``
のクライアント証明書に署名し、\ ``kubernetes.io/tls``
タイプのシークレットに保存します。プライマリインスタンスへの安全な接続を許可するために、この証明書はレプリカの接続文字列で\ ``sslcert``
および\ ``sslkey`` として渡されます。

ユーザー提供の証明書モード
--------------------------

.. _サーバー証明書-1:

サーバー証明書
^^^^^^^^^^^^^^

必要に応じて、 `cert-manager <https://cert-manager.io/>`_ 
などの別のコンポーネントを使用して生成し、2つのサーバー証明書を提供することもできます。クラスターにカスタムサーバーTLS証明書を使用するには、次のパラメーターを指定する必要があります。

- ``serverTLSSecret`` – サーバーTLS証明書を含む\ ``kubernetes.io/tls``
  タイプのシークレットの名前。これには、標準の\ ``tls.crt``
  および\ ``tls.key`` キーの両方が含まれている必要があります。

- ``serverCASecret`` – ``ca.crt`` キーを含むシークレットの名前。

..  Note::
   オペレーターは、引き続きクライアント証明書に関連する2つのシークレットを作成および管理します。

..  Note::
   オペレーターとインスタンスは、DNS名を無視して、CAのみに対してサーバー証明書を検証します。このアプローチは、クラスター内の通信に使用される`<cluster>-rw` サービスのユーザー指定証明書にDNS名が一般的に欠如しているためです。

..  Note::
   ConfigMapとシークレットをインスタンスによってリロードする場合は、キー `k8s.enterprisedb.io/reload`  のラベルを追加できます。それ以外の場合は、 `kubectl cnp reload` サブコマンドを使用してインスタンスをリロードする必要があります。

例
^^

次のファイルがあるとします。

- ``server-ca.crt`` – サーバーTLS証明書に署名したCAの証明書。

- ``server.crt`` – サーバーTLS証明書の証明書。

- ``server.key`` –サーバーTLS証明書のプライベートキー。

CA証明書を含むシークレットを作成します。

.. code:: sh

   kubectl create secret generic my-postgresql-server-ca \
     --from-file=ca.crt=./server-ca.crt

TLS証明書を使用してシークレットを作成します。

.. code:: sh

   kubectl create secret tls my-postgresql-server \
     --cert=./server.crt --key=./server.key

これらのシークレットを参照するPostgreSQLクラスターを作成します。

.. code:: bash

   kubectl apply -f - <<EOF
   apiVersion: postgresql.k8s.enterprisedb.io/v1
   kind: Cluster
   metadata:
     name: cluster-example
   spec:
     instances: 3
     certificates:
       serverCASecret: my-postgresql-server-ca
       serverTLSSecret: my-postgresql-server
     storage:
       storageClass: standard
       size: 1Gi
   EOF

新しいクラスターは、TLS接続に提供されたサーバー証明書を使用します。

Cert-managerの例
^^^^^^^^^^^^^^^^

この簡単な例は、 `cert-manager <https://cert-manager.io/>`_ の使用方法を示しています

自己署名CAをセットアップし、必要なTLSサーバー証明書を生成するには。

.. code:: yaml

   - --
   apiVersion: cert-manager.io/v1
   kind: Issuer
   metadata:
     name: selfsigned-issuer
   spec:
     selfSigned: {}
   - --
   apiVersion: v1
   kind: Secret
   metadata:
     name: my-postgres-server-cert
     labels:
       k8s.enterprisedb.io/reload: ""
   - --
   apiVersion: cert-manager.io/v1
   kind: Certificate
   metadata:
     name: my-postgres-server-cert
   spec:
     secretName: my-postgres-server-cert
     usages:
       - server auth
     dnsNames:
       - cluster-example-lb.internal.mydomain.net
       - cluster-example-rw
       - cluster-example-rw.default
       - cluster-example-rw.default.svc
       - cluster-example-r
       - cluster-example-r.default
       - cluster-example-r.default.svc
       - cluster-example-ro
       - cluster-example-ro.default
       - cluster-example-ro.default.svc
     issuerRef:
       name: selfsigned-issuer
       kind: Issuer
       group: cert-manager.io

Cert-managerは、\ ``my-postgres-server-cert``
という名前のシークレットを作成します。これには、必要なすべてのファイルが含まれており、次のようにクラスターから参照できます。

.. code:: yaml

   apiVersion: postgresql.k8s.enterprisedb.io/v1
   kind: Cluster
   metadata:
     name: cluster-example
   spec:
     instances: 3
     certificates:
       serverTLSSecret: my-postgres-server-cert
       serverCASecret: my-postgres-server-cert
     storage:
       size: 1Gi

cert-managerを使用して、サーバーとクライアントの両方のCA、および展開マニフェストの証明書を管理する完全な例を見つけることができます。

::

   apiVersion: cert-manager.io/v1
   kind: Issuer
   metadata:
     name: selfsigned-issuer
   spec:
     selfSigned: {}
   - --
   apiVersion: cert-manager.io/v1
   kind: Certificate
   metadata:
     name: server-ca
   spec:
     isCA: true
     commonName: my-selfsigned-server-ca
     secretName: server-ca-key-pair
     privateKey:
       algorithm: ECDSA
       size: 256
     issuerRef:
       name: selfsigned-issuer
       kind: Issuer
       group: cert-manager.io
   - --
   apiVersion: cert-manager.io/v1
   kind: Issuer
   metadata:
     name: server-ca-issuer
   spec:
     ca:
       secretName: server-ca-key-pair
   - --
   apiVersion: v1
   kind: Secret
   metadata:
     name: my-postgres-server-cert
     labels:
       k8s.enterprisedb.io/reload: ""
   - --
   apiVersion: cert-manager.io/v1
   kind: Certificate
   metadata:
     name: my-postgres-server-cert
   spec:
     secretName: my-postgres-server-cert
     usages:
       - server auth
     dnsNames:
       - cluster-example-lb.internal.mydomain.net
       - cluster-example-rw
       - cluster-example-rw.default
       - cluster-example-rw.default.svc
       - cluster-example-r
       - cluster-example-r.default
       - cluster-example-r.default.svc
       - cluster-example-ro
       - cluster-example-ro.default
       - cluster-example-ro.default.svc
     issuerRef:
       name: server-ca-issuer
       kind: Issuer
       group: cert-manager.io
   - --
   apiVersion: cert-manager.io/v1
   kind: Certificate
   metadata:
     name: client-ca
   spec:
     isCA: true
     commonName: my-selfsigned-client-ca
     secretName: client-ca-key-pair
     privateKey:
       algorithm: ECDSA
       size: 256
     issuerRef:
       name: selfsigned-issuer
       kind: Issuer
       group: cert-manager.io
   - --
   apiVersion: cert-manager.io/v1
   kind: Issuer
   metadata:
     name: client-ca-issuer
   spec:
     ca:
       secretName: client-ca-key-pair
   - --
   apiVersion: v1
   kind: Secret
   metadata:
     name: my-postgres-client-cert
     labels:
       k8s.enterprisedb.io/reload: ""
   - --
   apiVersion: cert-manager.io/v1
   kind: Certificate
   metadata:
     name: my-postgres-client-cert
   spec:
     secretName: my-postgres-client-cert
     usages:
       - client auth
     commonName: streaming_replica
     issuerRef:
       name: client-ca-issuer
       kind: Issuer
       group: cert-manager.io
   - --
   apiVersion: postgresql.k8s.enterprisedb.io/v1
   kind: Cluster
   metadata:
     name: cluster-example
   spec:
     instances: 3
     certificates:
       serverTLSSecret: my-postgres-server-cert
       serverCASecret: my-postgres-server-cert
       clientCASecret: my-postgres-client-cert
       replicationTLSSecret: my-postgres-client-cert
     storage:
       size: 1Gi

.. _クライアント証明書-1:

クライアント証明書
^^^^^^^^^^^^^^^^^^

必要に応じて、
`cert-manager <https://cert-manager.io/>`_ や `HashiCorp vault <https://www.vaultproject.io/docs/secrets/pki>`_ などの別のコンポーネントを使用して生成し、2つのクライアント証明書を提供することもできます。カスタムCAを使用してクラスターのクライアント証明書を検証するには、次のパラメーターを指定する必要があります。

- ``replicationTLSSecret`` – ユーザー ``streaming_replica``
  のクライアント証明書を含む\ ``kubernetes.io/tls``
  タイプのシークレットの名前 ``streaming_replica``
  。これには、標準の\ ``tls.crt`` および\ ``tls.key``
  キーの両方が含まれている必要があります。

- ``clientCASecret`` –
  クライアント証明書の検証に使用するCAの\ ``ca.crt``
  キーを含むシークレットの名前。

..  Note::
   オペレーターは、サーバー証明書に関連する2つのシークレットを作成および管理します。

..  Note::
   クラスターはクライアントCA秘密キーを制御していないため、 `kubectl cnp certificate` を使用してクライアント証明書を生成できません。

..  Note::
   ConfigMapとシークレットをインスタンスによって自動的にリロードする場合は、キー `k8s.enterprisedb.io/reload`  のラベルを追加できます。それ以外の場合、 `kubectl cnp reload` サブコマンドを使用してインスタンスをリロードする必要があります。

.. _cert-managerの例-1:

Cert-managerの例
^^^^^^^^^^^^^^^^

この簡単な例は、 `cert-manager <https://cert-manager.io/>`_ の使用方法を示しています

自己署名CAをセットアップし、必要なTLSサーバー証明書を生成するには。

.. code:: yaml

   - --
   apiVersion: cert-manager.io/v1
   kind: Issuer
   metadata:
     name: selfsigned-issuer
   spec:
     selfSigned: {}
   - --
   apiVersion: v1
   kind: Secret
   metadata:
     name: my-postgres-client-cert
     labels:
       k8s.enterprisedb.io/reload: ""
   - --
   apiVersion: cert-manager.io/v1
   kind: Certificate
   metadata:
     name: my-postgres-client-cert
   spec:
     secretName: my-postgres-client-cert
     usages:
       - client auth
     commonName: streaming_replica
     issuerRef:
       name: selfsigned-issuer
       kind: Issuer
       group: cert-manager.io

Cert-managerは、必要なすべてのファイルを含む\ ``my-postgres-client-cert``
という名前のシークレットを作成します。次のようにクラスターから参照できます。

.. code:: yaml

   apiVersion: postgresql.k8s.enterprisedb.io/v1
   kind: Cluster
   metadata:
     name: cluster-example
   spec:
     instances: 3
     certificates:
       clientCASecret: my-postgres-client-cert
       replicationTLSSecret: my-postgres-client-cert
     storage:
       size: 1Gi

cert-managerを使用して、サーバーとクライアントの両方のCA、および展開マニフェストの証明書を管理する完全な例を見つけることができます。

::

   apiVersion: cert-manager.io/v1
   kind: Issuer
   metadata:
     name: selfsigned-issuer
   spec:
     selfSigned: {}
   - --
   apiVersion: cert-manager.io/v1
   kind: Certificate
   metadata:
     name: server-ca
   spec:
     isCA: true
     commonName: my-selfsigned-server-ca
     secretName: server-ca-key-pair
     privateKey:
       algorithm: ECDSA
       size: 256
     issuerRef:
       name: selfsigned-issuer
       kind: Issuer
       group: cert-manager.io
   - --
   apiVersion: cert-manager.io/v1
   kind: Issuer
   metadata:
     name: server-ca-issuer
   spec:
     ca:
       secretName: server-ca-key-pair
   - --
   apiVersion: v1
   kind: Secret
   metadata:
     name: my-postgres-server-cert
     labels:
       k8s.enterprisedb.io/reload: ""
   - --
   apiVersion: cert-manager.io/v1
   kind: Certificate
   metadata:
     name: my-postgres-server-cert
   spec:
     secretName: my-postgres-server-cert
     usages:
       - server auth
     dnsNames:
       - cluster-example-lb.internal.mydomain.net
       - cluster-example-rw
       - cluster-example-rw.default
       - cluster-example-rw.default.svc
       - cluster-example-r
       - cluster-example-r.default
       - cluster-example-r.default.svc
       - cluster-example-ro
       - cluster-example-ro.default
       - cluster-example-ro.default.svc
     issuerRef:
       name: server-ca-issuer
       kind: Issuer
       group: cert-manager.io
   - --
   apiVersion: cert-manager.io/v1
   kind: Certificate
   metadata:
     name: client-ca
   spec:
     isCA: true
     commonName: my-selfsigned-client-ca
     secretName: client-ca-key-pair
     privateKey:
       algorithm: ECDSA
       size: 256
     issuerRef:
       name: selfsigned-issuer
       kind: Issuer
       group: cert-manager.io
   - --
   apiVersion: cert-manager.io/v1
   kind: Issuer
   metadata:
     name: client-ca-issuer
   spec:
     ca:
       secretName: client-ca-key-pair
   - --
   apiVersion: v1
   kind: Secret
   metadata:
     name: my-postgres-client-cert
     labels:
       k8s.enterprisedb.io/reload: ""
   - --
   apiVersion: cert-manager.io/v1
   kind: Certificate
   metadata:
     name: my-postgres-client-cert
   spec:
     secretName: my-postgres-client-cert
     usages:
       - client auth
     commonName: streaming_replica
     issuerRef:
       name: client-ca-issuer
       kind: Issuer
       group: cert-manager.io
   - --
   apiVersion: postgresql.k8s.enterprisedb.io/v1
   kind: Cluster
   metadata:
     name: cluster-example
   spec:
     instances: 3
     certificates:
       serverTLSSecret: my-postgres-server-cert
       serverCASecret: my-postgres-server-cert
       clientCASecret: my-postgres-client-cert
       replicationTLSSecret: my-postgres-client-cert
     storage:
       size: 1Gi
