Skip to content

Commit 4e91166

Browse files
committed
Use PreferAvoidPods annotation to avoid pods being scheduled to specific node.
1. define PreferAvoidPods annotation 2. add PreferAvoidPodsPriority 3. validate AvoidPods in node annotations
1 parent eecbfb1 commit 4e91166

14 files changed

Lines changed: 2941 additions & 147 deletions

File tree

pkg/api/helpers.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,10 @@ const (
428428
// CreatedByAnnotation represents the key used to store the spec(json)
429429
// used to create the resource.
430430
CreatedByAnnotation = "kubernetes.io/created-by"
431+
432+
// PreferAvoidPodsAnnotationKey represents the key of preferAvoidPods data (json serialized)
433+
// in the Annotations of a Node.
434+
PreferAvoidPodsAnnotationKey string = "scheduler.alpha.kubernetes.io/preferAvoidPods"
431435
)
432436

433437
// GetAffinityFromPod gets the json serialized affinity data from Pod.Annotations
@@ -500,3 +504,14 @@ func TaintToleratedByTolerations(taint *Taint, tolerations []Toleration) bool {
500504
}
501505
return tolerated
502506
}
507+
508+
func GetAvoidPodsFromNodeAnnotations(annotations map[string]string) (AvoidPods, error) {
509+
var avoidPods AvoidPods
510+
if len(annotations) > 0 && annotations[PreferAvoidPodsAnnotationKey] != "" {
511+
err := json.Unmarshal([]byte(annotations[PreferAvoidPodsAnnotationKey]), &avoidPods)
512+
if err != nil {
513+
return avoidPods, err
514+
}
515+
}
516+
return avoidPods, nil
517+
}

pkg/api/helpers_test.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,3 +295,99 @@ func TestGetAffinityFromPod(t *testing.T) {
295295
}
296296
}
297297
}
298+
299+
func TestGetAvoidPodsFromNode(t *testing.T) {
300+
controllerFlag := true
301+
testCases := []struct {
302+
node *Node
303+
expectValue AvoidPods
304+
expectErr bool
305+
}{
306+
{
307+
node: &Node{},
308+
expectValue: AvoidPods{},
309+
expectErr: false,
310+
},
311+
{
312+
node: &Node{
313+
ObjectMeta: ObjectMeta{
314+
Annotations: map[string]string{
315+
PreferAvoidPodsAnnotationKey: `
316+
{
317+
"preferAvoidPods": [
318+
{
319+
"podSignature": {
320+
"podController": {
321+
"apiVersion": "v1",
322+
"kind": "ReplicationController",
323+
"name": "foo",
324+
"uid": "abcdef123456",
325+
"controller": true
326+
}
327+
},
328+
"reason": "some reason",
329+
"message": "some message"
330+
}
331+
]
332+
}`,
333+
},
334+
},
335+
},
336+
expectValue: AvoidPods{
337+
PreferAvoidPods: []PreferAvoidPodsEntry{
338+
{
339+
PodSignature: PodSignature{
340+
PodController: &OwnerReference{
341+
APIVersion: "v1",
342+
Kind: "ReplicationController",
343+
Name: "foo",
344+
UID: "abcdef123456",
345+
Controller: &controllerFlag,
346+
},
347+
},
348+
Reason: "some reason",
349+
Message: "some message",
350+
},
351+
},
352+
},
353+
expectErr: false,
354+
},
355+
{
356+
node: &Node{
357+
// Missing end symbol of "podController" and "podSignature"
358+
ObjectMeta: ObjectMeta{
359+
Annotations: map[string]string{
360+
PreferAvoidPodsAnnotationKey: `
361+
{
362+
"preferAvoidPods": [
363+
{
364+
"podSignature": {
365+
"podController": {
366+
"kind": "ReplicationController",
367+
"apiVersion": "v1"
368+
"reason": "some reason",
369+
"message": "some message"
370+
}
371+
]
372+
}`,
373+
},
374+
},
375+
},
376+
expectValue: AvoidPods{},
377+
expectErr: true,
378+
},
379+
}
380+
381+
for i, tc := range testCases {
382+
v, err := GetAvoidPodsFromNodeAnnotations(tc.node.Annotations)
383+
if err == nil && tc.expectErr {
384+
t.Errorf("[%v]expected error but got none.", i)
385+
}
386+
if err != nil && !tc.expectErr {
387+
t.Errorf("[%v]did not expect error but got: %v", i, err)
388+
}
389+
if !reflect.DeepEqual(tc.expectValue, v) {
390+
t.Errorf("[%v]expect value %v but got %v with %v", i, tc.expectValue, v, v.PreferAvoidPods[0].PodSignature.PodController.Controller)
391+
}
392+
}
393+
}

0 commit comments

Comments
 (0)