Encrypting PVCs using StorageClass with Kubernetes Secrets


Portworx Encrypted Volumes

This guide will give you an overview of how to use the encryption feature for Portworx volumes. Under the hood, Portworx uses the libgcrypt library to interface with the dm-crypt module for creating, accessing and managing encrypted devices. Portworx uses the LUKS format of dm-crypt and AES-256 as the cipher with xts-plain64 as the cipher mode.

All encrypted volumes are protected by a passphrase. Portworx uses this passphrase to encrypt the volume data at rest as well as in transit. It is recommended to store these passphrases in a secure secret store.

There are two ways in which you can provide the passphrase to Portworx:

1. Per volume secret: Use a unique secret for each encrypted volume

2. Cluster-wide secret: Use a default common secret for all encrypted volumes

Portworx has two different kinds of encrypted volumes:

  • Encrypted Volumes

Encrypted volumes are regular volumes which can be accessed from only one node.

  • Encrypted Shared Volumes

Encrypted shared volume allows access to the same encrypted volume from multiple nodes.

Using a StorageClass parameter, you can tell Portworx to encrypt all PVCs created using that StorageClass. Portworx uses a cluster wide secret to encrypt all the volumes created using the secure StorageClass.

Step 1: Create cluster wide secret key

A cluster wide secret key is a common key that points to a secret value/passphrase which can be used to encrypt all your volumes.

Create a cluster wide secret in Kubernetes, if not already created:

kubectl -n portworx create secret generic px-vol-encryption \
  --from-literal=cluster-wide-secret-key=<value>

Note that the cluster wide secret has to reside in the px-vol-encryption secret under the portworx namespace.

Now you have to give Portworx the cluster wide secret key, that acts as the default encryption key for all volumes.

PX_POD=$(kubectl get pods -l name=portworx -n kube-system -o jsonpath='{.items[0].metadata.name}')
kubectl exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl secrets set-cluster-key \
  --secret cluster-wide-secret-key

Step 2: Create a StorageClass

Create a storage class with the secure parameter set to true.

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: px-secure-sc
provisioner: kubernetes.io/portworx-volume
parameters:
  secure: "true"
  repl: "3"

To create a shared encrypted volume set the shared parameter to true as well.

Step 3: Create Persistent Volume Claim

Create a PVC that uses the above px-secure-sc storage class.

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: secure-pvc
spec:
  storageClassName: px-secure-sc
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi

Step 4: Verify the volume

Once the PVC has been created, verify the volume created in Portworx is encrypted.

PX_POD=$(kubectl get pods -l name=portworx -n kube-system -o jsonpath='{.items[0].metadata.name}')
kubectl exec $PX_POD -n kube-system -- /opt/pwx/bin/pxctl volume list
ID                 NAME                                      ...  ENCRYPTED  ...
10852605918962284  pvc-5a885584-44ca-11e8-a17b-080027ee1df7  ...  yes        ...


Last edited: Tuesday, Dec 17, 2019