diff --git a/pkg/controller/daemon/controller.go b/pkg/controller/daemon/controller.go index 9c920f8612a..39d131ae37d 100644 --- a/pkg/controller/daemon/controller.go +++ b/pkg/controller/daemon/controller.go @@ -601,6 +601,11 @@ func (dsc *DaemonSetsController) nodeShouldRunDaemonPod(node *api.Node, ds *exte if pod.Spec.NodeName != node.Name { continue } + // ignore pods that belong to the daemonset when taking into account wheter + // a daemonset should bind to a node. + if pds := dsc.getPodDaemonSet(pod); pds != nil && ds.Name == pds.Name { + continue + } pods = append(pods, pod) } _, notFittingCPU, notFittingMemory := predicates.CheckPodsExceedingFreeResources(pods, node.Status.Allocatable) diff --git a/pkg/controller/daemon/controller_test.go b/pkg/controller/daemon/controller_test.go index ceccbceeb08..eceb00dcce3 100644 --- a/pkg/controller/daemon/controller_test.go +++ b/pkg/controller/daemon/controller_test.go @@ -284,6 +284,36 @@ func TestPortConflictNodeDaemonDoesNotLaunchPod(t *testing.T) { manager.podStore.Add(&api.Pod{ Spec: podSpec, }) + + ds := newDaemonSet("foo") + ds.Spec.Template.Spec = podSpec + manager.dsStore.Add(ds) + syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0) +} + +// Test that if the node is already scheduled with a pod using a host port +// but belonging to the same daemonset, we don't delete that pod +// +// Issue: https://github.com/kubernetes/kubernetes/issues/22309 +func TestPortConflictWithSameDaemonPodDoesNotDeletePod(t *testing.T) { + podSpec := api.PodSpec{ + NodeName: "port-conflict", + Containers: []api.Container{{ + Ports: []api.ContainerPort{{ + HostPort: 666, + }}, + }}, + } + manager, podControl := newTestController() + node := newNode("port-conflict", nil) + manager.nodeStore.Add(node) + manager.podStore.Add(&api.Pod{ + ObjectMeta: api.ObjectMeta{ + Labels: simpleDaemonSetLabel, + Namespace: api.NamespaceDefault, + }, + Spec: podSpec, + }) ds := newDaemonSet("foo") ds.Spec.Template.Spec = podSpec manager.dsStore.Add(ds)