daemon: add custom node indexer

pull/8/head
Michal Fojtik 2018-06-12 10:29:55 +02:00
parent 52603a78ab
commit 6517e250cd
No known key found for this signature in database
GPG Key ID: 172B61E538AAC0EE
2 changed files with 33 additions and 16 deletions

View File

@ -113,6 +113,8 @@ type DaemonSetsController struct {
historyStoreSynced cache.InformerSynced
// podLister get list/get pods from the shared informers's store
podLister corelisters.PodLister
// podNodeIndex indexes pods by their nodeName
podNodeIndex cache.Indexer
// 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.
podStoreSynced cache.InformerSynced
@ -191,6 +193,12 @@ func NewDaemonSetsController(daemonSetInformer appsinformers.DaemonSetInformer,
DeleteFunc: dsc.deletePod,
})
dsc.podLister = podInformer.Lister()
// This custom indexer will index pods based on their NodeName which will decrease the amount of pods we need to get in simulate() call.
podInformer.Informer().GetIndexer().AddIndexers(cache.Indexers{
"nodeName": indexByPodNodeName,
})
dsc.podNodeIndex = podInformer.Informer().GetIndexer()
dsc.podStoreSynced = podInformer.Informer().HasSynced
nodeInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
@ -207,6 +215,18 @@ func NewDaemonSetsController(daemonSetInformer appsinformers.DaemonSetInformer,
return dsc, nil
}
func indexByPodNodeName(obj interface{}) ([]string, error) {
pod, ok := obj.(*v1.Pod)
if !ok {
return []string{}, nil
}
// We are only interested in active pods with nodeName set
if len(pod.Spec.NodeName) == 0 || pod.Status.Phase == v1.PodSucceeded || pod.Status.Phase == v1.PodFailed {
return []string{}, nil
}
return []string{pod.Spec.NodeName}, nil
}
func (dsc *DaemonSetsController) deleteDaemonset(obj interface{}) {
ds, ok := obj.(*apps.DaemonSet)
if !ok {
@ -1272,31 +1292,27 @@ func (dsc *DaemonSetsController) simulate(newPod *v1.Pod, node *v1.Node, ds *app
})
}
pods := []*v1.Pod{}
podList, err := dsc.podLister.List(labels.Everything())
objects, err := dsc.podNodeIndex.ByIndex("nodeName", node.Name)
if err != nil {
return nil, nil, err
}
for _, pod := range podList {
if pod.Spec.NodeName != node.Name {
continue
}
if pod.Status.Phase == v1.PodSucceeded || pod.Status.Phase == v1.PodFailed {
continue
}
// ignore pods that belong to the daemonset when taking into account whether
// a daemonset should bind to a node.
nodeInfo := schedulercache.NewNodeInfo()
nodeInfo.SetNode(node)
for _, obj := range objects {
// Ignore pods that belong to the daemonset when taking into account whether a daemonset should bind to a node.
// TODO: replace this with metav1.IsControlledBy() in 1.12
pod, ok := obj.(*v1.Pod)
if !ok {
continue
}
if isControlledByDaemonSet(pod, ds.GetUID()) {
continue
}
pods = append(pods, pod)
nodeInfo.AddPod(pod)
}
nodeInfo := schedulercache.NewNodeInfo(pods...)
nodeInfo.SetNode(node)
_, reasons, err := Predicates(newPod, nodeInfo)
return reasons, nodeInfo, err
}

View File

@ -1953,6 +1953,7 @@ func TestNodeShouldRunDaemonPod(t *testing.T) {
for _, p := range c.podsOnNode {
manager.podStore.Add(p)
p.Spec.NodeName = "test-node"
manager.podNodeIndex.Add(p)
}
c.ds.Spec.UpdateStrategy = *strategy
wantToRun, shouldSchedule, shouldContinueRunning, err := manager.nodeShouldRunDaemonPod(node, c.ds)