Skip to content

Commit

Permalink
osd: set blkdevmapper capabilities
Browse files Browse the repository at this point in the history
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: #9156
Signed-off-by: Omar Pakker <Omar007@users.noreply.github.com>
(cherry picked from commit 4726d39)
  • Loading branch information
Omar007 authored and mergify-bot committed Nov 15, 2021
1 parent 2950abc commit 7bbeffc
Showing 1 changed file with 20 additions and 7 deletions.
27 changes: 20 additions & 7 deletions pkg/operator/ceph/cluster/osd/spec.go
Expand Up @@ -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.
Expand All @@ -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,
}
}
Expand Down Expand Up @@ -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,
}
}
Expand Down Expand Up @@ -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,
}
}
Expand Down Expand Up @@ -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,
}
}
Expand Down Expand Up @@ -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,
}
}
Expand All @@ -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,
}
}
Expand Down Expand Up @@ -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,
}
}
Expand Down

0 comments on commit 7bbeffc

Please sign in to comment.