Set up encrypted persistent storage
This section guides you through the process of configuring encrypted persistent storage for your application.
Applicability
This step is recommended for any Contrast deployment that stores sensitive data persistently.
Prerequisites
How-to
The following demonstrates how to set up an encrypted LUKS mount for an arbitrary /mount/path
directory to easily deploy an application with encrypted persistent storage using Contrast.
Configuration
Add a volume
of type emptyDir
to your pod.
Mount it through a volumeMount
with HostToContainer
propagation.
The specified mountPath
is where the Contrast Initializer will mount the encrypted volume.
Use a volumeClaimTemplate
to make a persistent storage device available to your deployment.
The Initializer creates an encrypted volume and a filesystem on this device.
Supported volume types can be found in the k8s documentation.
Finally, add the Contrast annotation contrast.edgeless.systems/secure-pv
with value device-name:mount-name
.
The presence of this annotation instructs an init container running cryptsetup
to use the workload secret at /contrast/secrets/workload-secret-seed
to generate
a key and setup the block device as a LUKS partition. Before starting the application container,
the init container uses the generated key to open the LUKS device, which is then mounted
by the application container. For the application container, this process is completely
transparent and works like mounting any other volume. The cryptsetup
container
will remain running to provide the necessary decryption context for the workload
container.
spec: # v1.StatefulSetSpec
template:
metadata:
annotations:
contrast.edgeless.systems/secure-pv: device-name:mount-name
spec:
containers:
- volumeMounts:
- mountPath: /mount/path
mountPropagation: HostToContainer
name: mount-name
volumes:
- emptyDir: {}
name: mount-name
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: device-name
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
volumeMode: Block
Secure persistent volumes make use of workload secrets to be able to re-open devices after container restarts. Please read about the implications in the workload secrets section.
Deployment
Follow the steps of the generic workload deployment instructions:
Example application: MySQL
The above guide can be tried out with a MySQL sample deployment which is part of the contrast release. You can add the deployment file to your resources by running:
curl -fLO https://github.com/edgelesssys/contrast/releases/latest/download/mysql-demo.yml --output-dir resources
MySQL is an open-source database used to organize data into
tables and quickly retrieve information about its content. All of the data in a
MySQL database is stored in the /var/lib/mysql
directory. In this example, we
use the workload secret to setup an encrypted LUKS mount for the
/var/lib/mysql
directory to easily deploy an application with encrypted
persistent storage using Contrast.
The resources provided in this demo are designed for educational purposes and shouldn't be used in a production environment without proper evaluation. When working with persistent storage, regular backups are recommended in order to prevent data loss. For confidential applications, please also refer to the security considerations. Also be aware of the differences in security implications of the workload secrets for the data owner and the workload owner. For more details, see the Workload Secrets documentation.
The MySQL server is defined as a StatefulSet
, with a storage setup analogous to what has been described above.
A 1Gi
block device is provided to the mysql-backend
container through a volumeClaimTemplate
and mounted to /var/lib/mysql
, MySQL's default state directory.
An example MySQL client is defined through a separate deployment. The mysql-client
container connects to the backend and calls on it to perform demo database operations.
Since the backend's MySQL state directory is located on the prepared storage device, the results of these operations are persisted.
Follow the steps given above to reapply your configuration.
The deployment YAML shipped for this demo is already configured to be used with Contrast.
A runtime class contrast-cc
was added to the pods to signal they should be run as Confidential Containers. During the generation process,
the Contrast Initializer will be added as an init container to these
workloads. It will attest the pod to the Coordinator and fetch the workload certificates and the workload secret.
Further, the deployment YAML is also configured with the Contrast service mesh. The configured service mesh proxy provides transparent protection for the communication between the MySQL server and client.