NOTE: LUKS encryption allows users to bring their own keys and manage them, while BlockStorage encryption is managed by Linode and it's automatically handled on the backend.
Notes:
-
Setting Up Encryption: In the provided StorageClasses, encryption is activated by specifying
linodebs.csi.linode.com/encrypted: "true"
in theparameters
field. This signals the CSI driver to provision volumes with encryption enabled, provided encryption is supported in the specified region. -
Retention and Expansion Options:
- The
linode-block-storage-encrypted
StorageClass uses the defaultDelete
reclaim policy, meaning that volumes created with this StorageClass will be deleted when the associated PVC is deleted. - In contrast, the
linode-block-storage-retain-encrypted
StorageClass uses theRetain
policy. This allows the volume to persist even after the PVC is deleted, ensuring data is preserved until manually removed. - Both StorageClasses support volume expansion through the
allowVolumeExpansion: true
setting, allowing users to resize volumes as needed without data loss.
- The
-
Default StorageClass Annotation: By marking both StorageClasses with
storageclass.kubernetes.io/is-default-class: "true"
, they’re eligible to act as default classes. However, Kubernetes will only treat one StorageClass as the actual default. Consider applying this annotation only to the preferred default StorageClass. -
Region Compatibility: Ensure that encryption is supported in the Linode region where the volumes will be created. If encryption is not available in a specific region, the CSI driver will return an error.
- To check if the region has encryption capability visit https://techdocs.akamai.com/linode-api/reference/get-regions
- For your specific region, check the
capabilities
and see ifBlock Storage Encryption
is listed in it.
-
Usage in PersistentVolumeClaims (PVCs): Use the
storageClassName
field in a PVC to reference the desired StorageClass (linode-block-storage-encrypted
orlinode-block-storage-retain-encrypted
). Each PVC will inherit the encryption settings defined in the referenced StorageClass.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: linode-block-storage-encrypted
namespace: kube-system
parameters:
linodebs.csi.linode.com/encrypted: "true"
allowVolumeExpansion: true
provisioner: linodebs.csi.linode.com
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: linode-block-storage-retain-encrypted
namespace: kube-system
parameters:
linodebs.csi.linode.com/encrypted: "true"
allowVolumeExpansion: true
provisioner: linodebs.csi.linode.com
reclaimPolicy: Retain
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-example-pvc-encrypted
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: linode-block-storage-encrypted
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-example-pvc-encrypted-retain
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: linode-block-storage-retain-encrypted
Notes:
- Resizing: Resize is possible with similar steps to resizing PVCs on LKE and are not handled by driver. Need cryptSetup resize + resize2fs on LKE node.
- Key Rotation: Key rotation process is not handled by driver but is possible via similar steps to out of band resize operations.
- PVC Requirement: Encryption only possible on a new/empty PVC.
- Secret Handling: LUKS key is currently pulled from a native Kubernetes secret. Take note of how your cluster handles secrets in etcd. The CSI driver is careful to otherwise keep the secret on an ephemeral tmpfs mount and otherwise refuses to continue.
Tip
To use an encryption key per PVC you can make a new StorageClass/Secret combination each time.
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
annotations:
storageclass.kubernetes.io/is-default-class: "true"
name: linode-block-storage-retain-luks
namespace: kube-system
provisioner: linodebs.csi.linode.com
reclaimPolicy: Retain
parameters:
linodebs.csi.linode.com/luks-encrypted: "true"
linodebs.csi.linode.com/luks-cipher: "aes-xts-plain64"
linodebs.csi.linode.com/luks-key-size: "512"
csi.storage.k8s.io/node-stage-secret-namespace: csi-encrypt-example
csi.storage.k8s.io/node-stage-secret-name: csi-encrypt-example-luks-key
---
apiVersion: v1
kind: Secret
metadata:
name: csi-encrypt-example-luks-key
namespace: csi-encrypt-example
stringData:
luksKey: "SECRETGOESHERE"
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-example-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: linode-block-storage-retain
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-example-pvcluks
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: linode-block-storage-retain-luks