Merge pull request #49488 from k82cn/k8s_46935

Automatic merge from submit-queue (batch tested with PRs 49488, 50407, 46105, 50456, 50258)

Requeue DaemonSets if non-daemon pods were deleted.

**What this PR does / why we need it**:
Requeue DaemonSets if no daemon pods were deleted.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #46935

**Release note**:

```release-note
None
```
This commit is contained in:
Kubernetes Submit Queue
2017-08-11 14:13:53 -07:00
committed by GitHub
3 changed files with 273 additions and 6 deletions

View File

@@ -1613,6 +1613,179 @@ func TestUpdateNode(t *testing.T) {
}
}
// DaemonSets should be resynced when non-daemon pods was deleted.
func TestDeleteNoDaemonPod(t *testing.T) {
var enqueued bool
cases := []struct {
test string
node *v1.Node
existPods []*v1.Pod
deletedPod *v1.Pod
ds *extensions.DaemonSet
shouldEnqueue bool
}{
{
test: "Deleted non-daemon pods to release resources",
node: func() *v1.Node {
node := newNode("node1", nil)
node.Status.Conditions = []v1.NodeCondition{
{Type: v1.NodeReady, Status: v1.ConditionTrue},
}
node.Status.Allocatable = allocatableResources("200M", "200m")
return node
}(),
existPods: func() []*v1.Pod {
pods := []*v1.Pod{}
for i := 0; i < 4; i++ {
podSpec := resourcePodSpec("node1", "50M", "50m")
pods = append(pods, &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("pod_%d", i),
},
Spec: podSpec,
})
}
return pods
}(),
deletedPod: func() *v1.Pod {
podSpec := resourcePodSpec("node1", "50M", "50m")
return &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod_0",
},
Spec: podSpec,
}
}(),
ds: func() *extensions.DaemonSet {
ds := newDaemonSet("ds")
ds.Spec.Template.Spec = resourcePodSpec("", "50M", "50m")
return ds
}(),
shouldEnqueue: true,
},
{
test: "Deleted non-daemon pods (with controller) to release resources",
node: func() *v1.Node {
node := newNode("node1", nil)
node.Status.Conditions = []v1.NodeCondition{
{Type: v1.NodeReady, Status: v1.ConditionTrue},
}
node.Status.Allocatable = allocatableResources("200M", "200m")
return node
}(),
existPods: func() []*v1.Pod {
pods := []*v1.Pod{}
for i := 0; i < 4; i++ {
podSpec := resourcePodSpec("node1", "50M", "50m")
pods = append(pods, &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("pod_%d", i),
OwnerReferences: []metav1.OwnerReference{
{Controller: func() *bool { res := true; return &res }()},
},
},
Spec: podSpec,
})
}
return pods
}(),
deletedPod: func() *v1.Pod {
podSpec := resourcePodSpec("node1", "50M", "50m")
return &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod_0",
OwnerReferences: []metav1.OwnerReference{
{Controller: func() *bool { res := true; return &res }()},
},
},
Spec: podSpec,
}
}(),
ds: func() *extensions.DaemonSet {
ds := newDaemonSet("ds")
ds.Spec.Template.Spec = resourcePodSpec("", "50M", "50m")
return ds
}(),
shouldEnqueue: true,
},
{
test: "Deleted no scheduled pods",
node: func() *v1.Node {
node := newNode("node1", nil)
node.Status.Conditions = []v1.NodeCondition{
{Type: v1.NodeReady, Status: v1.ConditionTrue},
}
node.Status.Allocatable = allocatableResources("200M", "200m")
return node
}(),
existPods: func() []*v1.Pod {
pods := []*v1.Pod{}
for i := 0; i < 4; i++ {
podSpec := resourcePodSpec("node1", "50M", "50m")
pods = append(pods, &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("pod_%d", i),
OwnerReferences: []metav1.OwnerReference{
{Controller: func() *bool { res := true; return &res }()},
},
},
Spec: podSpec,
})
}
return pods
}(),
deletedPod: func() *v1.Pod {
podSpec := resourcePodSpec("", "50M", "50m")
return &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod_5",
},
Spec: podSpec,
}
}(),
ds: func() *extensions.DaemonSet {
ds := newDaemonSet("ds")
ds.Spec.Template.Spec = resourcePodSpec("", "50M", "50m")
return ds
}(),
shouldEnqueue: false,
},
}
for _, c := range cases {
for _, strategy := range updateStrategies() {
manager, podControl, _ := newTestController()
manager.nodeStore.Add(c.node)
c.ds.Spec.UpdateStrategy = *strategy
manager.dsStore.Add(c.ds)
for _, pod := range c.existPods {
manager.podStore.Add(pod)
}
switch strategy.Type {
case extensions.OnDeleteDaemonSetStrategyType:
syncAndValidateDaemonSets(t, manager, c.ds, podControl, 0, 0, 2)
case extensions.RollingUpdateDaemonSetStrategyType:
syncAndValidateDaemonSets(t, manager, c.ds, podControl, 0, 0, 3)
default:
t.Fatalf("unexpected UpdateStrategy %+v", strategy)
}
manager.enqueueDaemonSetRateLimited = func(ds *extensions.DaemonSet) {
if ds.Name == "ds" {
enqueued = true
}
}
enqueued = false
manager.deletePod(c.deletedPod)
if enqueued != c.shouldEnqueue {
t.Errorf("Test case: '%s', expected: %t, got: %t", c.test, c.shouldEnqueue, enqueued)
}
}
}
}
func TestGetNodesToDaemonPods(t *testing.T) {
for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo")