Skip to content
logo
Percona Operator for PostgreSQL
Transport Encryption (TLS/SSL)
Initializing search
    percona/k8spg-docs
    percona/k8spg-docs
    • Welcome
      • System Requirements
      • Design and architecture
      • Comparison with other solutions
      • Install on Minikube
      • Install on Google Kubernetes Engine (GKE)
      • Install with Helm
      • Generic Kubernetes installation
      • Install on OpenShift
      • Application and system users
      • Changing PostgreSQL Options
      • Anti-affinity and tolerations
      • Transport Encryption (TLS/SSL)
        • Allow the Operator to generate certificates automatically
          • Installation of the cert-manager
          • Turning automatic generation of certificates on
        • Generate certificates manually
        • Check connectivity to the cluster
        • Run Percona Distribution for PostgreSQL without TLS
      • Telemetry
      • Backup and restore
      • Upgrade Percona Distribution for PostgreSQL and the Operator
      • Horizontal and vertical scaling
      • Monitor with Percona Monitoring and Management (PMM)
      • Restart or pause the cluster
      • Deploy a standby cluster for Disaster Recovery
      • Provide Percona Operator for PostgreSQL single-namespace and multi-namespace deployment
      • Use PostgreSQL tablespaces with Percona Operator for PostgreSQL
      • Custom Resource options
      • Operator installation options
      • Percona certified images
      • Frequently Asked Questions
      • Release notes index
      • Percona Operator for PostgreSQL 1.3.0 (2022-08-04)
      • Percona Operator for PostgreSQL 1.2.0 (2022-04-06)
      • Percona Operator for PostgreSQL 1.1.0 (2021-12-07)
      • Percona Operator for PostgreSQL 1.0.0 (2021-10-07)
      • Percona Operator for PostgreSQL 0.2.0 (2021-08-12)
      • Percona Operator for PostgreSQL 0.1.0 (2021-05-10)

    • Allow the Operator to generate certificates automatically
      • Installation of the cert-manager
      • Turning automatic generation of certificates on
    • Generate certificates manually
    • Check connectivity to the cluster
    • Run Percona Distribution for PostgreSQL without TLS

    Transport Layer Security (TLS)¶

    The Percona Operator for PostgreSQL uses Transport Layer Security (TLS) cryptographic protocol for the following types of communication:

    • Internal - communication between PostgreSQL instances in the cluster
    • External - communication between the client application and the cluster

    The internal certificate is also used as an authorization method for PostgreSQL Replica instances.

    TLS security can be configured in several ways:

    • the Operator can generate certificates automatically at cluster creation time,
    • you can also generate certificates manually.

    You can also use pre-generated certificates available in the deploy/ssl-secrets.yaml file for test purposes, but we strongly recommend avoiding their usage on any production system!

    The following subsections explain how to configure TLS security with the Operator yourself, as well as how to temporarily disable it if needed.

    Allow the Operator to generate certificates automatically¶

    The Operator is able to generate long-term certificates automatically and turn on encryption at cluster creation time, if there are no certificate secrets available. It generates certificates with the help of cert-manager - a Kubernetes certificate management controller widely used to automate the management and issuance of TLS certificates. Cert-manager is community-driven and open source.

    Installation of the cert-manager¶

    You can install cert-manager as follows:

    • Create a namespace,
    • Disable resource validations on the cert-manager namespace,
    • Install the cert-manager.

    The following commands perform all the needed actions:

    $ kubectl create namespace cert-manager
    $ kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true
    $ kubectl_bin apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml
    

    After the installation, you can verify the cert-manager by running the following command:

    $ kubectl get pods -n cert-manager
    

    The result should display the cert-manager and webhook active and running.

    Turning automatic generation of certificates on¶

    When you have already installed cert-manager, the operator is able to request a certificate from it. To make this happend, uncomment sslCA, sslSecretName, and sslReplicationSecretName options in the deploy/cr.yaml configuration file:

    ...
    spec:
    #  secretsName: cluster1-users
      sslCA: cluster1-ssl-ca
      sslSecretName: cluster1-ssl-keypair
      sslReplicationSecretName: cluster1-ssl-keypair
    ...
    

    When done, deploy your cluster as usual, with the kubectl apply -f deploy/cr.yaml command. Certificates will be generated if there are no certificate secrets available.

    Generate certificates manually¶

    To generate certificates manually, follow these steps:

    1. Provision a to generate TLS certificates,
    2. Generate a key and certificate file with the server details,
    3. Create the server TLS certificates using the keys, certs, and server details.

    The set of commands generates certificates with the following attributes:

    • Server-pem - Certificate
    • Server-key.pem - the private key
    • ca.pem - Certificate Authority

    You should generate one set of certificates for external communications, and another set for internal ones.

    Supposing that your cluster name is cluster1, you can use the following commands to generate certificates:

    $ CLUSTER_NAME=cluster1
    $ NAMESPACE=default
    $ cat <<EOF | cfssl gencert -initca - | cfssljson -bare ca
    {
      "CN": "*",
      "key": {
        "algo": "ecdsa",
        "size": 384
      }
    }
    EOF
    
    $ cat <<EOF > ca-config.json
    {
       "signing": {
         "default": {
            "expiry": "87600h",
            "usages": ["digital signature", "key encipherment", "content commitment"]
          }
       }
    }
    EOF
    
    $ cat <<EOF | cfssl gencert -ca=ca.pem  -ca-key=ca-key.pem -config=./ca-config.json - | cfssljson -bare server
    {
       "hosts": [
         "localhost",
         "${CLUSTER_NAME}",
         "${CLUSTER_NAME}.${NAMESPACE}",
         "${CLUSTER_NAME}.${NAMESPACE}.svc.cluster.local",
         "${CLUSTER_NAME}-pgbouncer",
         "${CLUSTER_NAME}-pgbouncer.${NAMESPACE}",
         "${CLUSTER_NAME}-pgbouncer.${NAMESPACE}.svc.cluster.local",
         "*.${CLUSTER_NAME}",
         "*.${CLUSTER_NAME}.${NAMESPACE}",
         "*.${CLUSTER_NAME}.${NAMESPACE}.svc.cluster.local",
         "*.${CLUSTER_NAME}-pgbouncer",
         "*.${CLUSTER_NAME}-pgbouncer.${NAMESPACE}",
         "*.${CLUSTER_NAME}-pgbouncer.${NAMESPACE}.svc.cluster.local"
       ],
       "CN": "${CLUSTER_NAME}",
       "key": {
         "algo": "ecdsa",
         "size": 384
       }
    }
    EOF
    
    $ kubectl create secret generic ${CLUSTER_NAME}-ssl-ca --from-file=ca.crt=ca.pem
    $ kubectl create secret tls  ${CLUSTER_NAME}-ssl-keypair --cert=server.pem --key=server-key.pem
    

    If your PostgreSQL cluster includes replica instances (this feature is on by default), generate certificates for them in a similar way:

    $ cat <<EOF | cfssl gencert -ca=ca.pem  -ca-key=ca-key.pem -config=./ca-config.json - | cfssljson -bare replicas
    {
       "CN": "primaryuser",
       "key": {
          "algo": "ecdsa",
          "size": 384
       }
    }
    EOF
    
    $ kubectl create secret tls  ${CLUSTER_NAME}-ssl-replicas --cert=replicas.pem --key=replicas-key.pem
    

    When certificates are generated, set the following keys in the deploy/cr.yaml configuration file:

    • spec.sslCA key should contain the name of the secret with TLS used for both connection encryption (external traffic), and replication (internal traffic),
    • spec.sslSecretName key should contain the name of the secret created to encrypt external communications,
    • spec.secrets.sslReplicationSecretName key should contain the name of the secret created to encrypt internal communications,
    • spec.tlsOnly is set to true by default and enforces encryption

    Don’t forget to apply changes as usual:

    $ kubectl apply -f deploy/cr.yaml
    

    Check connectivity to the cluster¶

    You can check TLS communication with use of the psql, the standard interactive terminal-based frontend to PostgreSQL. The following command will spawn a new pg-client container, which includes needed command and can be used for the check (use your real cluster name instead of the <cluster-name> placeholder):

    $ cat <<EOF | kubectl apply -f -
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: pg-client
    spec:
      replicas: 1
      selector:
        matchLabels:
          name: pg-client
      template:
        metadata:
          labels:
            name: pg-client
        spec:
          containers:
            - name: pg-client
              image: perconalab/percona-distribution-postgresql:14.4
              imagePullPolicy: Always
              command:
              - sleep
              args:
              - "100500"
              volumeMounts:
                - name: ca
                  mountPath: "/tmp/tls"
          volumes:
          - name: ca
            secret:
              secretName: <cluster_name>-ssl-ca
              items:
              - key: ca.crt
                path: ca.crt
                mode: 0777
    EOF
    

    Now get shell access to the newly created container, and launch the PostgreSQL interactive terminal to check connectivity over the encrypted channel (please use real cluster-name, PostgreSQL user login and password):

    $ kubectl exec -it deployment/pg-client -- bash -il
    [postgres@pg-client /]$ PGSSLMODE=verify-ca PGSSLROOTCERT=/tmp/tls/ca.crt psql postgres://<postgresql-user>:<postgresql-password>@<cluster-name>-pgbouncer.<namespace>.svc.cluster.local
    

    Now you should see the prompt of PostgreSQL interactive terminal:

    $ psql (14.4)
    Type "help" for help.
    pgdb=>
    

    Run Percona Distribution for PostgreSQL without TLS¶

    Omitting TLS is also possible, but we recommend that you run your cluster with the TLS protocol enabled.

    To disable TLS protocol (e.g. for demonstration purposes) set the spec.tlsOnly key to false, and make sure that there are no certificate secrets configured in the deploy/cr.yaml file.

    Contact Us

    For free technical help, visit the Percona Community Forum.

    To report bugs or submit feature requests, open a JIRA ticket.

    For paid support and managed or consulting services , contact Percona Sales.


    Last update: 2023-02-09
    Back to top
    Percona LLC and/or its affiliates, © 2009 - 2022
    Made with Material for MkDocs

    Cookie consent

    We use cookies to recognize your repeated visits and preferences, as well as to measure the effectiveness of our documentation and whether users find what they're searching for. With your consent, you're helping us to make our documentation better.