mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #130859 from hakuna-matatah/optimize-ds
Optimize DS Controller Performance: Reduce Work Duration Time & Minimize Cache Locking.
This commit is contained in:
commit
dca334e350
@ -86,6 +86,13 @@ const (
|
|||||||
|
|
||||||
// PodNodeNameKeyIndex is the name of the index used by PodInformer to index pods by their node name.
|
// PodNodeNameKeyIndex is the name of the index used by PodInformer to index pods by their node name.
|
||||||
PodNodeNameKeyIndex = "spec.nodeName"
|
PodNodeNameKeyIndex = "spec.nodeName"
|
||||||
|
|
||||||
|
// OrphanPodIndexKey is used to index all Orphan pods to this key
|
||||||
|
OrphanPodIndexKey = "_ORPHAN_POD"
|
||||||
|
|
||||||
|
// podControllerUIDIndex is the name for the Pod store's index function,
|
||||||
|
// which is to index by pods's controllerUID.
|
||||||
|
PodControllerUIDIndex = "podControllerUID"
|
||||||
)
|
)
|
||||||
|
|
||||||
var UpdateTaintBackoff = wait.Backoff{
|
var UpdateTaintBackoff = wait.Backoff{
|
||||||
@ -1076,6 +1083,30 @@ func AddPodNodeNameIndexer(podInformer cache.SharedIndexInformer) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddPodControllerUIDIndexer adds an indexer for Pod's controllerRef.UID to the given PodInformer.
|
||||||
|
// This indexer is used to efficiently look up pods by their ControllerRef.UID
|
||||||
|
func AddPodControllerUIDIndexer(podInformer cache.SharedIndexInformer) error {
|
||||||
|
if _, exists := podInformer.GetIndexer().GetIndexers()[PodControllerUIDIndex]; exists {
|
||||||
|
// indexer already exists, do nothing
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return podInformer.AddIndexers(cache.Indexers{
|
||||||
|
PodControllerUIDIndex: func(obj interface{}) ([]string, error) {
|
||||||
|
pod, ok := obj.(*v1.Pod)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
// Get the ControllerRef of the Pod to check if it's managed by a controller
|
||||||
|
if ref := metav1.GetControllerOf(pod); ref != nil {
|
||||||
|
return []string{string(ref.UID)}, nil
|
||||||
|
}
|
||||||
|
// If the Pod has no controller (i.e., it's orphaned), index it with the OrphanPodIndexKey
|
||||||
|
// This helps identify orphan pods for reconciliation and adoption by controllers
|
||||||
|
return []string{OrphanPodIndexKey}, nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// PodKey returns a key unique to the given pod within a cluster.
|
// PodKey returns a key unique to the given pod within a cluster.
|
||||||
// It's used so we consistently use the same key scheme in this module.
|
// It's used so we consistently use the same key scheme in this module.
|
||||||
// It does exactly what cache.MetaNamespaceKeyFunc would have done
|
// It does exactly what cache.MetaNamespaceKeyFunc would have done
|
||||||
|
@ -113,7 +113,7 @@ type DaemonSetsController struct {
|
|||||||
historyStoreSynced cache.InformerSynced
|
historyStoreSynced cache.InformerSynced
|
||||||
// podLister get list/get pods from the shared informers's store
|
// podLister get list/get pods from the shared informers's store
|
||||||
podLister corelisters.PodLister
|
podLister corelisters.PodLister
|
||||||
// podIndexer allows looking up pods by node name.
|
// podIndexer allows looking up pods by node name or by ControllerRef UID
|
||||||
podIndexer cache.Indexer
|
podIndexer cache.Indexer
|
||||||
// podStoreSynced returns true if the pod store has been synced at least once.
|
// podStoreSynced returns true if the pod store has been synced at least once.
|
||||||
// Added as a member to the struct to allow injection for testing.
|
// Added as a member to the struct to allow injection for testing.
|
||||||
@ -217,6 +217,7 @@ func NewDaemonSetsController(
|
|||||||
dsc.podLister = podInformer.Lister()
|
dsc.podLister = podInformer.Lister()
|
||||||
dsc.podStoreSynced = podInformer.Informer().HasSynced
|
dsc.podStoreSynced = podInformer.Informer().HasSynced
|
||||||
controller.AddPodNodeNameIndexer(podInformer.Informer())
|
controller.AddPodNodeNameIndexer(podInformer.Informer())
|
||||||
|
controller.AddPodControllerUIDIndexer(podInformer.Informer())
|
||||||
dsc.podIndexer = podInformer.Informer().GetIndexer()
|
dsc.podIndexer = podInformer.Informer().GetIndexer()
|
||||||
|
|
||||||
nodeInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
nodeInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
@ -688,6 +689,30 @@ func (dsc *DaemonSetsController) updateNode(logger klog.Logger, old, cur interfa
|
|||||||
dsc.nodeUpdateQueue.Add(curNode.Name)
|
dsc.nodeUpdateQueue.Add(curNode.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getPodsFromCache returns the Pods that a given DS should manage.
|
||||||
|
func (dsc *DaemonSetsController) getDaemonPodsFromCache(ds *apps.DaemonSet) ([]*v1.Pod, error) {
|
||||||
|
// Iterate over two keys:
|
||||||
|
// The UID of the Daemonset, which identifies Pods that are controlled by the Daemonset.
|
||||||
|
// The OrphanPodIndexKey, which helps identify orphaned Pods that are not currently managed by any controller,
|
||||||
|
// but may be adopted later on if they have matching labels with the Daemonset.
|
||||||
|
podsForDS := []*v1.Pod{}
|
||||||
|
for _, key := range []string{string(ds.UID), controller.OrphanPodIndexKey} {
|
||||||
|
podObjs, err := dsc.podIndexer.ByIndex(controller.PodControllerUIDIndex, key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, obj := range podObjs {
|
||||||
|
pod, ok := obj.(*v1.Pod)
|
||||||
|
if !ok {
|
||||||
|
utilruntime.HandleError(fmt.Errorf("unexpected object type in pod indexer: %v", obj))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
podsForDS = append(podsForDS, pod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return podsForDS, nil
|
||||||
|
}
|
||||||
|
|
||||||
// getDaemonPods returns daemon pods owned by the given ds.
|
// getDaemonPods returns daemon pods owned by the given ds.
|
||||||
// This also reconciles ControllerRef by adopting/orphaning.
|
// This also reconciles ControllerRef by adopting/orphaning.
|
||||||
// Note that returned Pods are pointers to objects in the cache.
|
// 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
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// List all pods indexed to DS UID and Orphan pods
|
||||||
// List all pods to include those that don't match the selector anymore but
|
pods, err := dsc.getDaemonPodsFromCache(ds)
|
||||||
// have a ControllerRef pointing to this controller.
|
|
||||||
pods, err := dsc.podLister.Pods(ds.Namespace).List(labels.Everything())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user