mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 10:20:51 +00:00
Fix SELinux mismatch metrics
DesiredStateOfWorld must remember both - the effective SELinux label to apply as a mount option (non-empty for RWOP volumes, empty otherwise) - and the label that _would_ be used if the mount option would be used by all access modes. Mismatch warning metrics must be generated from the second label.
This commit is contained in:
parent
771c9be291
commit
48ea6a3f3a
@ -206,12 +206,23 @@ type volumeToMount struct {
|
||||
// Usually this value reflects size recorded in pv.Spec.Capacity
|
||||
persistentVolumeSize *resource.Quantity
|
||||
|
||||
// seLinuxFileLabel is desired SELinux label on files on the volume. If empty, then
|
||||
// effectiveSELinuxMountFileLabel is the SELinux label that will be applied to the volume using mount options.
|
||||
// If empty, then:
|
||||
// - either the context+label is unknown (assigned randomly by the container runtime)
|
||||
// - or the volume plugin responsible for this volume does not support mounting with -o context
|
||||
// - or the volume is not ReadWriteOncePod
|
||||
// - or the OS does not support SELinux
|
||||
// In all cases, the SELinux context does not matter when mounting the volume.
|
||||
effectiveSELinuxMountFileLabel string
|
||||
|
||||
// originalSELinuxLabel is the SELinux label that would be used if SELinux mount was supported for all access modes.
|
||||
// For RWOP volumes it's the same as effectiveSELinuxMountFileLabel.
|
||||
// It is used only to report potential SELinux mismatch metrics.
|
||||
// If empty, then:
|
||||
// - either the context+label is unknown (assigned randomly by the container runtime)
|
||||
// - or the volume plugin responsible for this volume does not support mounting with -o context
|
||||
// - or the OS does not support SELinux
|
||||
// In all cases, the SELinux context does not matter when mounting the volume.
|
||||
seLinuxFileLabel string
|
||||
originalSELinuxLabel string
|
||||
}
|
||||
|
||||
// The pod object represents a pod that references the underlying volume and
|
||||
@ -307,23 +318,25 @@ func (dsw *desiredStateOfWorld) AddPodToVolume(
|
||||
}
|
||||
}
|
||||
}
|
||||
effectiveSELinuxMountLabel := seLinuxFileLabel
|
||||
if !util.VolumeSupportsSELinuxMount(volumeSpec) {
|
||||
// Clear SELinux label for the volume with unsupported access modes.
|
||||
klog.V(4).InfoS("volume does not support SELinux context mount, clearing the expected label", "volume", volumeSpec.Name())
|
||||
seLinuxFileLabel = ""
|
||||
effectiveSELinuxMountLabel = ""
|
||||
}
|
||||
if seLinuxFileLabel != "" {
|
||||
seLinuxVolumesAdmitted.Add(1.0)
|
||||
}
|
||||
vmt := volumeToMount{
|
||||
volumeName: volumeName,
|
||||
podsToMount: make(map[types.UniquePodName]podToMount),
|
||||
pluginIsAttachable: attachable,
|
||||
pluginIsDeviceMountable: deviceMountable,
|
||||
volumeGidValue: volumeGidValue,
|
||||
reportedInUse: false,
|
||||
desiredSizeLimit: sizeLimit,
|
||||
seLinuxFileLabel: seLinuxFileLabel,
|
||||
volumeName: volumeName,
|
||||
podsToMount: make(map[types.UniquePodName]podToMount),
|
||||
pluginIsAttachable: attachable,
|
||||
pluginIsDeviceMountable: deviceMountable,
|
||||
volumeGidValue: volumeGidValue,
|
||||
reportedInUse: false,
|
||||
desiredSizeLimit: sizeLimit,
|
||||
effectiveSELinuxMountFileLabel: effectiveSELinuxMountLabel,
|
||||
originalSELinuxLabel: seLinuxFileLabel,
|
||||
}
|
||||
// record desired size of the volume
|
||||
if volumeSpec.PersistentVolume != nil {
|
||||
@ -337,9 +350,9 @@ func (dsw *desiredStateOfWorld) AddPodToVolume(
|
||||
} else {
|
||||
// volume exists
|
||||
if pluginSupportsSELinuxContextMount {
|
||||
if seLinuxFileLabel != vol.seLinuxFileLabel {
|
||||
if seLinuxFileLabel != vol.originalSELinuxLabel {
|
||||
// TODO: update the error message after tests, e.g. add at least the conflicting pod names.
|
||||
fullErr := fmt.Errorf("conflicting SELinux labels of volume %s: %q and %q", volumeSpec.Name(), vol.seLinuxFileLabel, seLinuxFileLabel)
|
||||
fullErr := fmt.Errorf("conflicting SELinux labels of volume %s: %q and %q", volumeSpec.Name(), vol.originalSELinuxLabel, seLinuxFileLabel)
|
||||
supported := util.VolumeSupportsSELinuxMount(volumeSpec)
|
||||
if err := handleSELinuxMetricError(fullErr, supported, seLinuxVolumeContextMismatchWarnings, seLinuxVolumeContextMismatchErrors); err != nil {
|
||||
return "", err
|
||||
@ -499,7 +512,7 @@ func (dsw *desiredStateOfWorld) VolumeExists(
|
||||
// and mounted with new SELinux mount options for pod B.
|
||||
// Without SELinux, kubelet can (and often does) reuse device mounted
|
||||
// for A.
|
||||
return vol.seLinuxFileLabel == seLinuxMountContext
|
||||
return vol.effectiveSELinuxMountFileLabel == seLinuxMountContext
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -515,7 +528,7 @@ func (dsw *desiredStateOfWorld) PodExistsInVolume(
|
||||
}
|
||||
|
||||
if feature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
|
||||
if volumeObj.seLinuxFileLabel != seLinuxMountOption {
|
||||
if volumeObj.effectiveSELinuxMountFileLabel != seLinuxMountOption {
|
||||
// The volume is in DSW, but with a different SELinux mount option.
|
||||
// Report it as unused, so the volume is unmounted and mounted back
|
||||
// with the right SELinux option.
|
||||
@ -573,7 +586,7 @@ func (dsw *desiredStateOfWorld) GetVolumesToMount() []VolumeToMount {
|
||||
ReportedInUse: volumeObj.reportedInUse,
|
||||
MountRequestTime: podObj.mountRequestTime,
|
||||
DesiredSizeLimit: volumeObj.desiredSizeLimit,
|
||||
SELinuxLabel: volumeObj.seLinuxFileLabel,
|
||||
SELinuxLabel: volumeObj.effectiveSELinuxMountFileLabel,
|
||||
},
|
||||
}
|
||||
if volumeObj.persistentVolumeSize != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user