From b1035dd49de81ad0d8c5a6412413f7e0511b9167 Mon Sep 17 00:00:00 2001 From: Scott Seago Date: Fri, 11 Oct 2024 12:34:44 -0400 Subject: [PATCH] add no-relabeling option to backupPVC configmap Signed-off-by: Scott Seago --- changelogs/unreleased/8288-sseago | 1 + pkg/exposer/csi_snapshot.go | 16 ++++++++++++++++ pkg/nodeagent/node_agent.go | 4 ++++ .../data-movement-backup-pvc-configuration.md | 14 ++++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 changelogs/unreleased/8288-sseago diff --git a/changelogs/unreleased/8288-sseago b/changelogs/unreleased/8288-sseago new file mode 100644 index 0000000000..fe67c45320 --- /dev/null +++ b/changelogs/unreleased/8288-sseago @@ -0,0 +1 @@ +add no-relabeling option to backupPVC configmap diff --git a/pkg/exposer/csi_snapshot.go b/pkg/exposer/csi_snapshot.go index 5bb247ebbc..d91a3be665 100644 --- a/pkg/exposer/csi_snapshot.go +++ b/pkg/exposer/csi_snapshot.go @@ -174,12 +174,20 @@ func (e *csiSnapshotExposer) Expose(ctx context.Context, ownerObject corev1.Obje // for backupPVC (intermediate PVC in snapshot data movement) object creation backupPVCStorageClass := csiExposeParam.StorageClass backupPVCReadOnly := false + spcNoRelabeling := false if value, exists := csiExposeParam.BackupPVCConfig[csiExposeParam.StorageClass]; exists { if value.StorageClass != "" { backupPVCStorageClass = value.StorageClass } backupPVCReadOnly = value.ReadOnly + if value.SPCNoRelabeling { + if backupPVCReadOnly { + spcNoRelabeling = true + } else { + curLog.WithField("vs name", volumeSnapshot.Name).Warn("Ignoring spcNoRelabling for read-write volume") + } + } } backupPVC, err := e.createBackupPVC(ctx, ownerObject, backupVS.Name, backupPVCStorageClass, csiExposeParam.AccessMode, volumeSize, backupPVCReadOnly) @@ -203,6 +211,7 @@ func (e *csiSnapshotExposer) Expose(ctx context.Context, ownerObject corev1.Obje csiExposeParam.Affinity, csiExposeParam.Resources, backupPVCReadOnly, + spcNoRelabeling, ) if err != nil { return errors.Wrap(err, "error to create backup pod") @@ -444,6 +453,7 @@ func (e *csiSnapshotExposer) createBackupPod( affinity *kube.LoadAffinity, resources corev1.ResourceRequirements, backupPVCReadOnly bool, + spcNoRelabeling bool, ) (*corev1.Pod, error) { podName := ownerObject.Name @@ -557,5 +567,11 @@ func (e *csiSnapshotExposer) createBackupPod( }, } + if spcNoRelabeling { + pod.Spec.SecurityContext.SELinuxOptions = &corev1.SELinuxOptions{ + Type: "spc_t", + } + } + return e.kubeClient.CoreV1().Pods(ownerObject.Namespace).Create(ctx, pod, metav1.CreateOptions{}) } diff --git a/pkg/nodeagent/node_agent.go b/pkg/nodeagent/node_agent.go index 8922df3921..b83efc6f47 100644 --- a/pkg/nodeagent/node_agent.go +++ b/pkg/nodeagent/node_agent.go @@ -68,6 +68,10 @@ type BackupPVC struct { // ReadOnly sets the backupPVC's access mode as read only ReadOnly bool `json:"readOnly,omitempty"` + + // SPCNoRelabeling sets Spec.SecurityContext.SELinux.Type to "spc_t" for the pod mounting the backupPVC + // ignored if ReadOnly is false + SPCNoRelabeling bool `json:"spcNoRelabeling,omitempty"` } type Configs struct { diff --git a/site/content/docs/main/data-movement-backup-pvc-configuration.md b/site/content/docs/main/data-movement-backup-pvc-configuration.md index ee4ebe1b3b..11f6d6bc7f 100644 --- a/site/content/docs/main/data-movement-backup-pvc-configuration.md +++ b/site/content/docs/main/data-movement-backup-pvc-configuration.md @@ -15,6 +15,10 @@ operation could perform better. Specifically: - Some storage providers create one or more replicas when creating a volume, the number of replicas is defined in the storage class. However, it doesn't make any sense to keep replicas when an intermediate volume used by the backup. Therefore, users should be allowed to configure another storage class specifically used by the `backupPVC`. +- In SELinux-enabled clusters, such as OpenShift, when using the above-mentioned readOnly access mode setting, SELinux relabeling of the + volume is not possible. Therefore for these clusters, when setting `readOnly` for a storage class, users must also disable relabeling. + Note that this option is not consistent with the Restricted pod security policy, so if Velero pods must run with a restricted policy, + disabling relabeling (and therefore readOnly volume mounting) is not possible. Velero introduces a new section in the node agent configuration ConfigMap (the name of this ConfigMap is passed using `--node-agent-configmap` velero server argument) called `backupPVC`, through which you can specify the following @@ -26,6 +30,10 @@ default the source PVC's storage class will be used. - `readOnly`: This is a boolean value. If set to `true` then `ReadOnlyMany` will be the only value set to the backupPVC's access modes. Otherwise `ReadWriteOnce` value will be used. +- `spcNoRelabeling`: This is a boolean value. If set to `true`, then `pod.Spec.SecurityContext.SELinuxOptions.Type` will be set to `spc_t`. From + the SELinux point of view, this will be considered a "Super Privileged Container" which means that selinux enforcement will be disabled and + volume relabeling will not occur. This field is ignored if `readOnly` is `false`. + The users can specify the ConfigMap name during velero installation by CLI: `velero install --node-agent-configmap=` @@ -43,6 +51,10 @@ A sample of `backupPVC` config as part of the ConfigMap would look like: "storage-class-3": { "readOnly": true } + "storage-class-4": { + "readOnly": true, + "spcNoRelabeling": true + } } } ``` @@ -53,5 +65,7 @@ A sample of `backupPVC` config as part of the ConfigMap would look like: - If the users are setting `readOnly` value as `true` in the `backupPVC` config then they must also make sure that the storage class that is being used for `backupPVC` should support creation of `ReadOnlyMany` PVC from a snapshot, otherwise the corresponding DataUpload CR will stay in `Accepted` phase until timeout (data movement prepare timeout value is 30m by default). +- In an SELinux-enabled cluster, any time users set `readOnly=true` they must also set `spcNoRelabeling=true`. There is no need to set `spcNoRelabeling=true` +if the volume is not readOnly. - If any of the above problems occur, then the DataUpload CR is `canceled` after timeout, and the backupPod and backupPVC will be deleted, and the backup will be marked as `PartiallyFailed`.