Skip to content

Commit

Permalink
Add metrics for SELinux context mount
Browse files Browse the repository at this point in the history
Add separate _errors and _warnings to capture volumes that were rejected
from those will be rejected when the feature is expanded to all access
mode.
  • Loading branch information
jsafrane committed Aug 4, 2022
1 parent 48b0751 commit b2e18c0
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cache

import (
"sync"

compbasemetrics "k8s.io/component-base/metrics"
"k8s.io/component-base/metrics/legacyregistry"
)

var (
// TODO: add plugin name + access mode labels to all these metrics
seLinuxContainerContextErrors = compbasemetrics.NewGauge(
&compbasemetrics.GaugeOpts{
Name: "volume_manager_selinux_container_errors_total",
Help: "Number of errors when kubelet cannot compute SELinux context for a container. Kubelet can't start such a Pod then and it will retry, therefore value of this metric may not represent the actual nr. of containers.",
StabilityLevel: compbasemetrics.ALPHA,
})
seLinuxContainerContextWarnings = compbasemetrics.NewGauge(
&compbasemetrics.GaugeOpts{
Name: "volume_manager_selinux_container_warnings_total",
StabilityLevel: compbasemetrics.ALPHA,
Help: "Number of errors when kubelet cannot compute SELinux context for a container that are ignored. They will become real errors when SELinuxMountReadWriteOncePod feature is expanded to all volume access modes.",
})
seLinuxPodContextMismatchErrors = compbasemetrics.NewGauge(
&compbasemetrics.GaugeOpts{
Name: "volume_manager_selinux_pod_context_mismatch_errors_total",
Help: "Number of errors when a Pod defines different SELinux contexts for its containers that use the same volume. Kubelet can't start such a Pod then and it will retry, therefore value of this metric may not represent the actual nr. of Pods.",
StabilityLevel: compbasemetrics.ALPHA,
})
seLinuxPodContextMismatchWarnings = compbasemetrics.NewGauge(
&compbasemetrics.GaugeOpts{
Name: "volume_manager_selinux_pod_context_mismatch_warnings_total",
Help: "Number of errors when a Pod defines different SELinux contexts for its containers that use the same volume. They are not errors yet, but they will become real errors when SELinuxMountReadWriteOncePod feature is expanded to all volume access modes.",
StabilityLevel: compbasemetrics.ALPHA,
})
seLinuxVolumeContextMismatchErrors = compbasemetrics.NewGauge(
&compbasemetrics.GaugeOpts{
Name: "volume_manager_selinux_volume_context_mismatch_errors_total",
Help: "Number of errors when a Pod uses a volume that is already mounted with a different SELinux context than the Pod needs. Kubelet can't start such a Pod then and it will retry, therefore value of this metric may not represent the actual nr. of Pods.",
StabilityLevel: compbasemetrics.ALPHA,
})
seLinuxVolumeContextMismatchWarnings = compbasemetrics.NewGauge(
&compbasemetrics.GaugeOpts{
Name: "volume_manager_selinux_volume_context_mismatch_warnings_total",
Help: "Number of errors when a Pod uses a volume that is already mounted with a different SELinux context than the Pod needs. They are not errors yet, but they will become real errors when SELinuxMountReadWriteOncePod feature is expanded to all volume access modes.",
StabilityLevel: compbasemetrics.ALPHA,
})
seLinuxVolumesAdmitted = compbasemetrics.NewGauge(
&compbasemetrics.GaugeOpts{
Name: "volume_manager_selinux_volumes_admitted_total",
Help: "Number of volumes whose SELinux context was fine and will be mounted with mount -o context option.",
StabilityLevel: compbasemetrics.ALPHA,
})

registerMetrics sync.Once
)

func registerSELinuxMetrics() {
registerMetrics.Do(func() {
legacyregistry.MustRegister(seLinuxContainerContextErrors)
legacyregistry.MustRegister(seLinuxContainerContextWarnings)
legacyregistry.MustRegister(seLinuxPodContextMismatchErrors)
legacyregistry.MustRegister(seLinuxPodContextMismatchWarnings)
legacyregistry.MustRegister(seLinuxVolumeContextMismatchErrors)
legacyregistry.MustRegister(seLinuxVolumeContextMismatchWarnings)
legacyregistry.MustRegister(seLinuxVolumesAdmitted)
})
}
19 changes: 16 additions & 3 deletions pkg/kubelet/volumemanager/cache/desired_state_of_world.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ type VolumeToMount struct {

// NewDesiredStateOfWorld returns a new instance of DesiredStateOfWorld.
func NewDesiredStateOfWorld(volumePluginMgr *volume.VolumePluginMgr) DesiredStateOfWorld {
if feature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) {
registerSELinuxMetrics()
}
return &desiredStateOfWorld{
volumesToMount: make(map[v1.UniqueVolumeName]volumeToMount),
volumePluginMgr: volumePluginMgr,
Expand Down Expand Up @@ -302,10 +305,11 @@ func (dsw *desiredStateOfWorld) AddPodToVolume(
fullErr := fmt.Errorf("failed to construct SELinux label from context %q: %s", containerContext, err)
if isRWOP {
// Cannot mount with -o context if the context can't be composed.
seLinuxContainerContextErrors.Add(1.0)
return "", fullErr
} else {
// This is not an error yet, but it will be when support for RWO and RWX volumes is added
// TODO: bump some metric here
seLinuxContainerContextWarnings.Add(1.0)
klog.V(4).ErrorS(err, "Please report this error in https://github.com/kubernetes/enhancements/issues/1710, together with full Pod yaml file")
break
}
Expand All @@ -317,10 +321,11 @@ func (dsw *desiredStateOfWorld) AddPodToVolume(
if seLinuxFileLabel != newLabel {
fullErr := fmt.Errorf("volume %s is used with two different SELinux contexts in the same pod: %q, %q", volumeSpec.Name(), seLinuxFileLabel, newLabel)
if isRWOP {
seLinuxPodContextMismatchErrors.Add(1.0)
return "", fullErr
} else {
// This is not an error yet, but it will be when support for RWO and RWX volumes is added
// TODO: bump some metric here
seLinuxPodContextMismatchWarnings.Add(1.0)
klog.V(4).ErrorS(err, "Please report this error in https://github.com/kubernetes/enhancements/issues/1710, together with full Pod yaml file")
break
}
Expand Down Expand Up @@ -350,6 +355,9 @@ func (dsw *desiredStateOfWorld) AddPodToVolume(
}
}
}
if seLinuxFileLabel != "" {
seLinuxVolumesAdmitted.Add(1.0)
}
vmt := volumeToMount{
volumeName: volumeName,
podsToMount: make(map[types.UniquePodName]podToMount),
Expand All @@ -376,12 +384,17 @@ func (dsw *desiredStateOfWorld) AddPodToVolume(
// 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)
if isRWOP {
seLinuxVolumeContextMismatchErrors.Add(1.0)
return "", fullErr
} else {
// This is not an error yet, but it will be when support for RWO and RWX volumes is added
// TODO: bump some metric here
seLinuxVolumeContextMismatchWarnings.Add(1.0)
klog.V(4).ErrorS(err, "Please report this error in https://github.com/kubernetes/enhancements/issues/1710, together with full Pod yaml file")
}
} else {
if seLinuxFileLabel != "" {
seLinuxVolumesAdmitted.Add(1.0)
}
}
}
}
Expand Down

0 comments on commit b2e18c0

Please sign in to comment.