@@ -140,9 +140,9 @@ func NewController(
140140
141141 logger := klog .FromContext (ctx )
142142 _ , err = podInformer .Informer ().AddEventHandler (cache.ResourceEventHandlerFuncs {
143- AddFunc : func (obj interface {}) { c .addPod (logger , obj ) },
144- DeleteFunc : func (obj interface {}) { c .deletePod (logger , obj ) },
145- // Not watching updates: Pod volumes and SecurityContext are immutable after creation
143+ AddFunc : func (obj interface {}) { c .enqueuePod (logger , obj ) },
144+ UpdateFunc : func (oldObj , newObj interface {}) { c .updatePod (logger , oldObj , newObj ) },
145+ DeleteFunc : func ( obj interface {}) { c . enqueuePod ( logger , obj ) },
146146 })
147147 if err != nil {
148148 return nil , err
@@ -178,20 +178,37 @@ func NewController(
178178 return c , nil
179179}
180180
181- func (c * Controller ) addPod (_ klog.Logger , obj interface {}) {
181+ func (c * Controller ) enqueuePod (_ klog.Logger , obj interface {}) {
182182 podRef , err := cache .DeletionHandlingObjectToName (obj )
183183 if err != nil {
184184 utilruntime .HandleError (fmt .Errorf ("couldn't get key for pod %#v: %w" , obj , err ))
185185 }
186186 c .queue .Add (podRef )
187187}
188188
189- func (c * Controller ) deletePod (_ klog.Logger , obj interface {}) {
190- podRef , err := cache .DeletionHandlingObjectToName (obj )
191- if err != nil {
192- utilruntime .HandleError (fmt .Errorf ("couldn't get key for pod %#v: %w" , obj , err ))
189+ func (c * Controller ) updatePod (logger klog.Logger , oldObj , newObj interface {}) {
190+ // Pod.Spec fields that are relevant to this controller are immutable after creation (i.e.
191+ // pod volumes, SELinux labels, privileged flag). React to update only when the Pod
192+ // reaches its final state - kubelet will unmount the Pod volumes and the controller should
193+ // therefore remove them from the cache.
194+ oldPod , ok := oldObj .(* v1.Pod )
195+ if ! ok {
196+ return
193197 }
194- c .queue .Add (podRef )
198+ newPod , ok := newObj .(* v1.Pod )
199+ if ! ok {
200+ return
201+ }
202+
203+ // This is an optimization. In theory, passing most pod updates to the controller queue should lead to noop.
204+ // To save some CPU, pass only pod updates that can cause any action in the controller
205+ if oldPod .Status .Phase == newPod .Status .Phase {
206+ return
207+ }
208+ if newPod .Status .Phase != v1 .PodFailed && newPod .Status .Phase != v1 .PodSucceeded {
209+ return
210+ }
211+ c .enqueuePod (logger , newObj )
195212}
196213
197214func (c * Controller ) addPVC (logger klog.Logger , obj interface {}) {
@@ -277,11 +294,7 @@ func (c *Controller) enqueueAllPodsForPVC(logger klog.Logger, namespace, name st
277294 return
278295 }
279296 for _ , obj := range objs {
280- podRef , err := cache .DeletionHandlingObjectToName (obj )
281- if err != nil {
282- utilruntime .HandleError (fmt .Errorf ("couldn't get key for pod %#v: %w" , obj , err ))
283- }
284- c .queue .Add (podRef )
297+ c .enqueuePod (logger , obj )
285298 }
286299}
287300
@@ -401,6 +414,11 @@ func (c *Controller) sync(ctx context.Context, podRef cache.ObjectName) error {
401414 logger .V (5 ).Info ("Error getting pod from informer" , "pod" , klog .KObj (pod ), "podUID" , pod .UID , "err" , err )
402415 return err
403416 }
417+ if pod .Status .Phase == v1 .PodFailed || pod .Status .Phase == v1 .PodSucceeded {
418+ // The pod has reached its final state and kubelet is unmounting is volumes.
419+ // Remove them from the cache.
420+ return c .syncPodDelete (ctx , podRef )
421+ }
404422
405423 return c .syncPod (ctx , pod )
406424}
@@ -481,8 +499,15 @@ func (c *Controller) syncVolume(logger klog.Logger, pod *v1.Pod, spec *volume.Sp
481499 changePolicy := v1 .SELinuxChangePolicyMountOption
482500 if pod .Spec .SecurityContext != nil && pod .Spec .SecurityContext .SELinuxChangePolicy != nil {
483501 changePolicy = * pod .Spec .SecurityContext .SELinuxChangePolicy
502+ logger .V (5 ).Info ("Using Pod SELinux change policy" , "pod" , klog .KObj (pod ), "changePolicy" , changePolicy )
484503 }
485- if ! pluginSupportsSELinuxContextMount {
504+ if ! pluginSupportsSELinuxContextMount && changePolicy != v1 .SELinuxChangePolicyRecursive {
505+ logger .V (5 ).Info ("Volume does not support SELinux context mount, setting changePolicy to Recursive" , "pod" , klog .KObj (pod ), "volume" , spec .Name ())
506+ changePolicy = v1 .SELinuxChangePolicyRecursive
507+ }
508+
509+ if seLinuxLabel == "" && changePolicy != v1 .SELinuxChangePolicyRecursive {
510+ logger .V (5 ).Info ("Pod has empty SELinux label, setting changePolicy to Recursive" , "pod" , klog .KObj (pod ))
486511 changePolicy = v1 .SELinuxChangePolicyRecursive
487512 }
488513
0 commit comments