Project: CloudNativePG (App Definition and Development / Database)
File: certificates.md

CloudNativePG was designed to natively support TLS certificates. To set up a cluster, the operator requires: A server certification authority (CA) certificate A server TLS certificate signed by the server CA A client CA certificate A streaming replication client certificate generated by the client CA !!! Note You can find all the secrets used by the cluster and their expiration dates in the cluster's status. CloudNativePG is very flexible when it comes to TLS certificates. It primarily operates in two modes: Certificates are internally managed by the operator in a fully automated way and signed using a CA created by CloudNativePG. Certificates are generated outside the operator and imported in the cluster definition as secrets. CloudNativePG integrates itself with (See .) You can also choose a hybrid approach, where only part of the certificates is generated outside CNPG. By default, the operator generates a single CA and uses it for both client and server certificates, which are then managed and renewed automatically. The operator generates a self-signed CA and stores it in a generic secret containing the following keys: `ca.crt` CA certificate used to validate the server certificate, used as `sslrootcert` in clients' connection strings. `ca.key` The key used to sign the server SSL certificate automatically. The operator uses the generated self-signed CA to sign a server TLS certificate. It's stored in a secret of type `kubernetes.io/tls` and configured to be used as `sslcertfile` and `sslkeyfile` by the instances. This approach enables clients to verify their identity and connect securely. In addition to the default ones, you can specify DNS server alternative names as part of the generated server TLS secret. By default, the same self-signed CA as the server CA is used. The public part is passed as `sslcafile` to all the instances so it can verify client certificates it signed. The private key is stored in the same secret and used to sign client certificates generated by the `kubectl cnpg` plugin. The operator uses the generated self-signed CA to sign a client certificate for the user `streaming_replica`, storing it in a secret of type `kubernetes.io/tls`. To allow secure connection to the primary instance, this certificate is passed as `sslcert` and `sslkey` in the replicas' connection strings. If required, you can also provide the two server certificates, generating them using a separate component such as . To use a custom server TLS certificate for a cluster, you must specify the following parameters: `serverTLSSecret` The name of a secret of type `kubernetes.io/tls` containing the server TLS certificate. It must contain both the standard `tls.crt` and `tls.key` keys. `serverCASecret` The name of a secret containing the `ca.crt` key. !!! Note The operator still creates and manages the two secrets related to client certificates. !!! Note If you want ConfigMaps and secrets to be reloaded by instances, you can add a label with the key `cnpg.io/reload` to it. Otherwise you must reload the instances using the `kubectl cnpg reload` subcommand. Given the following files: `server-ca.crt` The certificate of the CA that signed the server TLS certificate.

The certificate of the server TLS certificate. `server.key` The private key of the server TLS certificate. Create a secret containing the CA certificate: ``` kubectl create secret generic my-postgresql-server-ca \ --from-file=ca.crt=./server-ca.crt ``` Create a secret with the TLS certificate: ``` kubectl create secret tls my-postgresql-server \ --cert=./server.crt --key=./server.key ``` Create a PostgreSQL cluster referencing those secrets: ```bash kubectl apply -f - <<EOF apiVersion: postgresql.cnpg.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 ``` The new cluster uses the provided server certificates for TLS connections. This simple example shows how to use to set up a self-signed CA and generate the needed TLS server certificate: ```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: cnpg.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 creates a secret named `my-postgres-server-cert`. It contains all the needed files and can be referenced from a cluster as follows: ```yaml apiVersion: postgresql.cnpg.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 ``` You can find a complete example using cert-manager to manage both server and client CA and certificates in the deployment manifest. If required, you can also provide the two client certificates, generating them using a separate component such as or . To use a custom CA to verify client certificates for a cluster, you must specify the following parameters: `replicationTLSSecret` The name of a secret of type `kubernetes.io/tls` containing the client certificate for user `streaming_replica`. It must contain both the standard `tls.crt` and `tls.key` keys. `clientCASecret` The name of a secret containing the `ca.crt` key of the CA to use to verify client certificate. !!! Note The operator still creates and manages the two secrets related to server certificates. !!! Note As the cluster isn't in control of the client CA secret key, you can no longer generate client certificates using `kubectl cnpg certificate`. !!! Note If you want ConfigMaps and secrets to be automatically reloaded by instances, you can add a label with the key `cnpg.io/reload` to it. Otherwise, you must reload the instances using the `kubectl cnpg reload` subcommand. This simple example shows how to use to set up a self-signed CA and generate the needed TLS server certificate: ```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: cnpg.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 creates a secret named `my-postgres-client-cert` that contains all the needed files. You can reference it from a cluster as follows: ```yaml apiVersion: postgresql.cnpg.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 ``` You can find a complete example using cert-manager to manage both server and client CA and certificates in the deployment manifest.