Data-at-rest encryption is essential for compliance with regulations that require the protection of sensitive data. Encryption can help organizations comply with regulations and avoid legal consequences and fines. It is also critical for securing sensitive data and avoiding data breaches.
PostgreSQL does not natively support Transparent Data Encryption (TDE). TDE is a database encryption technique that encrypts data at the column or table level, as opposed to full-disk encryption (FDE), which encrypts the entire database.
As for FDE, there are multiple options available for PostgreSQL. In this blog post, you will learn:
In most public clouds, block storage is not encrypted by default. To enable the encryption of the storage in Kubernetes, you need to modify the StorageClass resource. This will instruct Container Storage Interface (CSI) to provision encrypted storage volume on your block storage (AWS EBS, GCP Persistent Disk, Ceph, etc.).
The configuration of the storage class depends on your storage plugin. For example, in Google Kubernetes Engine (GKE), you need to create the key in Cloud Key Management Service (KMS) and set it in the StorageClass:
|
1 |
apiVersion: storage.k8s.io/v1beta1<br>kind: StorageClass<br>metadata:<br> name: my-enc-sc<br>provisioner: pd.csi.storage.gke.io<br>parameters:<br> type: pd-standard<br> disk-encryption-kms-key: KMS_KEY_ID |
Get KMS_KEY_ID by following the instructions in this document.
For AWS EBS, you just need to add an encrypted field; the key in AWS KMS will be generated automatically.
|
1 |
apiVersion: storage.k8s.io/v1<br>kind: StorageClass<br>metadata:<br> name: my-enc-sc<br>provisioner: kubernetes.io/aws-ebs<br>parameters:<br> encrypted: 'true'<br> fsType: ext4<br> type: gp2<br>volumeBindingMode: WaitForFirstConsumer |
Read more about storage encryption in the documentation of your cloud provider or storage project of your choice.
Once you have the StorageClass created, it is time to use it. I will use Percona Operator for PostgreSQL v2 (currently in tech preview) in my tests, but such an approach can be used with any Percona Operator.
Deploy the operator by following our installation instructions. I will use the regular kubectl way:
|
1 |
kubectl apply -f deploy/bundle.yaml --server-side |
To create the cluster with encrypted storage, you must set the correct storage class in the Custom Resource.
|
1 |
spec:<br> ...<br> instances:<br> - name: instance1<br> ...<br> dataVolumeClaimSpec:<br> storageClassName: my-enc-sc<br> accessModes:<br> - ReadWriteOnce<br> resources:<br> requests:<br> storage: 1Gi |
Apply the custom resource:
|
1 |
kubectl apply -f deploy/cr.yaml |
The cluster should be up and running, backed by encrypted storage.
This task boils down to switching from one StorageClass to another. With version two of the Operator, we have a notion of instance groups. They are absolutely fantastic for testing new configurations, including compute and storage.
|
1 |
- name: instance2<br> replicas: 2<br> dataVolumeClaimSpec:<br> storageClassName: my-enc-sc<br> accessModes:<br> - ReadWriteOnce<br> resources:<br> requests:<br> storage: 1Gi |
Now your cluster runs using encrypted storage.
It is quite interesting that PostgreSQL does not have built-in data-at-rest encryption. Peter Zaitsev wrote a blog post about it in the past – Why PostgreSQL Needs Transparent Database Encryption (TDE) – and why it is needed.
Storage-level encryption allows you to keep your data safe, but it has its limitations. The top limitations are:
Even with these limitations, encrypting the data is highly recommended. Try out our operator and let us know what you think.
The Percona Kubernetes Operators automate the creation, alteration, or deletion of members in your Percona Distribution for MySQL, MongoDB, or PostgreSQL environment.
Resources
RELATED POSTS