Certificates
CloudNativePG has been designed to natively support TLS certificates.
In order to set up a Cluster
, the operator requires:
- a server Certification Authority (CA) certificate
- a server TLS certificate signed by the server Certification Authority
- a client Certification Authority certificate
- a streaming replication client certificate generated by the client Certification Authority
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, and primarily operates in two modes:
- operator managed: certificates are internally managed by the operator in a fully automated way, and signed using a CA created by CloudNativePG
- user provided: certificates are generated outside the operator and imported in the cluster definition as secrets - CloudNativePG integrates itself with cert-manager (see examples below)
You can also choose a hybrid approach, where only part of the certificates is generated outside CNPG.
Operator managed mode
By default, the operator generates a single Certification Authority and uses it for both client and server certificates, which are then managed and renewed automatically.
Server Certificates
Server CA Secret
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 assslrootcert
in clients' connection strings.ca.key
: the key used to sign Server SSL certificate automatically
Server TLS Secret
The operator uses the generated self-signed CA to sign a server TLS
certificate, stored in a Secret of type kubernetes.io/tls
and configured to
be used as ssl_cert_file
and ssl_key_file
by the instances so that clients
can verify their identity and connect securely.
Server alternative DNS names
You can specify DNS server alternative names that will be part of the generated server TLS secret in addition to the default ones.
Client Certificates
Client CA Secret
The same self-signed CA as the Server CA is used by default. The public part
will be passed as ssl_ca_file
to all the instances in order to be able to verify
client certificates it signed. The private key will be stored in the same secret and
used to sign Client certificates generated by the kubectl cnpg
plugin.
Client streaming_replica Certificate
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
.
This certificate will be passed as sslcert
and sslkey
in replicas' connection strings,
to allow securely connecting to the primary instance.
User-provided certificates mode
Server Certificates
If required, you can also provide the two server certificates, generating them using a separate component such as cert-manager. In order to use a custom server TLS certificate for a Cluster, you must specify the following parameters:
serverTLSSecret
: the name of a Secret of typekubernetes.io/tls
, containing the server TLS certificate. It must contain both the standardtls.crt
andtls.key
keys.serverCASecret
: the name of a Secret containing theca.crt
key.
Note
The operator will still create and manage the two secrets related to client certificates.
Note
If you want ConfigMaps and Secrets to be automatically reloaded by instances, you can
add a label with key cnpg.io/reload
to it, otherwise you will have to reload
the instances using the kubectl cnpg reload
subcommand.
See below for a complete example.
Example
Given the following files:
server-ca.crt
: the certificate of the CA that signed the server TLS certificate.server.crt
: 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 Cluster
referencing those secrets:
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 will use the provided server certificates for TLS connections.
Cert-manager Example
Here is a simple example about how to use cert-manager to set up a self-signed CA and generate the needed TLS server certificate:
---
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
A Secret named my-postgres-server-cert
is created by cert-manager, containing all the needed files and can be referenced
from a Cluster as follows:
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 cluster-example-cert-manager.yaml deployment manifest.
Client Certificate
If required, you can also provide the two client certificates, generating them using a separate component such as cert-manager or hashicorp vault. In order 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 typekubernetes.io/tls
, containing the client certificate for userstreaming_replica
. It must contain both the standardtls.crt
andtls.key
keys.clientCASecret
: the name of a Secret containing theca.crt
key of the CA that should be used to verify client certificate.
Note
The operator will still create and manage the two secrets related to server certificates.
Note
As the Cluster is not in control of the client CA secret key, client certificates
can not be generated using kubectl cnpg certificate
anymore.
Note
If you want ConfigMaps and Secrets to be automatically reloaded by instances, you can
add a label with key cnpg.io/reload
to it, otherwise you will have to reload
the instances using the kubectl cnpg reload
subcommand.
Cert-manager Example
Here a simple example about how to use cert-manager to set up a self-signed CA and generate the needed TLS server certificate:
---
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
A Secret named my-postgres-client-cert
is created by cert-manager, containing all the needed files and can be referenced
from a Cluster as follows:
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 cluster-example-cert-manager.yaml deployment manifest.