Skip to content

Commit a67cc3a

Browse files
Reduce locking duration on cache to fetch data in DaemonSet Controller
1 parent f1c634f commit a67cc3a

File tree

2 files changed

+59
-5
lines changed

2 files changed

+59
-5
lines changed

pkg/controller/controller_utils.go

+31
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ const (
8686

8787
// PodNodeNameKeyIndex is the name of the index used by PodInformer to index pods by their node name.
8888
PodNodeNameKeyIndex = "spec.nodeName"
89+
90+
// OrphanPodIndexKey is used to index all Orphan pods to this key
91+
OrphanPodIndexKey = "_ORPHAN_POD"
92+
93+
// podControllerUIDIndex is the name for the Pod store's index function,
94+
// which is to index by pods's controllerUID.
95+
PodControllerUIDIndex = "podControllerUID"
8996
)
9097

9198
var UpdateTaintBackoff = wait.Backoff{
@@ -1076,6 +1083,30 @@ func AddPodNodeNameIndexer(podInformer cache.SharedIndexInformer) error {
10761083
})
10771084
}
10781085

1086+
// AddPodControllerUIDIndexer adds an indexer for Pod's controllerRef.UID to the given PodInformer.
1087+
// This indexer is used to efficiently look up pods by their ControllerRef.UID
1088+
func AddPodControllerUIDIndexer(podInformer cache.SharedIndexInformer) error {
1089+
if _, exists := podInformer.GetIndexer().GetIndexers()[PodControllerUIDIndex]; exists {
1090+
// indexer already exists, do nothing
1091+
return nil
1092+
}
1093+
return podInformer.AddIndexers(cache.Indexers{
1094+
PodControllerUIDIndex: func(obj interface{}) ([]string, error) {
1095+
pod, ok := obj.(*v1.Pod)
1096+
if !ok {
1097+
return nil, nil
1098+
}
1099+
// Get the ControllerRef of the Pod to check if it's managed by a controller
1100+
if ref := metav1.GetControllerOf(pod); ref != nil {
1101+
return []string{string(ref.UID)}, nil
1102+
}
1103+
// If the Pod has no controller (i.e., it's orphaned), index it with the OrphanPodIndexKey
1104+
// This helps identify orphan pods for reconciliation and adoption by controllers
1105+
return []string{OrphanPodIndexKey}, nil
1106+
},
1107+
})
1108+
}
1109+
10791110
// PodKey returns a key unique to the given pod within a cluster.
10801111
// It's used so we consistently use the same key scheme in this module.
10811112
// It does exactly what cache.MetaNamespaceKeyFunc would have done

pkg/controller/daemon/daemon_controller.go

+28-5
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ type DaemonSetsController struct {
113113
historyStoreSynced cache.InformerSynced
114114
// podLister get list/get pods from the shared informers's store
115115
podLister corelisters.PodLister
116-
// podIndexer allows looking up pods by node name.
116+
// podIndexer allows looking up pods by node name or by ControllerRef UID
117117
podIndexer cache.Indexer
118118
// podStoreSynced returns true if the pod store has been synced at least once.
119119
// Added as a member to the struct to allow injection for testing.
@@ -217,6 +217,7 @@ func NewDaemonSetsController(
217217
dsc.podLister = podInformer.Lister()
218218
dsc.podStoreSynced = podInformer.Informer().HasSynced
219219
controller.AddPodNodeNameIndexer(podInformer.Informer())
220+
controller.AddPodControllerUIDIndexer(podInformer.Informer())
220221
dsc.podIndexer = podInformer.Informer().GetIndexer()
221222

222223
nodeInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
@@ -688,6 +689,30 @@ func (dsc *DaemonSetsController) updateNode(logger klog.Logger, old, cur interfa
688689
dsc.nodeUpdateQueue.Add(curNode.Name)
689690
}
690691

692+
// getPodsFromCache returns the Pods that a given DS should manage.
693+
func (dsc *DaemonSetsController) getDaemonPodsFromCache(ds *apps.DaemonSet) ([]*v1.Pod, error) {
694+
// Iterate over two keys:
695+
// The UID of the Daemonset, which identifies Pods that are controlled by the Daemonset.
696+
// The OrphanPodIndexKey, which helps identify orphaned Pods that are not currently managed by any controller,
697+
// but may be adopted later on if they have matching labels with the Daemonset.
698+
podsForDS := []*v1.Pod{}
699+
for _, key := range []string{string(ds.UID), controller.OrphanPodIndexKey} {
700+
podObjs, err := dsc.podIndexer.ByIndex(controller.PodControllerUIDIndex, key)
701+
if err != nil {
702+
return nil, err
703+
}
704+
for _, obj := range podObjs {
705+
pod, ok := obj.(*v1.Pod)
706+
if !ok {
707+
utilruntime.HandleError(fmt.Errorf("unexpected object type in pod indexer: %v", obj))
708+
continue
709+
}
710+
podsForDS = append(podsForDS, pod)
711+
}
712+
}
713+
return podsForDS, nil
714+
}
715+
691716
// getDaemonPods returns daemon pods owned by the given ds.
692717
// This also reconciles ControllerRef by adopting/orphaning.
693718
// Note that returned Pods are pointers to objects in the cache.
@@ -697,10 +722,8 @@ func (dsc *DaemonSetsController) getDaemonPods(ctx context.Context, ds *apps.Dae
697722
if err != nil {
698723
return nil, err
699724
}
700-
701-
// List all pods to include those that don't match the selector anymore but
702-
// have a ControllerRef pointing to this controller.
703-
pods, err := dsc.podLister.Pods(ds.Namespace).List(labels.Everything())
725+
// List all pods indexed to DS UID and Orphan pods
726+
pods, err := dsc.getDaemonPodsFromCache(ds)
704727
if err != nil {
705728
return nil, err
706729
}

0 commit comments

Comments
 (0)