diff --git a/docs/examples/pgbouncer/reconfigure-tls/add-tls.yaml b/docs/examples/pgbouncer/reconfigure-tls/add-tls.yaml new file mode 100644 index 000000000..63ea17675 --- /dev/null +++ b/docs/examples/pgbouncer/reconfigure-tls/add-tls.yaml @@ -0,0 +1,24 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: PgBouncerOpsRequest +metadata: + name: add-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: pb + tls: + sslMode: verify-full + clientAuthMode: md5 + issuerRef: + name: pb-issuer + kind: Issuer + apiGroup: "cert-manager.io" + certificates: + - alias: client + subject: + organizations: + - pgbouncer + organizationalUnits: + - client + apply: Always \ No newline at end of file diff --git a/docs/examples/pgbouncer/reconfigure-tls/change-issuer.yaml b/docs/examples/pgbouncer/reconfigure-tls/change-issuer.yaml new file mode 100644 index 000000000..f483e3b23 --- /dev/null +++ b/docs/examples/pgbouncer/reconfigure-tls/change-issuer.yaml @@ -0,0 +1,14 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: PgBouncerOpsRequest +metadata: + name: change-issuer + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: pb + tls: + issuerRef: + name: pb-new-issuer + kind: Issuer + apiGroup: "cert-manager.io" \ No newline at end of file diff --git a/docs/examples/pgbouncer/reconfigure-tls/issuer.yaml b/docs/examples/pgbouncer/reconfigure-tls/issuer.yaml new file mode 100644 index 000000000..c1c587fd3 --- /dev/null +++ b/docs/examples/pgbouncer/reconfigure-tls/issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: pb-issuer + namespace: demo +spec: + ca: + secretName: pgbouncer-ca \ No newline at end of file diff --git a/docs/examples/pgbouncer/reconfigure-tls/new-issuer.yaml b/docs/examples/pgbouncer/reconfigure-tls/new-issuer.yaml new file mode 100644 index 000000000..8c2a8c6b8 --- /dev/null +++ b/docs/examples/pgbouncer/reconfigure-tls/new-issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: pb-new-issuer + namespace: demo +spec: + ca: + secretName: pgbouncer-new-ca \ No newline at end of file diff --git a/docs/examples/pgbouncer/reconfigure-tls/pb.yaml b/docs/examples/pgbouncer/reconfigure-tls/pb.yaml new file mode 100644 index 000000000..07a3d82a3 --- /dev/null +++ b/docs/examples/pgbouncer/reconfigure-tls/pb.yaml @@ -0,0 +1,23 @@ +apiVersion: kubedb.com/v1 +kind: PgBouncer +metadata: + name: pb + namespace: demo +spec: + replicas: 1 + version: "1.18.0" + database: + syncUsers: true + databaseName: "postgres" + databaseRef: + name: "ha-postgres" + namespace: demo + connectionPool: + poolMode: session + port: 5432 + reservePoolSize: 5 + maxClientConnections: 87 + defaultPoolSize: 2 + minPoolSize: 1 + authType: md5 + deletionPolicy: WipeOut \ No newline at end of file diff --git a/docs/examples/pgbouncer/reconfigure-tls/remove-tls.yaml b/docs/examples/pgbouncer/reconfigure-tls/remove-tls.yaml new file mode 100644 index 000000000..bdadcf158 --- /dev/null +++ b/docs/examples/pgbouncer/reconfigure-tls/remove-tls.yaml @@ -0,0 +1,14 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: PgBouncerOpsRequest +metadata: + name: remove-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: pb + tls: + clientAuthMode: md5 + remove: true + timeout: 5m + apply: IfReady \ No newline at end of file diff --git a/docs/examples/pgbouncer/reconfigure-tls/rotate-tls.yaml b/docs/examples/pgbouncer/reconfigure-tls/rotate-tls.yaml new file mode 100644 index 000000000..cd6bfc3db --- /dev/null +++ b/docs/examples/pgbouncer/reconfigure-tls/rotate-tls.yaml @@ -0,0 +1,11 @@ +apiVersion: ops.kubedb.com/v1alpha1 +kind: PgBouncerOpsRequest +metadata: + name: rotate-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: pb + tls: + rotateCertificates: true \ No newline at end of file diff --git a/docs/examples/pgbouncer/tls/issuer.yaml b/docs/examples/pgbouncer/tls/issuer.yaml new file mode 100644 index 000000000..965f5e9a6 --- /dev/null +++ b/docs/examples/pgbouncer/tls/issuer.yaml @@ -0,0 +1,8 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: pgbouncer-ca-issuer + namespace: demo +spec: + ca: + secretName: pgbouncer-ca \ No newline at end of file diff --git a/docs/examples/pgbouncer/tls/pgbouncer-ssl.yaml b/docs/examples/pgbouncer/tls/pgbouncer-ssl.yaml new file mode 100644 index 000000000..e35f61fcc --- /dev/null +++ b/docs/examples/pgbouncer/tls/pgbouncer-ssl.yaml @@ -0,0 +1,38 @@ +apiVersion: kubedb.com/v1 +kind: PgBouncer +metadata: + name: pb-tls + namespace: demo +spec: + replicas: 1 + version: "1.18.0" + database: + syncUsers: true + databaseName: "postgres" + databaseRef: + name: "pg" + namespace: demo + connectionPool: + poolMode: session + port: 5432 + reservePoolSize: 5 + maxClientConnections: 87 + defaultPoolSize: 2 + minPoolSize: 1 + authType: md5 + deletionPolicy: WipeOut + sslMode: verify-ca + tls: + issuerRef: + apiGroup: cert-manager.io + name: pb-ca-issuer + kind: Issuer + certificates: + - alias: server + subject: + organizations: + - kubedb:server + dnsNames: + - localhost + ipAddresses: + - "127.0.0.1" \ No newline at end of file diff --git a/docs/guides/pgbouncer/reconfigure-tls/_index.md b/docs/guides/pgbouncer/reconfigure-tls/_index.md new file mode 100644 index 000000000..ed86414ff --- /dev/null +++ b/docs/guides/pgbouncer/reconfigure-tls/_index.md @@ -0,0 +1,10 @@ +--- +title: Reconfigure PgBouncer TLS/SSL +menu: + docs_{{ .version }}: + identifier: pb-reconfigure-tls + name: Reconfigure TLS/SSL + parent: pb-pgbouncer-guides + weight: 46 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/pgbouncer/reconfigure-tls/overview.md b/docs/guides/pgbouncer/reconfigure-tls/overview.md new file mode 100644 index 000000000..b7aced43f --- /dev/null +++ b/docs/guides/pgbouncer/reconfigure-tls/overview.md @@ -0,0 +1,54 @@ +--- +title: Reconfiguring TLS of PgBouncer +menu: + docs_{{ .version }}: + identifier: pb-reconfigure-tls-overview + name: Overview + parent: pb-reconfigure-tls + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Reconfiguring TLS of PgBouncer + +This guide will give an overview on how KubeDB Ops-manager operator reconfigures TLS configuration i.e. add TLS, remove TLS, update issuer/cluster issuer or Certificates and rotate the certificates of a `PgBouncer`. + +## Before You Begin + +- You should be familiar with the following `KubeDB` concepts: + - [PgBouncer](/docs/guides/pgbouncer/concepts/pgbouncer.md) + - [PgBouncerOpsRequest](/docs/guides/pgbouncer/concepts/opsrequest.md) + +## How Reconfiguring PgBouncer TLS Configuration Process Works + +The following diagram shows how KubeDB Ops-manager operator reconfigures TLS of a `PgBouncer`. Open the image in a new tab to see the enlarged version. + +
+  Reconfiguring TLS process of PgBouncer +
Fig: Reconfiguring TLS process of PgBouncer
+
+ +The Reconfiguring PgBouncer TLS process consists of the following steps: + +1. At first, a user creates a `PgBouncer` Custom Resource Object (CRO). + +2. `KubeDB` Provisioner operator watches the `PgBouncer` CRO. + +3. When the operator finds a `PgBouncer` CR, it creates `PetSet` and related necessary stuff like secrets, services, etc. + +4. Then, in order to reconfigure the TLS configuration of the `PgBouncer` the user creates a `PgBouncerOpsRequest` CR with desired information. + +5. `KubeDB` Ops-manager operator watches the `PgBouncerOpsRequest` CR. + +6. When it finds a `PgBouncerOpsRequest` CR, it pauses the `PgBouncer` object which is referred from the `PgBouncerOpsRequest`. So, the `KubeDB` Provisioner operator doesn't perform any operations on the `PgBouncer` object during the reconfiguring TLS process. + +7. Then the `KubeDB` Ops-manager operator will add, remove, update or rotate TLS configuration based on the Ops Request yaml. + +8. Then the `KubeDB` Ops-manager operator will restart all the Pods of the pgbouncer so that they restart with the new TLS configuration defined in the `PgBouncerOpsRequest` CR. + +9. After the successful reconfiguring of the `PgBouncer` TLS, the `KubeDB` Ops-manager operator resumes the `PgBouncer` object so that the `KubeDB` Provisioner operator resumes its usual operations. + +In the next docs, we are going to show a step-by-step guide on reconfiguring TLS configuration of a PgBouncer using `PgBouncerOpsRequest` CRD. \ No newline at end of file diff --git a/docs/guides/pgbouncer/reconfigure-tls/reconfigure-tls.md b/docs/guides/pgbouncer/reconfigure-tls/reconfigure-tls.md new file mode 100644 index 000000000..5842502f5 --- /dev/null +++ b/docs/guides/pgbouncer/reconfigure-tls/reconfigure-tls.md @@ -0,0 +1,628 @@ +--- +title: Reconfigure PgBouncer TLS/SSL Encryption +menu: + docs_{{ .version }}: + identifier: pb-reconfigure-tls-cluster + name: Reconfigure PgBouncer TLS/SSL Encryption + parent: pb-reconfigure-tls + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Reconfigure PgBouncer TLS/SSL (Transport Encryption) + +KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL certificates, changing issuer for existing PgBouncer database via a PgBouncerOpsRequest. This tutorial will show you how to use KubeDB to reconfigure TLS/SSL encryption. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Install `cert-manger` v1.0.0 or later to your cluster to manage your SSL/TLS certificates from [here](https://cert-manager.io/docs/installation/). + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + + ```bash + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: YAML files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +### Prepare Postgres +For a PgBouncer surely we will need a Postgres server so, prepare a KubeDB Postgres cluster using this [tutorial](/docs/guides/postgres/clustering/streaming_replication.md), or you can use any externally managed postgres but in that case you need to create an [appbinding](/docs/guides/pgbouncer/concepts/appbinding.md) yourself. In this tutorial we will use 3 node Postgres cluster named `ha-postgres`. + +Now, we are going to deploy a `PgBouncer` using a supported version by `KubeDB` operator. Then we are going to apply `PgBouncerOpsRequest` to reconfigure its configuration. + +### Prepare PgBouncer + +Now, we are going to deploy a `PgBouncer` with version `1.18.0`. + +## Add TLS to a PgBouncer database + +Here, We are going to create a PgBouncer database without TLS and then reconfigure the database to use TLS. + +### Deploy PgBouncer without TLS + +In this section, we are going to deploy a PgBouncer Replicaset database without TLS. In the next few sections we will reconfigure TLS using `PgBouncerOpsRequest` CRD. Below is the YAML of the `PgBouncer` CR that we are going to create, + +```yaml +apiVersion: kubedb.com/v1 +kind: PgBouncer +metadata: + name: pb + namespace: demo +spec: + replicas: 1 + version: "1.18.0" + database: + syncUsers: true + databaseName: "postgres" + databaseRef: + name: "ha-postgres" + namespace: demo + connectionPool: + poolMode: session + port: 5432 + reservePoolSize: 5 + maxClientConnections: 87 + defaultPoolSize: 2 + minPoolSize: 1 + authType: md5 + deletionPolicy: WipeOut +``` + +Let's create the `PgBouncer` CR we have shown above, + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure-tls/pb.yaml +pgbouncer.kubedb.com/pb created +``` + +Now, wait until `pb` has status `Ready`. i.e, + +```bash +$ kubectl get pb -n demo +NAME VERSION STATUS AGE +pb 1.18.0 Ready 131m + +$ kubectl dba describe pgbouncer pb -n demo +Name: pb +Namespace: demo +Labels: +Annotations: +API Version: kubedb.com/v1 +Kind: PgBouncer +Metadata: + Creation Timestamp: 2025-01-25T09:21:57Z + Finalizers: + kubedb.com + Generation: 2 + Resource Version: 157918 + UID: d3635680-b216-47db-8e4f-aac7e42f196c +Spec: + Auth Secret: + Name: pb-auth + Auto Ops: + Connection Pool: + Auth Type: md5 + Default Pool Size: 2 + Max Client Connections: 87 + Min Pool Size: 1 + Pool Mode: session + Port: 5432 + Reserve Pool Size: 5 + Database: + Database Name: postgres + Database Ref: + Name: ha-postgres + Namespace: demo + Sync Users: true + Deletion Policy: WipeOut + Health Checker: + Failure Threshold: 1 + Period Seconds: 10 + Timeout Seconds: 10 + Pod Template: + Controller: + Metadata: + Spec: + Containers: + Name: pgbouncer + Resources: + Limits: + Memory: 1Gi + Requests: + Cpu: 500m + Memory: 1Gi + Security Context: + Privileged: false + Run As Group: 70 + Run As User: 70 + Pod Placement Policy: + Name: default + Security Context: + Fs Group: 70 + Run As Group: 70 + Run As User: 70 + Service Account Name: pb + Replicas: 1 + Ssl Mode: disable + Version: 1.18.0 +Status: + Conditions: + Last Transition Time: 2025-01-25T09:22:17Z + Message: The KubeDB operator has started the provisioning of PgBouncer: demo/pb + Reason: DatabaseProvisioningStartedSuccessfully + Status: True + Type: ProvisioningStarted + Last Transition Time: 2025-01-25T09:22:29Z + Message: All desired replicas are ready. + Reason: AllReplicasReady + Status: True + Type: ReplicaReady + Last Transition Time: 2025-01-25T09:22:49Z + Message: pgBouncer demo/pb is accepting connection + Observed Generation: 2 + Reason: AcceptingConnection + Status: True + Type: AcceptingConnection + Last Transition Time: 2025-01-25T09:22:49Z + Message: pgBouncer demo/pb is ready + Observed Generation: 2 + Reason: AllReplicasReady + Status: True + Type: Ready + Last Transition Time: 2025-01-25T09:23:01Z + Message: The PgBouncer: demo/pb is successfully provisioned. + Observed Generation: 2 + Reason: DatabaseSuccessfullyProvisioned + Status: True + Type: Provisioned + Observed Generation: 2 + Phase: Ready +Events: +``` + +Now, we can verify that the TLS is disabled. + +$ kubectl exec -it -n demo pb-0 -- /bin/sh +cat /etc/config/pgbouncer.ini +[databases] +postgres= host=ha-postgres.demo.svc port=5432 dbname=postgres + +[pgbouncer] +max_client_conn = 87 +min_pool_size = 1 +reserve_pool_size = 5 +max_user_connections = 2 +listen_addr = * +admin_users = pgbouncer +pool_mode = session +reserve_pool_timeout = 5 +max_db_connections = 1 +logfile = /tmp/pgbouncer.log +auth_file = /var/run/pgbouncer/secret/userlist +listen_port = 5432 +default_pool_size = 2 +stats_period = 60 +pidfile = /tmp/pgbouncer.pid +auth_type = md5 +ignore_startup_parameters = extra_float_digits +``` +Here we can see `client_tls_sslmode` is not present. That means it is by default in `disable` mode. + +### Create Issuer/ ClusterIssuer + +Now, We are going to create an example `Issuer` that will be used to enable SSL/TLS in PgBouncer. Alternatively, you can follow this [cert-manager tutorial](https://cert-manager.io/docs/configuration/ca/) to create your own `Issuer`. + +- Start off by generating a ca certificates using openssl. + +```bash +$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=pgbouncer/O=kubedb" +Generating a RSA private key +................+++++ +........................+++++ +writing new private key to './ca.key' +----- +``` + +- Now we are going to create a ca-secret using the certificate files that we have just generated. + +```bash +$ kubectl create secret tls pgbouncer-ca \ + --cert=ca.crt \ + --key=ca.key \ + --namespace=demo +secret/pgbouncer-ca created +``` + +Now, Let's create an `Issuer` using the `pgbouncer-ca` secret that we have just created. The `YAML` file looks like this: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: pb-issuer + namespace: demo +spec: + ca: + secretName: pgbouncer-ca +``` + +Let's apply the `YAML` file: + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure-tls/issuer.yaml +issuer.cert-manager.io/pb-issuer created +``` + +```bash +$ kubectl get issuer -n demo +NAME READY AGE +pb-issuer True 30s +``` +Issuer is ready(true). + +### Create PgBouncerOpsRequest + +In order to add TLS to the database, we have to create a `PgBouncerOpsRequest` CRO with our created issuer. Below is the YAML of the `PgBouncerOpsRequest` CRO that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: PgBouncerOpsRequest +metadata: + name: add-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: pb + tls: + sslMode: verify-full + clientAuthMode: md5 + issuerRef: + name: pb-issuer + kind: Issuer + apiGroup: "cert-manager.io" + certificates: + - alias: client + subject: + organizations: + - pgbouncer + organizationalUnits: + - client + apply: Always +``` +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `pb` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.issuerRef` specifies the issuer name, kind and api group. +- `spec.tls.certificates` specifies the certificates. + +Let's create the `PgBouncerOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure-tls/add-tls.yaml +pgbounceropsrequest.ops.kubedb.com/add-tls created +``` + +#### Verify TLS Enabled Successfully + +Let's wait for `PgBouncerOpsRequest` to be `Successful`. Run the following command to watch `PgBouncerOpsRequest` CRO, + +```bash +$ kubectl get pbops -n demo add-tls +NAME TYPE STATUS AGE +add-tls ReconfigureTLS Successful 2m27s +``` + +We can see from the above output that the `PgBouncerOpsRequest` has succeeded. + +Now, Let's exec into a database primary pods to see if certificates are added there. +```bash +$ kubectl exec -it -n demo pb-0 -- /bin/sh +/ $ cat /etc/config/pgbouncer.ini +[databases] +postgres= host=ha-postgres.demo.svc port=5432 dbname=postgres + +[pgbouncer] +max_db_connections = 1 +max_user_connections = 2 +auth_type = md5 +ignore_startup_parameters = extra_float_digits +pidfile = /tmp/pgbouncer.pid +auth_file = /var/run/pgbouncer/secret/userlist +min_pool_size = 1 +stats_period = 60 +client_tls_cert_file = /var/run/pgbouncer/tls/serving/server/tls.crt +reserve_pool_timeout = 5 +pool_mode = session +max_client_conn = 87 +logfile = /tmp/pgbouncer.log +listen_addr = * +client_tls_sslmode = verify-full +admin_users = pgbouncer +listen_port = 5432 +reserve_pool_size = 5 +client_tls_ca_file = /var/run/pgbouncer/tls/serving/server/ca.crt +client_tls_key_file = /var/run/pgbouncer/tls/serving/server/tls.key +default_pool_size = 2 +``` +Here we can see the presence of `client_tls_sslmode`, `client_tls_cert_file`, `client_tls_ca_file` and `client_tls_key_file`. + +## Rotate Certificate + +Now we are going to rotate the certificate of this database. First let's check the current expiration date of the certificate. + +```bash +kubectl get secrets -n demo pb-client-cert -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -dates +notBefore=Jan 25 11:39:53 2025 GMT +notAfter=Jan 25 11:39:53 2026 GMT +``` + +So, the certificate will expire on this time `Jan 25 11:39:53 2026 GMT`. + +### Create PgBouncerOpsRequest + +Now we are going to increase it using a PgBouncerOpsRequest. Below is the yaml of the ops request that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: PgBouncerOpsRequest +metadata: + name: rotate-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: pb + tls: + rotateCertificates: true + +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `pb` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.rotateCertificates` specifies that we want to rotate the certificate of this database. + +Let's create the `PgBouncerOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure-tls/rotate-tls.yaml +pgbounceropsrequest.ops.kubedb.com/rotate-tls created +``` + +#### Verify Certificate Rotated Successfully + +Let's wait for `PgBouncerOpsRequest` to be `Successful`. Run the following command to watch `PgBouncerOpsRequest` CRO, + +```bash +$ kubectl get pbops -n demo rotate-tls +NAME TYPE STATUS AGE +rotate-tls ReconfigureTLS Successful 109s +``` + +We can see from the above output that the `PgBouncerOpsRequest` has succeeded. And we can check that the tls.crt has been updated. +```bash +$ kubectl get secrets -n demo pb-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +notBefore=Jan 25 11:53:14 2025 GMT +notAfter=Apr 25 11:53:14 2025 GMT + +$ kubectl get secrets -n demo pb-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +notBefore=Jan 25 11:53:14 2025 GMT +notAfter=Apr 25 11:53:14 2025 GMT +``` + + +As we can see from the above output, the certificate has been rotated successfully. + +## Change Issuer/ClusterIssuer + +Now, we are going to change the issuer of this database. + +- Let's create a new ca certificate and key using a different subject `CN=ca-update,O=kubedb-updated`. + +```bash +$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=pgbouncer/O=kubedb-updated" +........+....+.....+...+....+...+..+.+...+..+...+............+....+.........+..+.......+.....+..........+..+.+...+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+..+.............+......+...........+....+.....+....+........+....+...+...+..+.......+......+..+.+.....+.+...+..+......+....+...........+.......+...+.........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+...........+.......+...+.....+....+..+.+..+............+.........+.+......+.........+......+.....+............+............+...+.+..+....+...+........+...+.+......+.........+........+.+..+...+.......+........+.+...........+...+....+..+...............+..........+...........+...+.+.....+.+...+............+...+...........+......+.......+...+...+..+............+..........+............+.........+.....+.+.....+....+...........+.+..+.+............+........+.......+........+......+..................+.......+........+...+...+....+..................+..+.......+...+........+....+.....+....+.........+...+...+......+...+..+..............................+...+......+......+.............+...+..+......+....+..+.........+............+....+...+........+...+.+........+.......+.....+...+......+..........+..+.......+.....+..........+...+........+....+..+.+..............+.............+...+..+..........+..+...................+..+...+.+...+...........+.+...+...........+................+..............+.........+......+....+..+..........+.....+.+..+...+....+.....+......+....+.........+..+...+....+......+..............+...+...+.+...........+...+.......+..+.+...........+...+.+.....+.+...+...+..............................+...+......+..............+.+........+.+....................+......+.........+.+...........+....+.....+......+.......+...+..+.+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +...........+.......+.....+...+....+..+...................+..+....+...+...+...+..+...+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+......+..+...+....+..+.+.........+...+......+..+.......+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.............+.......+...............+...+...........+...+.+............+........+.........+.............+..+...+....+.....+................+...+..+...+.......+..+..........+.....+...+.............+..+...+.+..............+.+......+...+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +``` + +- Now we are going to create a new ca-secret using the certificate files that we have just generated. + +```bash +$ kubectl create secret tls pgbouncer-new-ca \ + --cert=ca.crt \ + --key=ca.key \ + --namespace=demo +secret/pgbouncer-new-ca created +``` + +Now, Let's create a new `Issuer` using the `pgbouncer-new-ca` secret that we have just created. The `YAML` file looks like this: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: pb-new-issuer + namespace: demo +spec: + ca: + secretName: pgbouncer-new-ca +``` + +Let's apply the `YAML` file: + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure-tls/new-issuer.yaml +issuer.cert-manager.io/pb-new-issuer created +``` + +### Create PgBouncerOpsRequest + +In order to use the new issuer to issue new certificates, we have to create a `PgBouncerOpsRequest` CRO with the newly created issuer. Below is the YAML of the `PgBouncerOpsRequest` CRO that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: PgBouncerOpsRequest +metadata: + name: change-issuer + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: pb + tls: + issuerRef: + name: pb-new-issuer + kind: Issuer + apiGroup: "cert-manager.io" +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `pb` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.issuerRef` specifies the issuer name, kind and api group. + +Let's create the `PgBouncerOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure-tls/change-issuer.yaml +pgbounceropsrequest.ops.kubedb.com/change-issuer created +``` + +#### Verify Issuer is changed successfully + +Let's wait for `PgBouncerOpsRequest` to be `Successful`. Run the following command to watch `PgBouncerOpsRequest` CRO, + +```bash +$ kubectl get pbops -n demo change-issuer +NAME TYPE STATUS AGE +change-issuer ReconfigureTLS Successful 104s +``` + +We can see from the above output that the `PgBouncerOpsRequest` has succeeded. + +Now, Let's exec into a database node and find out the ca subject to see if it matches the one we have provided. + +```bash +$ kubectl get secrets -n demo pb-client-cert -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -subject +subject=CN = pgbouncer, O = kubedb-updated + +$ kubectl get secrets -n demo pb-server-cert -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -subject +subject=CN = pgbouncer, O = kubedb-updated +``` +Now you can check [here](https://certlogik.com/decoder/). + +We can see from the above output that, the subject name matches the subject name of the new ca certificate that we have created. So, the issuer is changed successfully. + + +## Remove TLS from the Database + +Now, we are going to remove TLS from this database using a PgBouncerOpsRequest. + +### Create PgBouncerOpsRequest + +Below is the YAML of the `PgBouncerOpsRequest` CRO that we are going to create, + +```yaml +apiVersion: ops.kubedb.com/v1alpha1 +kind: PgBouncerOpsRequest +metadata: + name: remove-tls + namespace: demo +spec: + type: ReconfigureTLS + databaseRef: + name: pb + tls: + clientAuthMode: md5 + remove: true + timeout: 5m + apply: IfReady +``` + +Here, + +- `spec.databaseRef.name` specifies that we are performing reconfigure TLS operation on `pb` database. +- `spec.type` specifies that we are performing `ReconfigureTLS` on our database. +- `spec.tls.remove` specifies that we want to remove tls from this database. +- `spec.tls.clientAuthMode` defines clientAuthentication mode after removing tls. Possible values are `md5` `scram`. + + +Let's create the `PgBouncerOpsRequest` CR we have shown above, + +```bash +$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure-tls/remove-tls.yaml +pgbounceropsrequest.ops.kubedb.com/remove-tls created +``` + +#### Verify TLS Removed Successfully + +Let's wait for `PgBouncerOpsRequest` to be `Successful`. Run the following command to watch `PgBouncerOpsRequest` CRO, + +```bash +$ kubectl get pbops -n demo remove-tls +NAME TYPE STATUS AGE +remove-tls ReconfigureTLS Successful 104s +``` + +Now first verify if this works in config. + +```bash +kubectl exec -it -n demo pb-0 -- /bin/sh +/ $ cat etc/config/pgbouncer.ini +[databases] +postgres= host=ha-postgres.demo.svc port=5432 dbname=postgres + +[pgbouncer] +max_db_connections = 1 +max_user_connections = 2 +pidfile = /tmp/pgbouncer.pid +logfile = /tmp/pgbouncer.log +listen_port = 5432 +pool_mode = session +max_client_conn = 87 +min_pool_size = 1 +default_pool_size = 2 +reserve_pool_size = 5 +admin_users = pgbouncer +listen_addr = * +auth_file = /var/run/pgbouncer/secret/userlist +reserve_pool_timeout = 5 +stats_period = 60 +auth_type = md5 +ignore_startup_parameters = extra_float_digits +``` + +SSL is off now. + +## Cleaning up + +To cleanup the Kubernetes resources created by this tutorial, run: + +```bash +kubectl delete pgbouncer -n demo pb +kubectl delete issuer -n demo pb-issuer pb-new-issuer +kubectl delete pgbounceropsrequest add-tls remove-tls rotate-tls change-issuer +kubectl delete ns demo +``` + +## Next Steps + +- Detail concepts of [PgBouncer object](/docs/guides/pgbouncer/concepts/pgbouncer.md). +- Monitor your PgBouncer database with KubeDB using [out-of-the-box Prometheus operator](/docs/guides/pgbouncer/monitoring/using-prometheus-operator.md). +- Monitor your PgBouncer database with KubeDB using [out-of-the-box builtin-Prometheus](/docs/guides/pgbouncer/monitoring/using-builtin-prometheus.md). +- Use [private Docker registry](/docs/guides/pgbouncer/private-registry/using-private-registry.md) to deploy PgBouncer with KubeDB. +- Use [kubedb cli](/docs/guides/pgbouncer/cli/cli.md) to manage databases like kubectl for Kubernetes. +- Detail concepts of [PgBouncer object](/docs/guides/pgbouncer/concepts/pgbouncer.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/pgbouncer/tls/_index.md b/docs/guides/pgbouncer/tls/_index.md new file mode 100755 index 000000000..a5aca0c89 --- /dev/null +++ b/docs/guides/pgbouncer/tls/_index.md @@ -0,0 +1,10 @@ +--- +title: Run PGBouncer with TLS +menu: + docs_{{ .version }}: + identifier: pb-tls + name: TLS/SSL Encryption + parent: pb-pgbouncer-guides + weight: 45 +menu_name: docs_{{ .version }} +--- diff --git a/docs/guides/pgbouncer/tls/configure_ssl.md b/docs/guides/pgbouncer/tls/configure_ssl.md new file mode 100644 index 000000000..d0ef41752 --- /dev/null +++ b/docs/guides/pgbouncer/tls/configure_ssl.md @@ -0,0 +1,324 @@ +--- +title: PgBouncer TLS/SSL Encryption +menu: + docs_{{ .version }}: + identifier: pb-tls-configure + name: PgBouncer_SSL + parent: pb-tls + weight: 20 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# Run PgBouncer with TLS/SSL (Transport Encryption) + +KubeDB supports providing TLS/SSL encryption (via, `sslMode` and `connectionPool.authType`) for PgBouncer. This tutorial will show you how to use KubeDB to run a PgBouncer database with TLS/SSL encryption. + +## Before You Begin + +- At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). + +- Install [`cert-manger`](https://cert-manager.io/docs/installation/) v1.0.0 or later to your cluster to manage your SSL/TLS certificates. + +- Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps [here](/docs/setup/README.md). + +- To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. + + ```bash + $ kubectl create ns demo + namespace/demo created + ``` + +> Note: YAML files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). + +## Overview + +KubeDB uses following crd fields to enable SSL/TLS encryption in PgBouncer. + +- `spec:` + - `sslMode` + - `tls:` + - `issuerRef` + - `certificate` + - `connectionPool` + - `authType` + +Read about the fields in details in [pgbouncer concept](/docs/guides/pgbouncer/concepts/pgbouncer.md), + +`sslMode` enables TLS/SSL or mixed TLS/SSL used for all network connections. The value of `sslMode` field can be one of the following: + +| Value | Description | +|:-------------:|:--------------------------------------------------------------------------------------------------------------------------------------------| +| `disabled` | The server does not use TLS/SSL. | +| `allow` | If client requests TLS, it is used. If not, plain TCP is used. If the client presents a client certificate, it is not validated. | +| `prefer` | Same as allow. | +| `require` | Client must use TLS. If not, the client connection is rejected. If the client presents a client certificate, it is not validated. | +| `verify-ca` | Client must use TLS with valid client certificate. | +| `verify-full` | Same as verify-ca. | + +The specified ssl mode will be used by health checker and exporter of PgBouncer. + +The value of `connectionPool.authType` field can be one of the following: + +| Value | Description | +|:---------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `scram-sha-256` | The server uses scram-sha-256 authentication method to authenticate the users. | +| `md5` | The server uses md5 authentication method to authenticate the users. | + +The `userlist.txt` of PgBouncer will have the configuration based on the specified AuthType. + +When, SSLMode is anything other than `disabled`, users must specify the `tls.issuerRef` field. KubeDB uses the `issuer` or `clusterIssuer` referenced in the `tls.issuerRef` field, and the certificate specs provided in `tls.certificate` to generate certificate secrets. These certificate secrets are then used to generate required certificates including `ca.pem`, `tls.crt` and `tls.key`. + +## Create Issuer/ ClusterIssuer + +We are going to create an example `Issuer` that will be used throughout the duration of this tutorial to enable SSL/TLS in PgBouncer. Alternatively, you can follow this [cert-manager tutorial](https://cert-manager.io/docs/configuration/ca/) to create your own `Issuer`. + +- Start off by generating you ca certificates using openssl. + +```bash +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=pgbouncer/O=kubedb" +``` + +- Now create a ca-secret using the certificate files you have just generated. + +```bash +kubectl create secret tls pgbouncer-ca \ + --cert=ca.crt \ + --key=ca.key \ + --namespace=demo +``` + +Now, create an `Issuer` using the `ca-secret` you have just created. The `YAML` file looks like this: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: pgbouncer-ca-issuer + namespace: demo +spec: + ca: + secretName: pgbouncer-ca +``` + +Apply the `YAML` file: + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/tls/issuer.yaml +issuer.cert-manager.io/pgbouncer-ca-issuer created +``` + +## Prepare Postgres +Prepare a KubeDB Postgres cluster using this [tutorial](/docs/guides/postgres/clustering/streaming_replication.md), or you can use any externally managed postgres but in that case you need to create an [appbinding](/docs/guides/pgbouncer/concepts/appbinding.md) yourself. In this tutorial we will use 3 node Postgres cluster named `ha-postgres`. + +## TLS/SSL encryption in PgBouncer + +Below is the YAML for PgBouncer with TLS enabled: + +```yaml +apiVersion: kubedb.com/v1 +kind: PgBouncer +metadata: + name: pb-tls + namespace: demo +spec: + replicas: 1 + version: "1.18.0" + database: + syncUsers: true + databaseName: "postgres" + databaseRef: + name: "pg" + namespace: demo + connectionPool: + poolMode: session + port: 5432 + reservePoolSize: 5 + maxClientConnections: 87 + defaultPoolSize: 2 + minPoolSize: 1 + authType: md5 + deletionPolicy: WipeOut + sslMode: verify-ca + tls: + issuerRef: + apiGroup: cert-manager.io + name: pb-ca-issuer + kind: Issuer + certificates: + - alias: server + subject: + organizations: + - kubedb:server + dnsNames: + - localhost + ipAddresses: + - "127.0.0.1" +``` + +### Deploy PgBouncer + +```bash +$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/tls/pgbouncer-ssl.yaml +pgbouncer.kubedb.com/pb-tls created +``` + +Now, wait until `pb-tls created` has status `Ready`. i.e, + +```bash +$ watch kubectl get pb -n demo +Every 2.0s: kubectl get pgbouncer -n demo +NAME VERSION STATUS AGE +pb-tls 1.18.0 Ready 108s +``` + +### Verify TLS/SSL in PgBouncer + +Now, connect to this database through [psql](https://www.postgresql.org/docs/current/app-psql.html) and verify if `SSLMode` has been set up as intended (i.e, `require`). + +```bash +$ kubectl describe secret -n demo pb-tls-client-cert +Name: pb-tls-client-cert +Namespace: demo +Labels: app.kubernetes.io/component=connection-pooler + app.kubernetes.io/instance=pb-tls + app.kubernetes.io/managed-by=kubedb.com + app.kubernetes.io/name=pgbouncers.kubedb.com + controller.cert-manager.io/fao=true +Annotations: cert-manager.io/alt-names: + cert-manager.io/certificate-name: pb-tls-client-cert + cert-manager.io/common-name: pgbouncer + cert-manager.io/ip-sans: + cert-manager.io/issuer-group: cert-manager.io + cert-manager.io/issuer-kind: Issuer + cert-manager.io/issuer-name: pb-ca-issuer + cert-manager.io/uri-sans: + +Type: kubernetes.io/tls + +Data +==== +ca.crt: 1159 bytes +tls.crt: 1135 bytes +tls.key: 1679 bytes +``` + +Now, Lets save the client cert and key to two different files: + +```bash +$ kubectl get secrets -n demo pb-tls-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt +$ cat client.crt +-----BEGIN CERTIFICATE----- +MIIDGTCCAgGgAwIBAgIQFzXjq6IExD5sjF7FW44NzTANBgkqhkiG9w0BAQsFADAl +MRIwEAYDVQQDDAlwZ2JvdW5jZXIxDzANBgNVBAoMBmt1YmVkYjAeFw0yNTAxMjMx +MDQ2MDBaFw0yNTA0MjMxMDQ2MDBaMBQxEjAQBgNVBAMTCXBnYm91bmNlcjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANtr22zMM8A0k7tsPvXICpNWUAfW +1xqDrEv5dsHP04Pd8YwioCP6lrDSahV8jkFhI4jrLCy4RYYhC8nzf3QLTkYIPTEd +PfYaS9jTfNPgGHMD8hSKFfO+gXSidg+PzUW2x8/hA8SFq9rJwn3/b39DVL71E4aU +D8aJYPc51LsIr2JoiGb0qPNSPpud/4bma1GcqCgsChkMLzsn88vOg0B9a74RUSKd +W78I37N2xNUwS5M7mgNmpzKVIhBfs0h01F6vfTVzOwOl/C9as1uQGDCIRBx6ONyl +7r1SJCENuEEr4Q33iTmBLRBwy5HKGy+UHc58DZ1lLwBaJsQdujUcbEoRrbMCAwEA +AaNWMFQwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAwGA1Ud +EwEB/wQCMAAwHwYDVR0jBBgwFoAUfEEIxgLcuBXzCYzm48qnmkbxZvIwDQYJKoZI +hvcNAQELBQADggEBAAkFInhE2W8bVbuRM+PESMNDff3cfgH8bzi9A+iWDR0XmpBm +qLqq8zciebGmuqH8PLQr518U6dCI9g0iATfV/WQ6JlRFhxiO3h+7rAjwW77V49QM +06CkL2uSRk0GeO9a/VNXMmcNZGARgG+m7gYZJ/sOVnzlj5zEchfaH82FY5HnInRl +coSL5sY28QU1iS0bO3wHoFx6t8gzwluP/H040ImS60CE5t/b3njIgfWDHzhDOkKV +Rl66yC3j2YD8+Dvdl63Dp8r5KtWDvGAkiM8SVysASHnKAM/ipEqUoqyWBUT7gG/L +JbiZCRCTnewRU9/mzcn9FxxmAPt7yq9IEND1cMQ= +-----END CERTIFICATE----- +$ kubectl get secrets -n demo pb-tls-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key +$ cat client.key +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA22vbbMwzwDSTu2w+9cgKk1ZQB9bXGoOsS/l2wc/Tg93xjCKg +I/qWsNJqFXyOQWEjiOssLLhFhiELyfN/dAtORgg9MR099hpL2NN80+AYcwPyFIoV +876BdKJ2D4/NRbbHz+EDxIWr2snCff9vf0NUvvUThpQPxolg9znUuwivYmiIZvSo +81I+m53/huZrUZyoKCwKGQwvOyfzy86DQH1rvhFRIp1bvwjfs3bE1TBLkzuaA2an +MpUiEF+zSHTUXq99NXM7A6X8L1qzW5AYMIhEHHo43KXuvVIkIQ24QSvhDfeJOYEt +EHDLkcobL5QdznwNnWUvAFomxB26NRxsShGtswIDAQABAoIBAQCXOLNmPSnhapry +TbzqiS54ssC/VlqzJFJnngsxsbjVpe2mJer2QOr//FQucMRd3MOvxlyQiYMo2LeW +PGH3qR8N9vmtUrj0VtU1HzRllYlkIzEA5NYSQZZYuurg+LuBM2JsK2j8VR/Gzsxj +J9tA+zd5z8/gLUTeEKoqWMn7CRZOm/OhorKM2PnduniazZjF9w9PZwSUlIjJnBNi +rx21RvVUw7UGCw/5jVvsDENSAkt/RHAQySu3Zzbk+gbpyhq2VIa/SADhKO9BgjxG +EQxWNQbi8anmVtSneGngfeY/OOnlyahsdzuQ9l53Iz/o511897TePDgvz6mmGxhS +4ht1QWk5AoGBAPThrun/G26f/GUxQN5QTywj926UBqpmfiCHaIoP/UM2M7Kck8Um +bgmZu2M9FvSErmmvi/KYHUJlY9yGRHX+8TqP8RVxHi0MxaPjCq0Jv/IRcSM15qVl +IoIbGPtAQrXNe1crLTeJboQ5mY20ekzkj1q9KYWWC/0Jc/Xj5kcIdO1vAoGBAOVi +PkTanAN7lMfBVEDk2dpcZTzf17WM//LGsZ1G/KTFjHq7hNMHakhla2CbPEkCOt9l +HgUOKqROsFf8lyWNIUnllEhyHfoBFRweplub2Zh3Y/JkQONA3MohKbkO28ZvDJDg +5AZB/eaTB36URqEr6hHdI037MwACZxOSKxjRp+n9AoGAZceTcrBUT4NxXQG+q2gH +sBn20l/18UcOLyj4m0GQCypxDFCl3nBdleHuj42ph9HJyCVtblQo/Rq1CchIlh5z +VtrS4g2U9DZ1wusv2cHOpKb5NiBGEAJb+GWY2XzY/UU9eXp5nbaiV5S1LL+RgXoR +1y3+HwbBTtdp+g5R/L4YE0MCgYBqxBeHpNkJJfRSJcI5kkt0P50/gFC+yCo5rhHt +yqS9bNW+KpngP4tQtyQLizW8JbWRVVdrsvRWFeouifswF0hvRNSIA9XAD9DrjbiQ +2zGkra1vnQo2vHIIAveQk0HoUrfel06LOxwavkS2vf1B91azieJs4YcTcgrYKSi2 +HJ+zYQKBgQCKfewbwVLuexdW6yLrxwXuMAZljtHUQWe7Txx3k+bw+kAF46NEBlN2 +bZc0zaz8cEn8d7GWVGGGulZA7XxZM+Tr3uD1t/8AkiS/GwRKcXBOjzQZS08bnTVJ +BwIhO4g2OiLojS6dQxrXtj/miB3pTZbVed7QhYOBUGEFs3lUV+KEVQ== +``` + +Now, if you see the common name of the client.crt you can see, +```bash +$ openssl x509 -in client.crt -inform PEM -subject -nameopt RFC2253 -noout +subject=CN=pgbouncer +``` +Here common name of the client certificate is important if you want to connect with the client certificate, the `username must match the common name of the certificate`. Here, we can see the common name(CN) is, `pgbouncer`. So, we will use pgbouncer user to connect with PgBouncer. + +Now, we can connect using `subject=CN=pgbouncer` to connect to the psql, + +```bash +$ psql "sslmode=require port=9999 host=localhost dbname=pgbouncer user=pgbouncer sslrootcert=ca.crt sslcert=client.crt sslkey=client.key" +psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 16.1) +SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off) +Type "help" for help. + +pgbouncer=# +``` + +We are connected to the pgbouncer database. Let's run some command to verify the sslMode and the user, + +```bash +pgbouncer=# SHOW SERVERS; +type | user | database | state | addr | port | local_addr | local_port | connect_time | request_time | wait | wait_us | close_needed | ptr | link | remote_pid | tls | application_name +------+----------+----------+-------+---------------+------+------------+------------+-------------------------+-------------------------+------+---------+--------------+----------------+------+------------+-----+------------------ + S | postgres | postgres | idle | 10.96.125.227 | 5432 | 10.244.0.6 | 57524 | 2025-01-24 05:17:47 UTC | 2025-01-24 06:06:07 UTC | 0 | 0 | 0 | 0x70872bea80a0 | | 476 | | +(1 row) +~ +~ +(END) +pgbouncer=# exit +⏎ +``` + +## Changing the SSLMode & ClusterAuthMode + +User can update `sslMode` & `connectionPool.authType` if needed. Some changes may be invalid from pgbouncer end, like using `sslMode: disabled` with `connectionPool.authType: cert`. + +The good thing is, **KubeDB operator will throw error for invalid SSL specs while creating/updating the PgBouncer object.** i.e., + +```bash +$ kubectl patch -n demo pb/pb-tls -p '{"spec":{"sslMode": "disabled"}}' --type="merge" +The PgBouncer "pb-tls" is invalid: spec.sslMode: Unsupported value: "disabled": supported values: "disable", "allow", "prefer", "require", "verify-ca", "verify-full" +``` + +> Note: There is no official support from kubedb for PgBouncer to connect wit cert mode`. + +## Cleaning up + +To clean up the Kubernetes resources created by this tutorial, run: + +```bash +kubectl delete pgbouncer -n demo pb-tls +kubectl delete issuer -n demo pb-ca-issuer +kubectl delete ns demo +``` + +## Next Steps + +- Detail concepts of [PgBouncer object](/docs/guides/pgbouncer/concepts/pgbouncer.md). +- Detail concepts of [PgBouncerVersion object](/docs/guides/pgbouncer/concepts/catalog.md). +- Monitor your PgBouncer database with KubeDB using [out-of-the-box Prometheus operator](/docs/guides/pgbouncer/monitoring/using-prometheus-operator.md). +- Monitor your PgBouncer database with KubeDB using [out-of-the-box builtin-Prometheus](/docs/guides/pgbouncer/monitoring/using-builtin-prometheus.md). +- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md). diff --git a/docs/guides/pgbouncer/tls/overview.md b/docs/guides/pgbouncer/tls/overview.md new file mode 100644 index 000000000..844ba9b66 --- /dev/null +++ b/docs/guides/pgbouncer/tls/overview.md @@ -0,0 +1,71 @@ +--- +title: PgBouncer TLS/SSL Encryption Overview +menu: + docs_{{ .version }}: + identifier: pb-tls-overview + name: Overview + parent: pb-tls + weight: 10 +menu_name: docs_{{ .version }} +section_menu_id: guides +--- + +> New to KubeDB? Please start [here](/docs/README.md). + +# PgBouncer TLS/SSL Encryption + +**Prerequisite :** To configure TLS/SSL in `PgBouncer`, `KubeDB` uses `cert-manager` to issue certificates. So first you have to make sure that the cluster has `cert-manager` installed. To install `cert-manager` in your cluster following steps [here](https://cert-manager.io/docs/installation/kubernetes/). + +To issue a certificate, the following crd of `cert-manager` is used: + +- `Issuer/ClusterIssuer`: Issuers, and ClusterIssuers represent certificate authorities (CAs) that are able to generate signed certificates by honoring certificate signing requests. All cert-manager certificates require a referenced issuer that is in a ready condition to attempt to honor the request. You can learn more details [here](https://cert-manager.io/docs/concepts/issuer/). + +- `Certificate`: `cert-manager` has the concept of Certificates that define a desired x509 certificate which will be renewed and kept up to date. You can learn more details [here](https://cert-manager.io/docs/concepts/certificate/). + +**PgBouncer CRD Specification :** + +KubeDB uses following crd fields to enable SSL/TLS encryption in `PgBouncer`. + +- `spec:` + - `sslMode` + - `tls:` + - `issuerRef` + - `certificates` + - `connectionPool` + - `authType` +Read about the fields in details from [pgbouncer concept](/docs/guides/pgbouncer/concepts/pgbouncer.md), + +When, `sslMode` is set to `require`, the users must specify the `tls.issuerRef` field. `KubeDB` uses the `issuer` or `clusterIssuer` referenced in the `tls.issuerRef` field, and the certificate specs provided in `tls.certificate` to generate certificate secrets using `Issuer/ClusterIssuers` specification. These certificates secrets including `ca.crt`, `tls.crt` and `tls.key` etc. are used to configure `PgBouncer` server, exporter etc. respectively. + +## How TLS/SSL configures in PgBouncer + +The following figure shows how `KubeDB` enterprise used to configure TLS/SSL in PgBouncer. Open the image in a new tab to see the enlarged version. + +
+Deploy PgBouncer with TLS/SSL +
Fig: Deploy PgBouncer with TLS/SSL
+
+ +Deploying PgBouncer with TLS/SSL configuration process consists of the following steps: + +1. At first, a user creates a `Issuer/ClusterIssuer` cr. + +2. Then the user creates a `PgBouncer` cr which refers to the `Issuer/ClusterIssuer` cr that the user created in the previous step. + +3. `KubeDB` Provisioner operator watches for the `PgBouncer` cr. + +4. When it finds one, it creates `Secret`, `Service`, etc. for the `PgBouncer` database. + +5. `KubeDB` Ops-manager operator watches for `PgBouncer`, `Issuer/ClusterIssuer`, `Secret` and `Service`. + +6. When it finds all the resources(`PgBouncer`, `Issuer/ClusterIssuer`, `Secret`, `Service`), it creates `Certificates` by using `tls.issuerRef` and `tls.certificates` field specification from `PgBouncer` cr. + +7. `cert-manager` watches for certificates. + +8. When it finds one, it creates certificate secrets `tls-secrets`(server, client, exporter secrets etc.) that holds the actual certificate signed by the CA. + +9. `KubeDB` Provisioner operator watches for the Certificate secrets `tls-secrets`. + +10. When it finds all the tls-secret, it creates the related `Petset` so that PgBouncer database can be configured with TLS/SSL. + +In the next doc, we are going to show a step-by-step guide on how to configure a `PgBouncer` database with TLS/SSL. \ No newline at end of file diff --git a/docs/images/day-2-operation/pgbouncer/pb-reconfigure-tls.png b/docs/images/day-2-operation/pgbouncer/pb-reconfigure-tls.png new file mode 100644 index 000000000..b9c95acd8 Binary files /dev/null and b/docs/images/day-2-operation/pgbouncer/pb-reconfigure-tls.png differ diff --git a/docs/images/day-2-operation/pgbouncer/pb-tls.svg b/docs/images/day-2-operation/pgbouncer/pb-tls.svg new file mode 100644 index 000000000..618a27a63 --- /dev/null +++ b/docs/images/day-2-operation/pgbouncer/pb-tls.svg @@ -0,0 +1,4 @@ + + + +            Enterprise            Operator              Community            Operator
service
se...
secret
se...
tls-secret
tls-secret
Cert- manager
Cert- ma...
PetSet
Statef...
Issuer/Cluster Issuer
Issuer...
PgBouncer
PgBouncer
Certificates
Certif...
User
User
2.Create
2.Create
1.Create
1.Create
5a.Watch
5a.Watch
3.Watch
3.Watch
4.Create
4.Create
5c.Watch
5c.Watch
6.Create
6.Create
7.Watch
7.Watch
uses
uses
8.Create
8.Create
9.Watch
9.Watch
10.Create
10.Create
5b.Watch
5b.Watch
refers to
refers to
Text is not SVG - cannot display
\ No newline at end of file