diff --git a/pkg/controller/daemonset/daemonset_controller.go b/pkg/controller/daemonset/daemonset_controller.go index 27e732f21d..149fb62329 100644 --- a/pkg/controller/daemonset/daemonset_controller.go +++ b/pkg/controller/daemonset/daemonset_controller.go @@ -223,6 +223,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { ds := e.Object.(*appsv1alpha1.DaemonSet) klog.V(4).Infof("Deleting DaemonSet %s/%s", ds.Namespace, ds.Name) dsc.expectations.DeleteExpectations(keyFunc(ds)) + newPodForDSCache.Delete(ds.UID) return true }, }) @@ -449,13 +450,28 @@ func isControlledByDaemonSet(p *corev1.Pod, uuid types.UID) bool { // NewPod creates a new pod func NewPod(ds *appsv1alpha1.DaemonSet, nodeName string) *corev1.Pod { + // firstly load the cache before lock + if pod := loadNewPodForDS(ds); pod != nil { + return pod + } + + newPodForDSLock.Lock() + defer newPodForDSLock.Unlock() + + // load the cache again after locked + if pod := loadNewPodForDS(ds); pod != nil { + return pod + } + newPod := &corev1.Pod{Spec: ds.Spec.Template.Spec, ObjectMeta: ds.Spec.Template.ObjectMeta} newPod.Namespace = ds.Namespace - newPod.Spec.NodeName = nodeName + // no need to set nodeName + // newPod.Spec.NodeName = nodeName // Added default tolerations for DaemonSet pods. daemonsetutil.AddOrUpdateDaemonPodTolerations(&newPod.Spec) + newPodForDSCache.Store(ds.UID, &newPodForDS{generation: ds.Generation, pod: newPod}) return newPod } diff --git a/pkg/controller/daemonset/daemonset_util.go b/pkg/controller/daemonset/daemonset_util.go index c225a130be..e3b6528582 100644 --- a/pkg/controller/daemonset/daemonset_util.go +++ b/pkg/controller/daemonset/daemonset_util.go @@ -19,6 +19,7 @@ package daemonset import ( "fmt" "sort" + "sync" appspub "github.com/openkruise/kruise/apis/apps/pub" appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1" @@ -37,6 +38,27 @@ import ( "k8s.io/utils/integer" ) +var ( + // newPodForDSCache is a cache for NewPod, it is map[ds.UID]*newPodForDS + newPodForDSCache sync.Map + newPodForDSLock sync.Mutex +) + +type newPodForDS struct { + generation int64 + pod *corev1.Pod +} + +func loadNewPodForDS(ds *appsv1alpha1.DaemonSet) *corev1.Pod { + if val, ok := newPodForDSCache.Load(ds.UID); ok { + newPodCache := val.(*newPodForDS) + if newPodCache.generation >= ds.Generation { + return newPodCache.pod + } + } + return nil +} + // nodeInSameCondition returns true if all effective types ("Status" is true) equals; // otherwise, returns false. func nodeInSameCondition(old []corev1.NodeCondition, cur []corev1.NodeCondition) bool {