Transparent Data Encryption (TDE) is a technology used by several database vendors to encrypt data at rest, meaning the database files are stored on disk. However, TDE does not encrypt data that is actively being used. TDE is available in the EDB Postgres Advanced Server and EDB Postgres Extended Server starting from version 15, and it is supported by the EDB Postgres for Kubernetes operator.
Note: TDE is available only for operands that support it: EPAS and PG Extended, versions 15 and newer.
This write-up details the process of setting up Transparent Data Encryption (TDE) in an EDB Postgres Extended (PGE) cluster within a Kubernetes environment. The steps taken, along with their results, are explained below.
The images for the EDB Postgres for Kubernetes operator, as well as various operands, are kept in private container image registries under docker.enterprisedb.com. For more information, refer to the following resources:
- Operator: EDB Postgres for Kubernetes v1.22.1
- Database: EDB Postgres Extended 15.6
We start by creating a namespace called tde
to isolate our TDE setup.
kubectl create ns tde
namespace/tde created
Next, we create a Kubernetes secret to store our TDE encryption key. This secret will be referenced in our Postgres cluster configuration.
kubectl create secret generic -o yaml tde-key --from-literal=key=PostgresRocks -n tde
Output:
apiVersion: v1
data:
key: UG9zdGdyZXNSb2Nrcw==
kind: Secret
metadata:
creationTimestamp: "2024-03-22T11:20:28Z"
name: tde-key
namespace: tde
resourceVersion: "14915"
uid: 948e7254-ea82-4355-82a8-7790c0dab1f3
type: Opaque
We define the Postgres cluster configuration in postgres-extended-tde.yaml
. Note the use of epas
to specify the EDB Postgres Advanced Server, which supports TDE.
apiVersion: postgresql.k8s.enterprisedb.io/v1
kind: Cluster
metadata:
name: cluster-tde
spec:
instances: 1
storage:
size: 1Gi
imagePullSecrets:
- name: my-secret
imageName: docker.enterprisedb.com/k8s_enterprise/edb-postgres-extended:15.6
postgresql:
epas:
tde:
enabled: true
secretKeyRef:
name: tde-key
key: key
Note: Various values for the postgresql
spec were tried, but only epas
worked in the TDE specification.
We apply the configuration to create the Postgres cluster.
kubectl apply -f postgres-extended-tde.yaml -n tde
cluster.postgresql.k8s.enterprisedb.io/cluster-tde created
We check the status of the pods to ensure the cluster is running.
kubectl get pods -n tde
Output:
NAME READY STATUS RESTARTS AGE
cluster-tde-1 1/1 Running 0 36s
We use kubectl cnp status
to get a detailed status report of the cluster.
Note: cnp plugin needs to be installed if not already, and link to the Docs
kubectl cnp status cluster-tde -n tde
Output:
Cluster Summary
Name: cluster-tde
Namespace: tde
System ID: 7349148315743027232
PostgreSQL Image: docker.enterprisedb.com/k8s_enterprise/edb-postgres-extended:15.6
Primary instance: cluster-tde-1
Primary start time: 2024-03-22 11:28:56 +0000 UTC (uptime 1m49s)
Status: Cluster in healthy state
Instances: 1
Ready instances: 1
Current Write LSN: 0/305BE98 (Timeline: 1 - WAL File: 000000010000000000000003)
Certificates Status
Certificate Name Expiration Date Days Left Until Expiration
---------------- --------------- --------------------------
cluster-tde-ca 2024-06-20 11:23:47 +0000 UTC 90.00
cluster-tde-replication 2024-06-20 11:23:47 +0000 UTC 90.00
cluster-tde-server 2024-06-20 11:23:47 +0000 UTC 90.00
Continuous Backup status
Not configured
Physical backups
No running physical backups found
Streaming Replication status
Not configured
Unmanaged Replication Slot Status
No unmanaged replication slots found
Managed roles status
No roles managed
Tablespaces status
No managed tablespaces
Instances status
Name Database Size Current LSN Replication role Status QoS Manager Version Node
---- ------------- ----------- ---------------- ------ ------
cluster-tde-1 29 MB 0/305BE98 Primary OK BestEffort 1.22.1 kind-pg4k-control-plane
We connect to the Postgres instance using kubectl cnp psql
and perform basic SQL operations to verify that the database is operational and using TDE.
kubectl cnp psql cluster-tde -n tde
psql (15.6 (EDB Postgres Extended Server 15.6.0))
Type "help" for help.
postgres=#
We then run several SQL commands to create a table, insert data, and check the physical storage to confirm encryption.
postgres=# select version();
version
-----------------------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 15.6 (EDB Postgres Extended Server 15.6.0) on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-20), 64-bit
(1 row)
postgres=# create table testtde (name varchar, id int);
CREATE TABLE
postgres=# insert into testtde values('swapnil',1);
INSERT 0 1
postgres=# select * from testtde;
name | id
---------+----
swapnil | 1
(1 row)
postgres=# select pg_relation_filepath('testtde');
pg_relation_filepath
----------------------
base/5/16394
(1 row)
To confirm that the data is encrypted on disk, we examine the file associated with the testtde
table.
kubectl exec -ti cluster-tde-1 -n tde -- bash
Once inside the container, we navigate to the data directory and use hexdump
to inspect the file contents.
[postgres@cluster-tde-1 /]$ cd /var/lib/postgresql/data/pgdata/base/5/
[postgres@cluster-tde-1 5]$ ls -lrth 16394
-rw------- 1 postgres postgres 8.0K Mar 22 11:53 16394
[postgres@cluster-tde-1 5]$ hexdump -C 16394 | grep swapnil
[postgres@cluster-tde-1 5]$ hexdump -C 16394 | tail -5
00001fc0 34 e6 28 8e 42 81 83 a3 71 9d 22 10 83 69 a9 03 |4.(.B...q."..i..|
00001fd0 70 43 fe af 7f 66 d8 cc 78 2b 1c 78 8f 9e e1 42 |pC...f..x+.x...B|
00001fe0 fd a4 38 97 b1 df 43 1e a8 18 87 90 15 50 90 58 |..8...C......P.X|
00001ff0 a1 64 2e d2 8e ff f4 a6 a8 33 20 70 4f 52 07 0c |.d.......3 pOR..|
00002000
No plain text data ("swapnil") is visible in the file, confirming that the data is encrypted.
Finally, we validate the data encryption version to confirm TDE is configured correctly across the cluster.
postgres=# select data_encryption_version from pg_control_init();
data_encryption_version
-------------------------
1
(1 row)
Through these steps, we have successfully set up and verified Transparent Data Encryption (TDE) in an EDB Postgres Extended (PGE) cluster running in a Kubernetes environment. The cluster was scaled and verified for encrypted data storage, ensuring data security both in single and multi-instance setups.