diff --git a/cmd/kube-controller-manager/app/options/options.go b/cmd/kube-controller-manager/app/options/options.go index 86bfd072c50..fe8affcbda0 100644 --- a/cmd/kube-controller-manager/app/options/options.go +++ b/cmd/kube-controller-manager/app/options/options.go @@ -131,9 +131,13 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet, allControllers []string, disabled fs.Int32Var(&s.ConcurrentDeploymentSyncs, "concurrent-deployment-syncs", s.ConcurrentDeploymentSyncs, "The number of deployment objects that are allowed to sync concurrently. Larger number = more responsive deployments, but more CPU (and network) load") fs.Int32Var(&s.ConcurrentNamespaceSyncs, "concurrent-namespace-syncs", s.ConcurrentNamespaceSyncs, "The number of namespace objects that are allowed to sync concurrently. Larger number = more responsive namespace termination, but more CPU (and network) load") fs.Int32Var(&s.ConcurrentSATokenSyncs, "concurrent-serviceaccount-token-syncs", s.ConcurrentSATokenSyncs, "The number of service account token objects that are allowed to sync concurrently. Larger number = more responsive token generation, but more CPU (and network) load") + // TODO(#43388): Remove the following flag 6 months after v1.6.0 is released. fs.Int32Var(&s.LookupCacheSizeForRC, "replication-controller-lookup-cache-size", s.LookupCacheSizeForRC, "This flag is deprecated and will be removed in future releases. ReplicationController no longer requires a lookup cache.") + fs.MarkDeprecated("replication-controller-lookup-cache-size", "This flag is deprecated and will be removed in future releases. ReplicationController no longer requires a lookup cache.") + // TODO(#43388): Remove the following flag 6 months after v1.6.0 is released. fs.Int32Var(&s.LookupCacheSizeForRS, "replicaset-lookup-cache-size", s.LookupCacheSizeForRS, "This flag is deprecated and will be removed in future releases. ReplicaSet no longer requires a lookup cache.") - // TODO: Remove the following flag 6 months after v1.6.0 is released. + fs.MarkDeprecated("replicaset-lookup-cache-size", "This flag is deprecated and will be removed in future releases. ReplicaSet no longer requires a lookup cache.") + // TODO(#43388): Remove the following flag 6 months after v1.6.0 is released. fs.Int32Var(&s.LookupCacheSizeForDaemonSet, "daemonset-lookup-cache-size", s.LookupCacheSizeForDaemonSet, "This flag is deprecated and will be removed in future releases. DaemonSet no longer requires a lookup cache.") fs.MarkDeprecated("daemonset-lookup-cache-size", "This flag is deprecated and will be removed in future releases. DaemonSet no longer requires a lookup cache.") fs.DurationVar(&s.ServiceSyncPeriod.Duration, "service-sync-period", s.ServiceSyncPeriod.Duration, "The period for syncing services with their external load balancers") diff --git a/pkg/apis/componentconfig/types.go b/pkg/apis/componentconfig/types.go index aefc343e0af..919088b01a0 100644 --- a/pkg/apis/componentconfig/types.go +++ b/pkg/apis/componentconfig/types.go @@ -684,12 +684,17 @@ type KubeControllerManagerConfiguration struct { ConcurrentSATokenSyncs int32 // lookupCacheSizeForRC is the size of lookup cache for replication controllers. // Larger number = more responsive replica management, but more MEM load. + // TODO(#43388): Remove the following flag 6 months after v1.6.0 is released. + // DEPRECATED: This is no longer used. LookupCacheSizeForRC int32 // lookupCacheSizeForRS is the size of lookup cache for replicatsets. // Larger number = more responsive replica management, but more MEM load. + // TODO(#43388): Remove the following flag 6 months after v1.6.0 is released. + // DEPRECATED: This is no longer used. LookupCacheSizeForRS int32 // lookupCacheSizeForDaemonSet is the size of lookup cache for daemonsets. // Larger number = more responsive daemonset, but more MEM load. + // TODO(#43388): Remove the following flag 6 months after v1.6.0 is released. // DEPRECATED: This is no longer used. LookupCacheSizeForDaemonSet int32 // serviceSyncPeriod is the period for syncing services with their external diff --git a/pkg/controller/replicaset/replica_set.go b/pkg/controller/replicaset/replica_set.go index 98970d7840c..0a31df9122f 100644 --- a/pkg/controller/replicaset/replica_set.go +++ b/pkg/controller/replicaset/replica_set.go @@ -181,6 +181,27 @@ func (rsc *ReplicaSetController) getPodReplicaSets(pod *v1.Pod) []*extensions.Re return rss } +// resolveControllerRef returns the controller referenced by a ControllerRef, +// or nil if the ControllerRef could not be resolved to a matching controller +// of the corrrect Kind. +func (rsc *ReplicaSetController) resolveControllerRef(namespace string, controllerRef *metav1.OwnerReference) *extensions.ReplicaSet { + // We can't look up by UID, so look up by Name and then verify UID. + // Don't even try to look up by Name if it's the wrong Kind. + if controllerRef.Kind != controllerKind.Kind { + return nil + } + rs, err := rsc.rsLister.ReplicaSets(namespace).Get(controllerRef.Name) + if err != nil { + return nil + } + if rs.UID != controllerRef.UID { + // The controller we found with this Name is not the same one that the + // ControllerRef points to. + return nil + } + return rs +} + // callback when RS is updated func (rsc *ReplicaSetController) updateRS(old, cur interface{}) { oldRS := old.(*extensions.ReplicaSet) @@ -217,19 +238,15 @@ func (rsc *ReplicaSetController) addPod(obj interface{}) { // If it has a ControllerRef, that's all that matters. if controllerRef := controller.GetControllerOf(pod); controllerRef != nil { - if controllerRef.Kind != controllerKind.Kind { - // It's controlled by a different type of controller. - return - } - glog.V(4).Infof("Pod %s created: %#v.", pod.Name, pod) - rs, err := rsc.rsLister.ReplicaSets(pod.Namespace).Get(controllerRef.Name) - if err != nil { + rs := rsc.resolveControllerRef(pod.Namespace, controllerRef) + if rs == nil { return } rsKey, err := controller.KeyFunc(rs) if err != nil { return } + glog.V(4).Infof("Pod %s created: %#v.", pod.Name, pod) rsc.expectations.CreationObserved(rsKey) rsc.enqueueReplicaSet(rs) return @@ -279,26 +296,20 @@ func (rsc *ReplicaSetController) updatePod(old, cur interface{}) { curControllerRef := controller.GetControllerOf(curPod) oldControllerRef := controller.GetControllerOf(oldPod) controllerRefChanged := !reflect.DeepEqual(curControllerRef, oldControllerRef) - if controllerRefChanged && - oldControllerRef != nil && oldControllerRef.Kind == controllerKind.Kind { + if controllerRefChanged && oldControllerRef != nil { // The ControllerRef was changed. Sync the old controller, if any. - rs, err := rsc.rsLister.ReplicaSets(oldPod.Namespace).Get(oldControllerRef.Name) - if err == nil { + if rs := rsc.resolveControllerRef(oldPod.Namespace, oldControllerRef); rs != nil { rsc.enqueueReplicaSet(rs) } } // If it has a ControllerRef, that's all that matters. if curControllerRef != nil { - if curControllerRef.Kind != controllerKind.Kind { - // It's controlled by a different type of controller. + rs := rsc.resolveControllerRef(curPod.Namespace, curControllerRef) + if rs == nil { return } glog.V(4).Infof("Pod %s updated, objectMeta %+v -> %+v.", curPod.Name, oldPod.ObjectMeta, curPod.ObjectMeta) - rs, err := rsc.rsLister.ReplicaSets(curPod.Namespace).Get(curControllerRef.Name) - if err != nil { - return - } rsc.enqueueReplicaSet(rs) // TODO: MinReadySeconds in the Pod will generate an Available condition to be added in // the Pod status which in turn will trigger a requeue of the owning replica set thus @@ -355,20 +366,15 @@ func (rsc *ReplicaSetController) deletePod(obj interface{}) { // No controller should care about orphans being deleted. return } - if controllerRef.Kind != controllerKind.Kind { - // It's controlled by a different type of controller. - return - } - glog.V(4).Infof("Pod %s/%s deleted through %v, timestamp %+v: %#v.", pod.Namespace, pod.Name, utilruntime.GetCaller(), pod.DeletionTimestamp, pod) - - rs, err := rsc.rsLister.ReplicaSets(pod.Namespace).Get(controllerRef.Name) - if err != nil { + rs := rsc.resolveControllerRef(pod.Namespace, controllerRef) + if rs == nil { return } rsKey, err := controller.KeyFunc(rs) if err != nil { return } + glog.V(4).Infof("Pod %s/%s deleted through %v, timestamp %+v: %#v.", pod.Namespace, pod.Name, utilruntime.GetCaller(), pod.DeletionTimestamp, pod) rsc.expectations.DeletionObserved(rsKey, controller.PodKey(pod)) rsc.enqueueReplicaSet(rs) } diff --git a/pkg/controller/replication/replication_controller.go b/pkg/controller/replication/replication_controller.go index 872acb0656c..332cf1d85f2 100644 --- a/pkg/controller/replication/replication_controller.go +++ b/pkg/controller/replication/replication_controller.go @@ -176,6 +176,27 @@ func (rm *ReplicationManager) getPodControllers(pod *v1.Pod) []*v1.ReplicationCo return rcs } +// resolveControllerRef returns the controller referenced by a ControllerRef, +// or nil if the ControllerRef could not be resolved to a matching controller +// of the corrrect Kind. +func (rm *ReplicationManager) resolveControllerRef(namespace string, controllerRef *metav1.OwnerReference) *v1.ReplicationController { + // We can't look up by UID, so look up by Name and then verify UID. + // Don't even try to look up by Name if it's the wrong Kind. + if controllerRef.Kind != controllerKind.Kind { + return nil + } + rc, err := rm.rcLister.ReplicationControllers(namespace).Get(controllerRef.Name) + if err != nil { + return nil + } + if rc.UID != controllerRef.UID { + // The controller we found with this Name is not the same one that the + // ControllerRef points to. + return nil + } + return rc +} + // callback when RC is updated func (rm *ReplicationManager) updateRC(old, cur interface{}) { oldRC := old.(*v1.ReplicationController) @@ -216,19 +237,15 @@ func (rm *ReplicationManager) addPod(obj interface{}) { // If it has a ControllerRef, that's all that matters. if controllerRef := controller.GetControllerOf(pod); controllerRef != nil { - if controllerRef.Kind != controllerKind.Kind { - // It's controlled by a different type of controller. - return - } - glog.V(4).Infof("Pod %s created: %#v.", pod.Name, pod) - rc, err := rm.rcLister.ReplicationControllers(pod.Namespace).Get(controllerRef.Name) - if err != nil { + rc := rm.resolveControllerRef(pod.Namespace, controllerRef) + if rc == nil { return } rsKey, err := controller.KeyFunc(rc) if err != nil { return } + glog.V(4).Infof("Pod %s created: %#v.", pod.Name, pod) rm.expectations.CreationObserved(rsKey) rm.enqueueController(rc) return @@ -278,26 +295,20 @@ func (rm *ReplicationManager) updatePod(old, cur interface{}) { curControllerRef := controller.GetControllerOf(curPod) oldControllerRef := controller.GetControllerOf(oldPod) controllerRefChanged := !reflect.DeepEqual(curControllerRef, oldControllerRef) - if controllerRefChanged && - oldControllerRef != nil && oldControllerRef.Kind == controllerKind.Kind { + if controllerRefChanged && oldControllerRef != nil { // The ControllerRef was changed. Sync the old controller, if any. - rc, err := rm.rcLister.ReplicationControllers(oldPod.Namespace).Get(oldControllerRef.Name) - if err == nil { + if rc := rm.resolveControllerRef(oldPod.Namespace, oldControllerRef); rc != nil { rm.enqueueController(rc) } } // If it has a ControllerRef, that's all that matters. if curControllerRef != nil { - if curControllerRef.Kind != controllerKind.Kind { - // It's controlled by a different type of controller. + rc := rm.resolveControllerRef(curPod.Namespace, curControllerRef) + if rc == nil { return } glog.V(4).Infof("Pod %s updated, objectMeta %+v -> %+v.", curPod.Name, oldPod.ObjectMeta, curPod.ObjectMeta) - rc, err := rm.rcLister.ReplicationControllers(curPod.Namespace).Get(curControllerRef.Name) - if err != nil { - return - } rm.enqueueController(rc) // TODO: MinReadySeconds in the Pod will generate an Available condition to be added in // the Pod status which in turn will trigger a requeue of the owning ReplicationController thus @@ -354,20 +365,15 @@ func (rm *ReplicationManager) deletePod(obj interface{}) { // No controller should care about orphans being deleted. return } - if controllerRef.Kind != controllerKind.Kind { - // It's controlled by a different type of controller. - return - } - glog.V(4).Infof("Pod %s/%s deleted through %v, timestamp %+v: %#v.", pod.Namespace, pod.Name, utilruntime.GetCaller(), pod.DeletionTimestamp, pod) - - rc, err := rm.rcLister.ReplicationControllers(pod.Namespace).Get(controllerRef.Name) - if err != nil { + rc := rm.resolveControllerRef(pod.Namespace, controllerRef) + if rc == nil { return } rsKey, err := controller.KeyFunc(rc) if err != nil { return } + glog.V(4).Infof("Pod %s/%s deleted through %v, timestamp %+v: %#v.", pod.Namespace, pod.Name, utilruntime.GetCaller(), pod.DeletionTimestamp, pod) rm.expectations.DeletionObserved(rsKey, controller.PodKey(pod)) rm.enqueueController(rc) }