mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-01 02:38:12 +00:00 
			
		
		
		
	Made multi-scheduler graduated to Beta and then v1.
This commit is contained in:
		| @@ -366,6 +366,7 @@ func TestEncodePtr(t *testing.T) { | |||||||
| 			TerminationGracePeriodSeconds: &grace, | 			TerminationGracePeriodSeconds: &grace, | ||||||
|  |  | ||||||
| 			SecurityContext: &api.PodSecurityContext{}, | 			SecurityContext: &api.PodSecurityContext{}, | ||||||
|  | 			SchedulerName:   api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	obj := runtime.Object(pod) | 	obj := runtime.Object(pod) | ||||||
|   | |||||||
| @@ -134,6 +134,9 @@ func FuzzerFor(t *testing.T, version schema.GroupVersion, src rand.Source) *fuzz | |||||||
| 			if s.Affinity == nil { | 			if s.Affinity == nil { | ||||||
| 				s.Affinity = new(api.Affinity) | 				s.Affinity = new(api.Affinity) | ||||||
| 			} | 			} | ||||||
|  | 			if s.SchedulerName == "" { | ||||||
|  | 				s.SchedulerName = api.DefaultSchedulerName | ||||||
|  | 			} | ||||||
| 		}, | 		}, | ||||||
| 		func(j *api.PodPhase, c fuzz.Continue) { | 		func(j *api.PodPhase, c fuzz.Continue) { | ||||||
| 			statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown} | 			statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown} | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ func DeepEqualSafePodSpec() api.PodSpec { | |||||||
| 		DNSPolicy:                     api.DNSClusterFirst, | 		DNSPolicy:                     api.DNSClusterFirst, | ||||||
| 		TerminationGracePeriodSeconds: &grace, | 		TerminationGracePeriodSeconds: &grace, | ||||||
| 		SecurityContext:               &api.PodSecurityContext{}, | 		SecurityContext:               &api.PodSecurityContext{}, | ||||||
|  | 		SchedulerName:                 api.DefaultSchedulerName, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1856,6 +1856,10 @@ type PodSpec struct { | |||||||
| 	// If specified, the pod's scheduling constraints | 	// If specified, the pod's scheduling constraints | ||||||
| 	// +optional | 	// +optional | ||||||
| 	Affinity *Affinity | 	Affinity *Affinity | ||||||
|  | 	// If specified, the pod will be dispatched by specified scheduler. | ||||||
|  | 	// If not specified, the pod will be dispatched by default scheduler. | ||||||
|  | 	// +optional | ||||||
|  | 	SchedulerName string | ||||||
| } | } | ||||||
|  |  | ||||||
| // Sysctl defines a kernel parameter to be set | // Sysctl defines a kernel parameter to be set | ||||||
|   | |||||||
| @@ -174,6 +174,9 @@ func SetDefaults_PodSpec(obj *PodSpec) { | |||||||
| 		period := int64(DefaultTerminationGracePeriodSeconds) | 		period := int64(DefaultTerminationGracePeriodSeconds) | ||||||
| 		obj.TerminationGracePeriodSeconds = &period | 		obj.TerminationGracePeriodSeconds = &period | ||||||
| 	} | 	} | ||||||
|  | 	if obj.SchedulerName == "" { | ||||||
|  | 		obj.SchedulerName = DefaultSchedulerName | ||||||
|  | 	} | ||||||
| } | } | ||||||
| func SetDefaults_Probe(obj *Probe) { | func SetDefaults_Probe(obj *Probe) { | ||||||
| 	if obj.TimeoutSeconds == 0 { | 	if obj.TimeoutSeconds == 0 { | ||||||
|   | |||||||
| @@ -807,3 +807,12 @@ func TestSetDefaultProbe(t *testing.T) { | |||||||
| 		t.Errorf("Expected probe: %+v\ngot: %+v\n", expectedProbe, actualProbe) | 		t.Errorf("Expected probe: %+v\ngot: %+v\n", expectedProbe, actualProbe) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestSetDefaultSchedulerName(t *testing.T) { | ||||||
|  | 	pod := &v1.Pod{} | ||||||
|  |  | ||||||
|  | 	output := roundTrip(t, runtime.Object(pod)).(*v1.Pod) | ||||||
|  | 	if output.Spec.SchedulerName != v1.DefaultSchedulerName { | ||||||
|  | 		t.Errorf("Expected scheduler name: %+v\ngot: %+v\n", v1.DefaultSchedulerName, output.Spec.SchedulerName) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -2140,6 +2140,10 @@ type PodSpec struct { | |||||||
| 	// If specified, the pod's scheduling constraints | 	// If specified, the pod's scheduling constraints | ||||||
| 	// +optional | 	// +optional | ||||||
| 	Affinity *Affinity `json:"affinity,omitempty" protobuf:"bytes,18,opt,name=affinity"` | 	Affinity *Affinity `json:"affinity,omitempty" protobuf:"bytes,18,opt,name=affinity"` | ||||||
|  | 	// If specified, the pod will be dispatched by specified scheduler. | ||||||
|  | 	// If not specified, the pod will be dispatched by default scheduler. | ||||||
|  | 	// +optional | ||||||
|  | 	SchedulerName string `json:"schedulername,omitempty" protobuf:"bytes,19,opt,name=schedulername"` | ||||||
| } | } | ||||||
|  |  | ||||||
| // PodSecurityContext holds pod-level security attributes and common container settings. | // PodSecurityContext holds pod-level security attributes and common container settings. | ||||||
|   | |||||||
| @@ -561,8 +561,7 @@ type KubeSchedulerConfiguration struct { | |||||||
| 	// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. | 	// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. | ||||||
| 	KubeAPIBurst int32 | 	KubeAPIBurst int32 | ||||||
| 	// schedulerName is name of the scheduler, used to select which pods | 	// schedulerName is name of the scheduler, used to select which pods | ||||||
| 	// will be processed by this scheduler, based on pod's annotation with | 	// will be processed by this scheduler, based on pod's "spec.SchedulerName". | ||||||
| 	// key 'scheduler.alpha.kubernetes.io/name'. |  | ||||||
| 	SchedulerName string | 	SchedulerName string | ||||||
| 	// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule | 	// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule | ||||||
| 	// corresponding to every RequiredDuringScheduling affinity rule. | 	// corresponding to every RequiredDuringScheduling affinity rule. | ||||||
|   | |||||||
| @@ -122,8 +122,7 @@ type KubeSchedulerConfiguration struct { | |||||||
| 	// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. | 	// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. | ||||||
| 	KubeAPIBurst int `json:"kubeAPIBurst"` | 	KubeAPIBurst int `json:"kubeAPIBurst"` | ||||||
| 	// schedulerName is name of the scheduler, used to select which pods | 	// schedulerName is name of the scheduler, used to select which pods | ||||||
| 	// will be processed by this scheduler, based on pod's annotation with | 	// will be processed by this scheduler, based on pod's "spec.SchedulerName". | ||||||
| 	// key 'scheduler.alpha.kubernetes.io/name'. |  | ||||||
| 	SchedulerName string `json:"schedulerName"` | 	SchedulerName string `json:"schedulerName"` | ||||||
| 	// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule | 	// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule | ||||||
| 	// corresponding to every RequiredDuringScheduling affinity rule. | 	// corresponding to every RequiredDuringScheduling affinity rule. | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ func TestSetDefaultDaemonSet(t *testing.T) { | |||||||
| 			RestartPolicy:                 v1.RestartPolicyAlways, | 			RestartPolicy:                 v1.RestartPolicyAlways, | ||||||
| 			SecurityContext:               &v1.PodSecurityContext{}, | 			SecurityContext:               &v1.PodSecurityContext{}, | ||||||
| 			TerminationGracePeriodSeconds: &period, | 			TerminationGracePeriodSeconds: &period, | ||||||
|  | 			SchedulerName:                 api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 		ObjectMeta: metav1.ObjectMeta{ | 		ObjectMeta: metav1.ObjectMeta{ | ||||||
| 			Labels: defaultLabels, | 			Labels: defaultLabels, | ||||||
| @@ -51,6 +52,7 @@ func TestSetDefaultDaemonSet(t *testing.T) { | |||||||
| 			RestartPolicy:                 v1.RestartPolicyAlways, | 			RestartPolicy:                 v1.RestartPolicyAlways, | ||||||
| 			SecurityContext:               &v1.PodSecurityContext{}, | 			SecurityContext:               &v1.PodSecurityContext{}, | ||||||
| 			TerminationGracePeriodSeconds: &period, | 			TerminationGracePeriodSeconds: &period, | ||||||
|  | 			SchedulerName:                 api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	tests := []struct { | 	tests := []struct { | ||||||
| @@ -155,6 +157,7 @@ func TestSetDefaultDeployment(t *testing.T) { | |||||||
| 			RestartPolicy:                 v1.RestartPolicyAlways, | 			RestartPolicy:                 v1.RestartPolicyAlways, | ||||||
| 			SecurityContext:               &v1.PodSecurityContext{}, | 			SecurityContext:               &v1.PodSecurityContext{}, | ||||||
| 			TerminationGracePeriodSeconds: &period, | 			TerminationGracePeriodSeconds: &period, | ||||||
|  | 			SchedulerName:                 api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	tests := []struct { | 	tests := []struct { | ||||||
|   | |||||||
| @@ -131,6 +131,7 @@ func TestMerge(t *testing.T) { | |||||||
| 					DNSPolicy:                     api.DNSClusterFirst, | 					DNSPolicy:                     api.DNSClusterFirst, | ||||||
| 					TerminationGracePeriodSeconds: &grace, | 					TerminationGracePeriodSeconds: &grace, | ||||||
| 					SecurityContext:               &api.PodSecurityContext{}, | 					SecurityContext:               &api.PodSecurityContext{}, | ||||||
|  | 					SchedulerName:                 api.DefaultSchedulerName, | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ func TestDecodeSinglePod(t *testing.T) { | |||||||
| 				SecurityContext:        securitycontext.ValidSecurityContextWithContainerDefaults(), | 				SecurityContext:        securitycontext.ValidSecurityContextWithContainerDefaults(), | ||||||
| 			}}, | 			}}, | ||||||
| 			SecurityContext: &v1.PodSecurityContext{}, | 			SecurityContext: &v1.PodSecurityContext{}, | ||||||
|  | 			SchedulerName:   api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	json, err := runtime.Encode(testapi.Default.Codec(), pod) | 	json, err := runtime.Encode(testapi.Default.Codec(), pod) | ||||||
| @@ -113,6 +114,7 @@ func TestDecodePodList(t *testing.T) { | |||||||
| 				SecurityContext:        securitycontext.ValidSecurityContextWithContainerDefaults(), | 				SecurityContext:        securitycontext.ValidSecurityContextWithContainerDefaults(), | ||||||
| 			}}, | 			}}, | ||||||
| 			SecurityContext: &v1.PodSecurityContext{}, | 			SecurityContext: &v1.PodSecurityContext{}, | ||||||
|  | 			SchedulerName:   api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	podList := &v1.PodList{ | 	podList := &v1.PodList{ | ||||||
|   | |||||||
| @@ -188,6 +188,7 @@ func getTestCases(hostname types.NodeName) []*testCase { | |||||||
| 				Spec: v1.PodSpec{ | 				Spec: v1.PodSpec{ | ||||||
| 					Containers:      []v1.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, | 					Containers:      []v1.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}}, | ||||||
| 					SecurityContext: &v1.PodSecurityContext{}, | 					SecurityContext: &v1.PodSecurityContext{}, | ||||||
|  | 					SchedulerName:   api.DefaultSchedulerName, | ||||||
| 				}, | 				}, | ||||||
| 				Status: v1.PodStatus{ | 				Status: v1.PodStatus{ | ||||||
| 					Phase: v1.PodPending, | 					Phase: v1.PodPending, | ||||||
| @@ -213,6 +214,7 @@ func getTestCases(hostname types.NodeName) []*testCase { | |||||||
| 						ImagePullPolicy:        "Always", | 						ImagePullPolicy:        "Always", | ||||||
| 						SecurityContext:        securitycontext.ValidSecurityContextWithContainerDefaults()}}, | 						SecurityContext:        securitycontext.ValidSecurityContextWithContainerDefaults()}}, | ||||||
| 					SecurityContext: &v1.PodSecurityContext{}, | 					SecurityContext: &v1.PodSecurityContext{}, | ||||||
|  | 					SchedulerName:   api.DefaultSchedulerName, | ||||||
| 				}, | 				}, | ||||||
| 				Status: v1.PodStatus{ | 				Status: v1.PodStatus{ | ||||||
| 					Phase: v1.PodPending, | 					Phase: v1.PodPending, | ||||||
|   | |||||||
| @@ -147,6 +147,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { | |||||||
| 					NodeName:        string(nodeName), | 					NodeName:        string(nodeName), | ||||||
| 					Containers:      []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}}, | 					Containers:      []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}}, | ||||||
| 					SecurityContext: &v1.PodSecurityContext{}, | 					SecurityContext: &v1.PodSecurityContext{}, | ||||||
|  | 					SchedulerName:   api.DefaultSchedulerName, | ||||||
| 				}, | 				}, | ||||||
| 				Status: v1.PodStatus{ | 				Status: v1.PodStatus{ | ||||||
| 					Phase: v1.PodPending, | 					Phase: v1.PodPending, | ||||||
| @@ -168,6 +169,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { | |||||||
| 						DNSPolicy:                     v1.DNSClusterFirst, | 						DNSPolicy:                     v1.DNSClusterFirst, | ||||||
| 						SecurityContext:               &v1.PodSecurityContext{}, | 						SecurityContext:               &v1.PodSecurityContext{}, | ||||||
| 						TerminationGracePeriodSeconds: &grace, | 						TerminationGracePeriodSeconds: &grace, | ||||||
|  | 						SchedulerName:                 api.DefaultSchedulerName, | ||||||
|  |  | ||||||
| 						Containers: []v1.Container{{ | 						Containers: []v1.Container{{ | ||||||
| 							Name:  "1", | 							Name:  "1", | ||||||
| @@ -198,6 +200,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { | |||||||
| 							NodeName:        nodeName, | 							NodeName:        nodeName, | ||||||
| 							Containers:      []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}}, | 							Containers:      []v1.Container{{Name: "1", Image: "foo", ImagePullPolicy: v1.PullAlways}}, | ||||||
| 							SecurityContext: &v1.PodSecurityContext{}, | 							SecurityContext: &v1.PodSecurityContext{}, | ||||||
|  | 							SchedulerName:   api.DefaultSchedulerName, | ||||||
| 						}, | 						}, | ||||||
| 						Status: v1.PodStatus{ | 						Status: v1.PodStatus{ | ||||||
| 							Phase: v1.PodPending, | 							Phase: v1.PodPending, | ||||||
| @@ -212,6 +215,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { | |||||||
| 							NodeName:        nodeName, | 							NodeName:        nodeName, | ||||||
| 							Containers:      []v1.Container{{Name: "2", Image: "bar:bartag", ImagePullPolicy: ""}}, | 							Containers:      []v1.Container{{Name: "2", Image: "bar:bartag", ImagePullPolicy: ""}}, | ||||||
| 							SecurityContext: &v1.PodSecurityContext{}, | 							SecurityContext: &v1.PodSecurityContext{}, | ||||||
|  | 							SchedulerName:   api.DefaultSchedulerName, | ||||||
| 						}, | 						}, | ||||||
| 						Status: v1.PodStatus{ | 						Status: v1.PodStatus{ | ||||||
| 							Phase: v1.PodPending, | 							Phase: v1.PodPending, | ||||||
| @@ -235,6 +239,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { | |||||||
| 						DNSPolicy:                     v1.DNSClusterFirst, | 						DNSPolicy:                     v1.DNSClusterFirst, | ||||||
| 						TerminationGracePeriodSeconds: &grace, | 						TerminationGracePeriodSeconds: &grace, | ||||||
| 						SecurityContext:               &v1.PodSecurityContext{}, | 						SecurityContext:               &v1.PodSecurityContext{}, | ||||||
|  | 						SchedulerName:                 api.DefaultSchedulerName, | ||||||
|  |  | ||||||
| 						Containers: []v1.Container{{ | 						Containers: []v1.Container{{ | ||||||
| 							Name:  "1", | 							Name:  "1", | ||||||
| @@ -261,6 +266,7 @@ func TestExtractPodsFromHTTP(t *testing.T) { | |||||||
| 						DNSPolicy:                     v1.DNSClusterFirst, | 						DNSPolicy:                     v1.DNSClusterFirst, | ||||||
| 						TerminationGracePeriodSeconds: &grace, | 						TerminationGracePeriodSeconds: &grace, | ||||||
| 						SecurityContext:               &v1.PodSecurityContext{}, | 						SecurityContext:               &v1.PodSecurityContext{}, | ||||||
|  | 						SchedulerName:                 api.DefaultSchedulerName, | ||||||
|  |  | ||||||
| 						Containers: []v1.Container{{ | 						Containers: []v1.Container{{ | ||||||
| 							Name:  "2", | 							Name:  "2", | ||||||
|   | |||||||
| @@ -73,6 +73,7 @@ func validNewPod() *api.Pod { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			SecurityContext: &api.PodSecurityContext{}, | 			SecurityContext: &api.PodSecurityContext{}, | ||||||
|  | 			SchedulerName:   api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -659,6 +660,7 @@ func TestEtcdUpdateScheduled(t *testing.T) { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			SecurityContext: &api.PodSecurityContext{}, | 			SecurityContext: &api.PodSecurityContext{}, | ||||||
|  | 			SchedulerName:   api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 	}, nil, 1) | 	}, nil, 1) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -687,6 +689,7 @@ func TestEtcdUpdateScheduled(t *testing.T) { | |||||||
|  |  | ||||||
| 			TerminationGracePeriodSeconds: &grace, | 			TerminationGracePeriodSeconds: &grace, | ||||||
| 			SecurityContext:               &api.PodSecurityContext{}, | 			SecurityContext:               &api.PodSecurityContext{}, | ||||||
|  | 			SchedulerName:                 api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	_, _, err = storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn, api.Scheme)) | 	_, _, err = storage.Update(ctx, podIn.Name, rest.DefaultUpdatedObjectInfo(&podIn, api.Scheme)) | ||||||
| @@ -727,6 +730,7 @@ func TestEtcdUpdateStatus(t *testing.T) { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			SecurityContext: &api.PodSecurityContext{}, | 			SecurityContext: &api.PodSecurityContext{}, | ||||||
|  | 			SchedulerName:   api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	err := storage.Storage.Create(ctx, key, &podStart, nil, 0) | 	err := storage.Storage.Create(ctx, key, &podStart, nil, 0) | ||||||
| @@ -751,6 +755,7 @@ func TestEtcdUpdateStatus(t *testing.T) { | |||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
| 			SecurityContext: &api.PodSecurityContext{}, | 			SecurityContext: &api.PodSecurityContext{}, | ||||||
|  | 			SchedulerName:   api.DefaultSchedulerName, | ||||||
| 		}, | 		}, | ||||||
| 		Status: api.PodStatus{ | 		Status: api.PodStatus{ | ||||||
| 			Phase:   api.PodRunning, | 			Phase:   api.PodRunning, | ||||||
|   | |||||||
| @@ -66,7 +66,7 @@ func (s *SchedulerServer) AddFlags(fs *pflag.FlagSet) { | |||||||
| 	fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.") | 	fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "Content type of requests sent to apiserver.") | ||||||
| 	fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver") | 	fs.Float32Var(&s.KubeAPIQPS, "kube-api-qps", s.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver") | ||||||
| 	fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver") | 	fs.Int32Var(&s.KubeAPIBurst, "kube-api-burst", s.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver") | ||||||
| 	fs.StringVar(&s.SchedulerName, "scheduler-name", s.SchedulerName, "Name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's annotation with key 'scheduler.alpha.kubernetes.io/name'") | 	fs.StringVar(&s.SchedulerName, "scheduler-name", s.SchedulerName, "Name of the scheduler, used to select which pods will be processed by this scheduler, based on pod's \"spec.SchedulerName\".") | ||||||
| 	fs.IntVar(&s.HardPodAffinitySymmetricWeight, "hard-pod-affinity-symmetric-weight", api.DefaultHardPodAffinitySymmetricWeight, | 	fs.IntVar(&s.HardPodAffinitySymmetricWeight, "hard-pod-affinity-symmetric-weight", api.DefaultHardPodAffinitySymmetricWeight, | ||||||
| 		"RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule corresponding "+ | 		"RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule corresponding "+ | ||||||
| 			"to every RequiredDuringScheduling affinity rule. --hard-pod-affinity-symmetric-weight represents the weight of implicit PreferredDuringScheduling affinity rule.") | 			"to every RequiredDuringScheduling affinity rule. --hard-pod-affinity-symmetric-weight represents the weight of implicit PreferredDuringScheduling affinity rule.") | ||||||
|   | |||||||
| @@ -48,7 +48,6 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	SchedulerAnnotationKey = "scheduler.alpha.kubernetes.io/name" |  | ||||||
| 	initialGetBackoff = 100 * time.Millisecond | 	initialGetBackoff = 100 * time.Millisecond | ||||||
| 	maximalGetBackoff = time.Minute | 	maximalGetBackoff = time.Minute | ||||||
| ) | ) | ||||||
| @@ -90,8 +89,7 @@ type ConfigFactory struct { | |||||||
| 	schedulerCache schedulercache.Cache | 	schedulerCache schedulercache.Cache | ||||||
|  |  | ||||||
| 	// SchedulerName of a scheduler is used to select which pods will be | 	// SchedulerName of a scheduler is used to select which pods will be | ||||||
| 	// processed by this scheduler, based on pods's annotation key: | 	// processed by this scheduler, based on pods's "spec.SchedulerName". | ||||||
| 	// 'scheduler.alpha.kubernetes.io/name' |  | ||||||
| 	schedulerName string | 	schedulerName string | ||||||
|  |  | ||||||
| 	// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule | 	// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule | ||||||
| @@ -514,11 +512,7 @@ func (f *ConfigFactory) getNextPod() *v1.Pod { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (f *ConfigFactory) ResponsibleForPod(pod *v1.Pod) bool { | func (f *ConfigFactory) ResponsibleForPod(pod *v1.Pod) bool { | ||||||
| 	if f.schedulerName == v1.DefaultSchedulerName { | 	return f.schedulerName == pod.Spec.SchedulerName | ||||||
| 		return pod.Annotations[SchedulerAnnotationKey] == f.schedulerName || pod.Annotations[SchedulerAnnotationKey] == "" |  | ||||||
| 	} else { |  | ||||||
| 		return pod.Annotations[SchedulerAnnotationKey] == f.schedulerName |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func getNodeConditionPredicate() cache.NodeConditionPredicate { | func getNodeConditionPredicate() cache.NodeConditionPredicate { | ||||||
|   | |||||||
| @@ -251,39 +251,33 @@ func TestResponsibleForPod(t *testing.T) { | |||||||
| 	// factory of "foo-scheduler" | 	// factory of "foo-scheduler" | ||||||
| 	factoryFooScheduler := NewConfigFactory(client, "foo-scheduler", v1.DefaultHardPodAffinitySymmetricWeight, v1.DefaultFailureDomains) | 	factoryFooScheduler := NewConfigFactory(client, "foo-scheduler", v1.DefaultHardPodAffinitySymmetricWeight, v1.DefaultFailureDomains) | ||||||
| 	// scheduler annotations to be tested | 	// scheduler annotations to be tested | ||||||
| 	schedulerAnnotationFitsDefault := map[string]string{"scheduler.alpha.kubernetes.io/name": "default-scheduler"} | 	schedulerFitsDefault := "default-scheduler" | ||||||
| 	schedulerAnnotationFitsFoo := map[string]string{"scheduler.alpha.kubernetes.io/name": "foo-scheduler"} | 	schedulerFitsFoo := "foo-scheduler" | ||||||
| 	schedulerAnnotationFitsNone := map[string]string{"scheduler.alpha.kubernetes.io/name": "bar-scheduler"} | 	schedulerFitsNone := "bar-scheduler" | ||||||
|  |  | ||||||
| 	tests := []struct { | 	tests := []struct { | ||||||
| 		pod             *v1.Pod | 		pod             *v1.Pod | ||||||
| 		pickedByDefault bool | 		pickedByDefault bool | ||||||
| 		pickedByFoo     bool | 		pickedByFoo     bool | ||||||
| 	}{ | 	}{ | ||||||
| 		{ | 		{ | ||||||
| 			// pod with no annotation "scheduler.alpha.kubernetes.io/name=<scheduler-name>" should be | 			// pod with "spec.Schedulername=default-scheduler" should be picked | ||||||
| 			// picked by the default scheduler, NOT by the one of name "foo-scheduler" |  | ||||||
| 			pod:             &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}}, |  | ||||||
| 			pickedByDefault: true, |  | ||||||
| 			pickedByFoo:     false, |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			// pod with annotation "scheduler.alpha.kubernetes.io/name=default-scheduler" should be picked |  | ||||||
| 			// by the scheduler of name "default-scheduler", NOT by the one of name "foo-scheduler" | 			// by the scheduler of name "default-scheduler", NOT by the one of name "foo-scheduler" | ||||||
| 			pod:             &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar", Annotations: schedulerAnnotationFitsDefault}}, | 			pod:             &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: v1.PodSpec{SchedulerName: schedulerFitsDefault}}, | ||||||
| 			pickedByDefault: true, | 			pickedByDefault: true, | ||||||
| 			pickedByFoo:     false, | 			pickedByFoo:     false, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			// pod with annotataion "scheduler.alpha.kubernetes.io/name=foo-scheduler" should be NOT | 			// pod with "spec.SchedulerName=foo-scheduler" should be NOT | ||||||
| 			// be picked by the scheduler of name "default-scheduler", but by the one of name "foo-scheduler" | 			// be picked by the scheduler of name "default-scheduler", but by the one of name "foo-scheduler" | ||||||
| 			pod:             &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar", Annotations: schedulerAnnotationFitsFoo}}, | 			pod:             &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: v1.PodSpec{SchedulerName: schedulerFitsFoo}}, | ||||||
| 			pickedByDefault: false, | 			pickedByDefault: false, | ||||||
| 			pickedByFoo:     true, | 			pickedByFoo:     true, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			// pod with annotataion "scheduler.alpha.kubernetes.io/name=foo-scheduler" should be NOT | 			// pod with "spec.SchedulerName=foo-scheduler" should be NOT | ||||||
| 			// be picked by niether the scheduler of name "default-scheduler" nor the one of name "foo-scheduler" | 			// be picked by niether the scheduler of name "default-scheduler" nor the one of name "foo-scheduler" | ||||||
| 			pod:             &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar", Annotations: schedulerAnnotationFitsNone}}, | 			pod:             &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "bar"}, Spec: v1.PodSpec{SchedulerName: schedulerFitsNone}}, | ||||||
| 			pickedByDefault: false, | 			pickedByDefault: false, | ||||||
| 			pickedByFoo:     false, | 			pickedByFoo:     false, | ||||||
| 		}, | 		}, | ||||||
|   | |||||||
| @@ -561,8 +561,7 @@ type KubeSchedulerConfiguration struct { | |||||||
| 	// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. | 	// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. | ||||||
| 	KubeAPIBurst int32 | 	KubeAPIBurst int32 | ||||||
| 	// schedulerName is name of the scheduler, used to select which pods | 	// schedulerName is name of the scheduler, used to select which pods | ||||||
| 	// will be processed by this scheduler, based on pod's annotation with | 	// will be processed by this scheduler, based on pod's "spec.SchedulerName". | ||||||
| 	// key 'scheduler.alpha.kubernetes.io/name'. |  | ||||||
| 	SchedulerName string | 	SchedulerName string | ||||||
| 	// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule | 	// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule | ||||||
| 	// corresponding to every RequiredDuringScheduling affinity rule. | 	// corresponding to every RequiredDuringScheduling affinity rule. | ||||||
|   | |||||||
| @@ -122,8 +122,7 @@ type KubeSchedulerConfiguration struct { | |||||||
| 	// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. | 	// kubeAPIBurst is the QPS burst to use while talking with kubernetes apiserver. | ||||||
| 	KubeAPIBurst int `json:"kubeAPIBurst"` | 	KubeAPIBurst int `json:"kubeAPIBurst"` | ||||||
| 	// schedulerName is name of the scheduler, used to select which pods | 	// schedulerName is name of the scheduler, used to select which pods | ||||||
| 	// will be processed by this scheduler, based on pod's annotation with | 	// will be processed by this scheduler, based on pod's "spec.SchedulerName". | ||||||
| 	// key 'scheduler.alpha.kubernetes.io/name'. |  | ||||||
| 	SchedulerName string `json:"schedulerName"` | 	SchedulerName string `json:"schedulerName"` | ||||||
| 	// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule | 	// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule | ||||||
| 	// corresponding to every RequiredDuringScheduling affinity rule. | 	// corresponding to every RequiredDuringScheduling affinity rule. | ||||||
|   | |||||||
| @@ -84,9 +84,6 @@ func createTerminatingPod(f *framework.Framework) (*v1.Pod, error) { | |||||||
| 	pod := &v1.Pod{ | 	pod := &v1.Pod{ | ||||||
| 		ObjectMeta: metav1.ObjectMeta{ | 		ObjectMeta: metav1.ObjectMeta{ | ||||||
| 			Name: string(uuid), | 			Name: string(uuid), | ||||||
| 			Annotations: map[string]string{ |  | ||||||
| 				"scheduler.alpha.kubernetes.io/name": "please don't schedule my pods", |  | ||||||
| 			}, |  | ||||||
| 		}, | 		}, | ||||||
| 		Spec: v1.PodSpec{ | 		Spec: v1.PodSpec{ | ||||||
| 			Containers: []v1.Container{ | 			Containers: []v1.Container{ | ||||||
| @@ -95,6 +92,7 @@ func createTerminatingPod(f *framework.Framework) (*v1.Pod, error) { | |||||||
| 					Image: "gcr.io/google_containers/busybox:1.24", | 					Image: "gcr.io/google_containers/busybox:1.24", | ||||||
| 				}, | 				}, | ||||||
| 			}, | 			}, | ||||||
|  | 			SchedulerName: "please don't schedule my pods", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	return f.ClientSet.Core().Pods(f.Namespace.Name).Create(pod) | 	return f.ClientSet.Core().Pods(f.Namespace.Name).Create(pod) | ||||||
|   | |||||||
| @@ -352,48 +352,48 @@ func TestMultiScheduler(t *testing.T) { | |||||||
| 	clientSet.Core().Nodes().Create(node) | 	clientSet.Core().Nodes().Create(node) | ||||||
|  |  | ||||||
| 	// 3. create 3 pods for testing | 	// 3. create 3 pods for testing | ||||||
| 	podWithNoAnnotation := createPod(clientSet, "pod-with-no-annotation", nil) | 	podWithoutSchedulerName := createPod(clientSet, "pod-without-scheduler-name", "") | ||||||
| 	testPodNoAnnotation, err := clientSet.Core().Pods(ns.Name).Create(podWithNoAnnotation) | 	testPod, err := clientSet.Core().Pods(ns.Name).Create(podWithoutSchedulerName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("Failed to create pod: %v", err) | 		t.Fatalf("Failed to create pod: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	schedulerAnnotationFitsDefault := map[string]string{"scheduler.alpha.kubernetes.io/name": "default-scheduler"} | 	schedulerFitsDefault := "default-scheduler" | ||||||
| 	podWithAnnotationFitsDefault := createPod(clientSet, "pod-with-annotation-fits-default", schedulerAnnotationFitsDefault) | 	podFitsDefault := createPod(clientSet, "pod-fits-default", schedulerFitsDefault) | ||||||
| 	testPodWithAnnotationFitsDefault, err := clientSet.Core().Pods(ns.Name).Create(podWithAnnotationFitsDefault) | 	testPodFitsDefault, err := clientSet.Core().Pods(ns.Name).Create(podFitsDefault) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("Failed to create pod: %v", err) | 		t.Fatalf("Failed to create pod: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	schedulerAnnotationFitsFoo := map[string]string{"scheduler.alpha.kubernetes.io/name": "foo-scheduler"} | 	schedulerFitsFoo := "foo-scheduler" | ||||||
| 	podWithAnnotationFitsFoo := createPod(clientSet, "pod-with-annotation-fits-foo", schedulerAnnotationFitsFoo) | 	podFitsFoo := createPod(clientSet, "pod-fits-foo", schedulerFitsFoo) | ||||||
| 	testPodWithAnnotationFitsFoo, err := clientSet.Core().Pods(ns.Name).Create(podWithAnnotationFitsFoo) | 	testPodFitsFoo, err := clientSet.Core().Pods(ns.Name).Create(podFitsFoo) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("Failed to create pod: %v", err) | 		t.Fatalf("Failed to create pod: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 4. **check point-1**: | 	// 4. **check point-1**: | ||||||
| 	//		- testPodNoAnnotation, testPodWithAnnotationFitsDefault should be scheduled | 	//		- testPod, testPodFitsDefault should be scheduled | ||||||
| 	//		- testPodWithAnnotationFitsFoo should NOT be scheduled | 	//		- testPodFitsFoo should NOT be scheduled | ||||||
| 	err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodNoAnnotation.Namespace, testPodNoAnnotation.Name)) | 	err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPod.Namespace, testPod.Name)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPodNoAnnotation.Name, err) | 		t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPod.Name, err) | ||||||
| 	} else { | 	} else { | ||||||
| 		t.Logf("Test MultiScheduler: %s Pod scheduled", testPodNoAnnotation.Name) | 		t.Logf("Test MultiScheduler: %s Pod scheduled", testPod.Name) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodWithAnnotationFitsDefault.Namespace, testPodWithAnnotationFitsDefault.Name)) | 	err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodFitsDefault.Namespace, testPodFitsDefault.Name)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPodWithAnnotationFitsDefault.Name, err) | 		t.Errorf("Test MultiScheduler: %s Pod not scheduled: %v", testPodFitsDefault.Name, err) | ||||||
| 	} else { | 	} else { | ||||||
| 		t.Logf("Test MultiScheduler: %s Pod scheduled", testPodWithAnnotationFitsDefault.Name) | 		t.Logf("Test MultiScheduler: %s Pod scheduled", testPodFitsDefault.Name) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodWithAnnotationFitsFoo.Namespace, testPodWithAnnotationFitsFoo.Name)) | 	err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodFitsFoo.Namespace, testPodFitsFoo.Name)) | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		t.Errorf("Test MultiScheduler: %s Pod got scheduled, %v", testPodWithAnnotationFitsFoo.Name, err) | 		t.Errorf("Test MultiScheduler: %s Pod got scheduled, %v", testPodFitsFoo.Name, err) | ||||||
| 	} else { | 	} else { | ||||||
| 		t.Logf("Test MultiScheduler: %s Pod not scheduled", testPodWithAnnotationFitsFoo.Name) | 		t.Logf("Test MultiScheduler: %s Pod not scheduled", testPodFitsFoo.Name) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 5. create and start a scheduler with name "foo-scheduler" | 	// 5. create and start a scheduler with name "foo-scheduler" | ||||||
| @@ -413,19 +413,19 @@ func TestMultiScheduler(t *testing.T) { | |||||||
|  |  | ||||||
| 	//	6. **check point-2**: | 	//	6. **check point-2**: | ||||||
| 	//		- testPodWithAnnotationFitsFoo should be scheduled | 	//		- testPodWithAnnotationFitsFoo should be scheduled | ||||||
| 	err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodWithAnnotationFitsFoo.Namespace, testPodWithAnnotationFitsFoo.Name)) | 	err = wait.Poll(time.Second, time.Second*5, podScheduled(clientSet, testPodFitsFoo.Namespace, testPodFitsFoo.Name)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Errorf("Test MultiScheduler: %s Pod not scheduled, %v", testPodWithAnnotationFitsFoo.Name, err) | 		t.Errorf("Test MultiScheduler: %s Pod not scheduled, %v", testPodFitsFoo.Name, err) | ||||||
| 	} else { | 	} else { | ||||||
| 		t.Logf("Test MultiScheduler: %s Pod scheduled", testPodWithAnnotationFitsFoo.Name) | 		t.Logf("Test MultiScheduler: %s Pod scheduled", testPodFitsFoo.Name) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	//	7. delete the pods that were scheduled by the default scheduler, and stop the default scheduler | 	//	7. delete the pods that were scheduled by the default scheduler, and stop the default scheduler | ||||||
| 	err = clientSet.Core().Pods(ns.Name).Delete(testPodNoAnnotation.Name, v1.NewDeleteOptions(0)) | 	err = clientSet.Core().Pods(ns.Name).Delete(testPod.Name, v1.NewDeleteOptions(0)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Errorf("Failed to delete pod: %v", err) | 		t.Errorf("Failed to delete pod: %v", err) | ||||||
| 	} | 	} | ||||||
| 	err = clientSet.Core().Pods(ns.Name).Delete(testPodWithAnnotationFitsDefault.Name, v1.NewDeleteOptions(0)) | 	err = clientSet.Core().Pods(ns.Name).Delete(testPodFitsDefault.Name, v1.NewDeleteOptions(0)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Errorf("Failed to delete pod: %v", err) | 		t.Errorf("Failed to delete pod: %v", err) | ||||||
| 	} | 	} | ||||||
| @@ -469,11 +469,12 @@ func TestMultiScheduler(t *testing.T) { | |||||||
| 	*/ | 	*/ | ||||||
| } | } | ||||||
|  |  | ||||||
| func createPod(client clientset.Interface, name string, annotation map[string]string) *v1.Pod { | func createPod(client clientset.Interface, name string, scheduler string) *v1.Pod { | ||||||
| 	return &v1.Pod{ | 	return &v1.Pod{ | ||||||
| 		ObjectMeta: metav1.ObjectMeta{Name: name, Annotations: annotation}, | 		ObjectMeta: metav1.ObjectMeta{Name: name}, | ||||||
| 		Spec: v1.PodSpec{ | 		Spec: v1.PodSpec{ | ||||||
| 			Containers:    []v1.Container{{Name: "container", Image: e2e.GetPauseImageName(client)}}, | 			Containers:    []v1.Container{{Name: "container", Image: e2e.GetPauseImageName(client)}}, | ||||||
|  | 			SchedulerName: scheduler, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Klaus Ma
					Klaus Ma