Skip to content

Rate this page
Thanks for your feedback
Thank you! The feedback has been submitted.

Get free database assistance or contact our experts for personalized support.

Update certificates

How your TLS certificates are updated depends on how they were created:

  • Certificates generated by the Operator are long-term. The Operator automatically updates the automatically-generated certificates to ensure your applications continue operation without communication issues.
  • Certificates issued by the cert-manager are short-term. You can configure their validity in the Custom Resource when you deploy a cluster. The cert-manager automatically reissues the certificates on schedule and without downtime.
  • Certificates you generated manually or provided to the Operator are out of its control. The Operator doesn’t update custom certificates. It is your responsibility to timely update them.

This document focuses on how to update manually generated certificates.

Check your certificates for expiration

  1. List the Secrets

    kubectl get secrets -n <namespace>
    
  2. First, check the necessary secrets names (cluster1-cluster-cert and cluster1-replication-cert by default):

    You will have the following response:

    NAME                            TYPE     DATA   AGE
    cluster1-cluster-cert           Opaque   3      11m
    ...
    cluster1-replication-cert       Opaque   3      11m
    ...
    
  3. Now use the following command to find out the certificates validity dates, substituting Secrets names if necessary:

    {
      kubectl -n <namespace> get secret/cluster1-replication-cert -o jsonpath='{.data.tls\.crt}' | base64 --decode | openssl x509 -noout -dates
      kubectl -n <namespace> get secret/cluster1-cluster-cert -o jsonpath='{.data.ca\.crt}' | base64 --decode | openssl x509 -noout -dates
      }
    

    The resulting output will be self-explanatory:

    notBefore=Jun 28 10:20:19 2023 GMT
    notAfter=Jun 27 11:20:19 2024 GMT
    notBefore=Jun 28 10:20:18 2023 GMT
    notAfter=Jun 25 11:20:18 2033 GMT
    

Update custom certificates

You can update only custom certificates for external and / or internal communication and keep the same root CA certificate.

You can update the contents of your existing Secrets referenced in the spec.secrets.customTLSSecret and/or spec.secrets.customReplicationTLSSecret fields in deploy/cr.yaml without changing their names. In this case, the Operator detects the updated certificate data and applies the changes to the running cluster without restarting it. Such update is called hot reload.

This example shows how you can do it. Let’s say you have the following certificates and Secrets:

  • server.pem / server-key.pem and the cluster1-cert Secret for external communication,
  • replica.pem / replica-key.pem and cluster1-replication-cert Secret for internal communication
  • ca.pem / ca-key.pem is the existing CA root certificate that you keep

Your cluster is deployed in the postgres-operator namespace.

  1. Set the context for the cluster:

    export NAMESPACE=postgres-operator
    
  2. Create a YAML manifest for the cluster1-cert Secret. Run the following command to generate a YAML manifest (adjust file paths if needed):

    kubectl create secret generic cluster1-cert \
       --from-file=tls.crt=server.pem \
       --from-file=tls.key=server-key.pem \
       --from-file=ca.crt=ca.pem \
       -n "$NAMESPACE" \
       --dry-run=client -o yaml > cluster1-cert.yaml
    
  3. Create a YAML manifest for the cluster1-replication-cert Secret. Run the following command to generate a YAML manifest (adjust file paths if needed):

    kubectl create secret generic cluster1-replication-cert \
       --from-file=tls.crt=replica.pem \
       --from-file=tls.key=replica-key.pem \
       --from-file=ca.crt=ca.pem \
       -n "$NAMESPACE" \
       --dry-run=client -o yaml > cluster1-replication-cert.yaml
    
  4. Apply the manifests to update the Secrets:

    kubectl apply -f cluster1-cert.yaml -f cluster1-replication-cert.yaml -n "$NAMESPACE"
    

If you create new Secrets with new names and values, update the spec.customTLSSecret and spec.customReplicationTLSSecret fields in the deploy/cr.yaml. When you apply the new configuration,this causes the Operator to restart the cluster.

Update a custom root CA certificate

Here’s what you need to know if you wish to update a custom root CA certificate:

  • If you change a root CA certificate, you must also change your custom TLS certificates for external and internal communications as these must be signed with the same root CA.
  • The new root CA and associated certs must be stored in new Secrets (not overwriting existing ones). This ensures rollback capability in case of misconfiguration or validation issues.
  • You must pause the cluster before applying changes. This prevents the Operator from restarting or reconfiguring Pods mid-update.

To update a custom root CA certificate, do the following:

  1. Generate a new root CA certificate and key. For example, you have them in files named new-ca.pem and new-ca-key.pem.
  2. Generate all dependent certificates for external and internal communication and sign them using the new root CA certificate. Check the Generate certificates manually section for the steps. For example, you end up with the following certificates:

    • server.pem and server-key.pem for external communication
    • replication.pem and replication-key.pem for internal communication
  3. Create a new Secret object for the new root CA certificate and define the new CA certificate and key within. Let’s name it cluster1-ca-cert-new.

    kubectl create secret generic -n postgres-operator cluster1-ca-cert-new \
      --from-file=ca.crt=new-ca.pem \
      --from-file=ca.key=new-ca-key.pem
    
  4. Create new Secrets for external and internal communications, named cluster1-tls and cluster1-replication-tls respectively

    kubectl create secret generic -n postgres-operator cluster1-tls \
      --from-file=ca.crt=ca.pem \
      --from-file=tls.key=server-key.pem \
      --from-file=tls.crt=server.pem
    
    kubectl create secret generic -n postgres-operator cluster1-replication-tls \
      --from-file=ca.crt=ca.pem \
      --from-file=tls.key=replication-key.pem \
      --from-file=tls.crt=replication.pem
    
  5. Pause the cluster to prevent the Operator to restart the Pods mid-update.

    kubectl patch pg cluster1 \
      --type merge \
      --patch '{"spec": {"pause": true}}' \
      --namespace postgres-operator
    
  6. Specify details about new custom certificates in the deploy/cr.yaml. Since this is a provisioned cluster, apply the patch as follows:

    kubectl patch pg cluster1 \
        --type merge \
        --patch '{
            "spec": {
                "secrets": {
                    "customRootCATLSSecret": {
                        "name": "cluster1-ca-cert-new",
                        "items": [
                            {
                                "key": "ca.crt",
                                "path": "root.crt"
                            },
                            {
                                "key": "ca.key",
                                "path": "root.key"
                            }
                        ]
                    },
                    "customTLSSecret": {
                        "name": "cluster1-tls"
                    },
                    "customReplicationTLSSecret": {
                        "name": "cluster1-replication-tls"
                    }
                }
            }
        }' \
        --namespace postgres-operator
    
  7. Unpause the cluster to resume the Operator control:

    kubectl patch pg cluster1 \
      --type merge \
      --patch '{"spec": {"pause": false}}' \
      --namespace postgres-operator
    

Last update: March 30, 2026
Created: March 26, 2026