* moves KMS type from StorageClass into KMS configuration itself * updates omapval used to identify KMS to only it's ID without the type why? 1. when using multiple KMS configurations (not currently supported) automated parsing of kms configuration will be failing because some entries in configs won't comply with the requested type 2. less options are needed in the StorageClass and less data used to identify the KMS Signed-off-by: Vasyl Purchel vasyl.purchel@workday.com Signed-off-by: Andrea Baglioni andrea.baglioni@workday.com
4.3 KiB
Encrypted Persistent Volume Claims
Proposal
Subject of this proposal is to add support for encryption of RBD volumes in Ceph-CSI.
Some but not all the benefits of this approach:
- guarantee encryption in transit to rbd without using messenger v2
- extra security layer to application with special regulatory needs
- at rest encryption can be disabled to selectively allow encryption only where required
Document Terminology
- volume encryption: encryption of a volume attached by rbd
- encryption at rest: encryption of physical disk done by ceph
- LUKS: Linux Unified Key Setup: stores all of the needed setup information for dm-crypt on the disk
- dm-crypt: linux kernel device-mapper crypto target
- cryptsetup: the command line tool to interface with dm-crypt
Proposed Solution
The proposed solution in this document, is to address the volume encryption requirement by using dm-crypt module through cryptsetup cli interface.
Implementation Summary
-
Encryption is implemented using cryptsetup with LUKS extension. A good introduction to LUKS and dm-crypt in general can be found here Functions to implement necessary interaction are implemented in a separate
cryptsetup.go
file.- LuksFormat
- LuksOpen
- LuksClose
- LuksStatus
-
CreateVolume
: refactored to prepare for encryption (tag image that it requires encryption later), before returning, if encrypted volume option is set. -
NodeStageVolume
: refactored to callencryptDevice
method on the very first volume attach request -
NodeStageVolume
: refactored to open encrypted device (openEncryptedDevice
) -
openEncryptedDevice
: looks up for a passphrase matching the volume id, returns the new device path in the form:/dev/mapper/luks-<volume_id>
. On the woker node where the attach is scheduled:$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 10G 0 disk └─sda1 8:1 0 10G 0 part / sdb 8:16 0 20G 0 disk rbd0 253:0 0 1G 0 disk └─luks-pvc-8a710f4c934811e9 252:0 0 1020M 0 crypt /var/lib/kubelet/pods/9eaceaef-936c-11e9-b396-005056af3de0/volumes/kubernetes.io~csi/pvc-8a710f4c934811e9/mount
-
detachRBDDevice
: callsLuksClose
function to remove the LUKS mapping before detaching the volume. -
StorageClass extended with following parameters:
encrypted
("true" or "false")encryptionKMSID
(string representing kms configuration of choice) ceph-csi plugin may support different kms vendors with different type of authentication
-
New KMS Configuration created.
Annotated YAML for RBD StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd
provisioner: rbd.csi.ceph.com
parameters:
# String representing Ceph cluster configuration
clusterID: <cluster-id>
# ceph pool
pool: rbd
# RBD image features, CSI creates image with image-format 2
# CSI RBD currently supports only `layering` feature.
imageFeatures: layering
# The secrets have to contain Ceph credentials with required access
# to the 'pool'.
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace: default
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
csi.storage.k8s.io/controller-expand-secret-namespace: default
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
csi.storage.k8s.io/node-stage-secret-namespace: default
# Specify the filesystem type of the volume. If not specified,
# csi-provisioner will set default as `ext4`.
csi.storage.k8s.io/fstype: ext4
# Encrypt volumes
encrypted: "true"
# Use external key management system for encryption passphrases by specifying
# a unique ID matching KMS ConfigMap. The ID is only used for correlation to
# config map entry.
encryptionKMSID: <kms-id>
reclaimPolicy: Delete
And kms configuration:
---
apiVersion: v1
kind: ConfigMap
data:
config.json: |-
{
"<kms-id>": {
"encryptionKMSType": "kmsType",
kms specific config...
}
}
metadata:
name: ceph-csi-encryption-kms-config