From 7bbeffc49d21913078f7fbc34e4b5df4f6ca9563 Mon Sep 17 00:00:00 2001 From: Omar Pakker Date: Fri, 12 Nov 2021 15:01:05 +0100 Subject: [PATCH] osd: set blkdevmapper capabilities The OSD blkdevmapper init container relies on the MKNOD capability, which it does not actually request. As a result, deployments fail on Kubernetes clusters that do not happen to assign this capability to all containers by default. Solve this by updating the container spec securityContext to explicitly request the capability it relies on. Closes: https://github.com/rook/rook/issues/9156 Signed-off-by: Omar Pakker (cherry picked from commit 4726d39688e116a64b6f0178b5800f6b6416ff43) --- pkg/operator/ceph/cluster/osd/spec.go | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/pkg/operator/ceph/cluster/osd/spec.go b/pkg/operator/ceph/cluster/osd/spec.go index 161f6729fd59..3075dd4ed523 100644 --- a/pkg/operator/ceph/cluster/osd/spec.go +++ b/pkg/operator/ceph/cluster/osd/spec.go @@ -856,6 +856,19 @@ func (c *Cluster) getActivateOSDInitContainer(configDir, namespace, osdID string return volume, container } +// The blockdevmapper container copies the device node file, which is regarded as a device special file. +// To be able to perform this action, the CAP_MKNOD capability is required. +// Provide a securityContext which requests the MKNOD capability for the container to function properly. +func getBlockDevMapperContext() *v1.SecurityContext { + return &v1.SecurityContext{ + Capabilities: &v1.Capabilities{ + Add: []v1.Capability{ + "MKNOD", + }, + }, + } +} + // Currently we can't mount a block mode pv directly to a privileged container // So we mount it to a non privileged init container and then copy it to a common directory mounted inside init container // and the privileged provision container. @@ -875,7 +888,7 @@ func (c *Cluster) getPVCInitContainer(osdProps osdProperties) v1.Container { }, }, VolumeMounts: []v1.VolumeMount{getPvcOSDBridgeMount(osdProps.pvc.ClaimName)}, - SecurityContext: controller.PodSecurityContext(), + SecurityContext: getBlockDevMapperContext(), Resources: osdProps.resources, } } @@ -907,7 +920,7 @@ func (c *Cluster) getPVCInitContainerActivate(mountPath string, osdProps osdProp }, }, VolumeMounts: []v1.VolumeMount{getPvcOSDBridgeMountActivate(mountPath, osdProps.pvc.ClaimName)}, - SecurityContext: controller.PodSecurityContext(), + SecurityContext: getBlockDevMapperContext(), Resources: osdProps.resources, } } @@ -1009,7 +1022,7 @@ func (c *Cluster) generateEncryptionCopyBlockContainer(resources v1.ResourceRequ // volumeMountPVCName is crucial, especially when the block we copy is the metadata block // its value must be the name of the block PV so that all init containers use the same bridge (the emptyDir shared by all the init containers) VolumeMounts: []v1.VolumeMount{getPvcOSDBridgeMountActivate(mountPath, volumeMountPVCName), getDeviceMapperMount()}, - SecurityContext: controller.PodSecurityContext(), + SecurityContext: getBlockDevMapperContext(), Resources: resources, } } @@ -1056,7 +1069,7 @@ func (c *Cluster) getPVCMetadataInitContainer(mountPath string, osdProps osdProp Name: fmt.Sprintf("%s-bridge", osdProps.metadataPVC.ClaimName), }, }, - SecurityContext: controller.PodSecurityContext(), + SecurityContext: getBlockDevMapperContext(), Resources: osdProps.resources, } } @@ -1090,7 +1103,7 @@ func (c *Cluster) getPVCMetadataInitContainerActivate(mountPath string, osdProps // We need to call getPvcOSDBridgeMountActivate() so that we can copy the metadata block into the "main" empty dir // This empty dir is passed along every init container VolumeMounts: []v1.VolumeMount{getPvcOSDBridgeMountActivate(mountPath, osdProps.pvc.ClaimName)}, - SecurityContext: controller.PodSecurityContext(), + SecurityContext: getBlockDevMapperContext(), Resources: osdProps.resources, } } @@ -1116,7 +1129,7 @@ func (c *Cluster) getPVCWalInitContainer(mountPath string, osdProps osdPropertie Name: fmt.Sprintf("%s-bridge", osdProps.walPVC.ClaimName), }, }, - SecurityContext: controller.PodSecurityContext(), + SecurityContext: getBlockDevMapperContext(), Resources: osdProps.resources, } } @@ -1150,7 +1163,7 @@ func (c *Cluster) getPVCWalInitContainerActivate(mountPath string, osdProps osdP // We need to call getPvcOSDBridgeMountActivate() so that we can copy the wal block into the "main" empty dir // This empty dir is passed along every init container VolumeMounts: []v1.VolumeMount{getPvcOSDBridgeMountActivate(mountPath, osdProps.pvc.ClaimName)}, - SecurityContext: controller.PodSecurityContext(), + SecurityContext: getBlockDevMapperContext(), Resources: osdProps.resources, } }