mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-19 09:52:49 +00:00
Merge pull request #114393 from danielvegamyhre/myfeature
Option to ignore existing pods' preferred inter-pod affinities if the incoming pod has no preferred inter-pod affinities
This commit is contained in:
commit
3a8e2e399b
@ -389,6 +389,27 @@ profiles:
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// high throughput profile config
|
||||
highThroughputProfileConfig := filepath.Join(tmpDir, "high-throughput.yaml")
|
||||
if err := os.WriteFile(highThroughputProfileConfig, []byte(fmt.Sprintf(`
|
||||
apiVersion: kubescheduler.config.k8s.io/v1
|
||||
kind: KubeSchedulerConfiguration
|
||||
clientConnection:
|
||||
kubeconfig: '%s'
|
||||
profiles:
|
||||
- schedulerName: "high-throughput-profile"
|
||||
plugins:
|
||||
preScore:
|
||||
enabled:
|
||||
- name: InterPodAffinity
|
||||
pluginConfig:
|
||||
- name: InterPodAffinity
|
||||
args:
|
||||
ignorePreferredTermsOfExistingPods: true
|
||||
`, configKubeconfig)), os.FileMode(0600)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Insulate this test from picking up in-cluster config when run inside a pod
|
||||
// We can't assume we have permissions to write to /var/run/secrets/... from a unit test to mock in-cluster config for testing
|
||||
originalHost := os.Getenv("KUBERNETES_SERVICE_HOST")
|
||||
@ -1525,6 +1546,110 @@ profiles:
|
||||
expectedError: `key "leaderElect" already set`,
|
||||
checkErrFn: runtime.IsStrictDecodingError,
|
||||
},
|
||||
{
|
||||
name: "high throughput profile",
|
||||
options: &Options{
|
||||
ConfigFile: highThroughputProfileConfig,
|
||||
Logs: logs.NewOptions(),
|
||||
},
|
||||
expectedUsername: "config",
|
||||
expectedConfig: kubeschedulerconfig.KubeSchedulerConfiguration{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: v1.SchemeGroupVersion.String(),
|
||||
},
|
||||
Parallelism: 16,
|
||||
DebuggingConfiguration: componentbaseconfig.DebuggingConfiguration{
|
||||
EnableProfiling: true,
|
||||
EnableContentionProfiling: true,
|
||||
},
|
||||
LeaderElection: componentbaseconfig.LeaderElectionConfiguration{
|
||||
LeaderElect: true,
|
||||
LeaseDuration: metav1.Duration{Duration: 15 * time.Second},
|
||||
RenewDeadline: metav1.Duration{Duration: 10 * time.Second},
|
||||
RetryPeriod: metav1.Duration{Duration: 2 * time.Second},
|
||||
ResourceLock: "leases",
|
||||
ResourceNamespace: "kube-system",
|
||||
ResourceName: "kube-scheduler",
|
||||
},
|
||||
ClientConnection: componentbaseconfig.ClientConnectionConfiguration{
|
||||
Kubeconfig: configKubeconfig,
|
||||
QPS: 50,
|
||||
Burst: 100,
|
||||
ContentType: "application/vnd.kubernetes.protobuf",
|
||||
},
|
||||
PercentageOfNodesToScore: defaultPercentageOfNodesToScore,
|
||||
PodInitialBackoffSeconds: defaultPodInitialBackoffSeconds,
|
||||
PodMaxBackoffSeconds: defaultPodMaxBackoffSeconds,
|
||||
Profiles: []kubeschedulerconfig.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "high-throughput-profile",
|
||||
Plugins: &kubeschedulerconfig.Plugins{
|
||||
QueueSort: defaults.PluginsV1.QueueSort,
|
||||
PreFilter: defaults.PluginsV1.PreFilter,
|
||||
Filter: defaults.PluginsV1.Filter,
|
||||
PostFilter: defaults.PluginsV1.PostFilter,
|
||||
PreScore: kubeschedulerconfig.PluginSet{
|
||||
Enabled: []kubeschedulerconfig.Plugin{
|
||||
{Name: "InterPodAffinity"},
|
||||
},
|
||||
},
|
||||
Score: defaults.PluginsV1.Score,
|
||||
Bind: defaults.PluginsV1.Bind,
|
||||
PreBind: defaults.PluginsV1.PreBind,
|
||||
Reserve: defaults.PluginsV1.Reserve,
|
||||
MultiPoint: defaults.PluginsV1.MultiPoint,
|
||||
},
|
||||
PluginConfig: []kubeschedulerconfig.PluginConfig{
|
||||
{
|
||||
Name: "InterPodAffinity",
|
||||
Args: &kubeschedulerconfig.InterPodAffinityArgs{
|
||||
HardPodAffinityWeight: 1,
|
||||
IgnorePreferredTermsOfExistingPods: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DefaultPreemption",
|
||||
Args: &kubeschedulerconfig.DefaultPreemptionArgs{
|
||||
MinCandidateNodesPercentage: 10,
|
||||
MinCandidateNodesAbsolute: 100,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "NodeAffinity",
|
||||
Args: &kubeschedulerconfig.NodeAffinityArgs{},
|
||||
},
|
||||
{
|
||||
Name: "NodeResourcesBalancedAllocation",
|
||||
Args: &kubeschedulerconfig.NodeResourcesBalancedAllocationArgs{
|
||||
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "NodeResourcesFit",
|
||||
Args: &kubeschedulerconfig.NodeResourcesFitArgs{
|
||||
ScoringStrategy: &kubeschedulerconfig.ScoringStrategy{
|
||||
Type: kubeschedulerconfig.LeastAllocated,
|
||||
Resources: []kubeschedulerconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "PodTopologySpread",
|
||||
Args: &kubeschedulerconfig.PodTopologySpreadArgs{
|
||||
DefaultingType: kubeschedulerconfig.SystemDefaulting,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "VolumeBinding",
|
||||
Args: &kubeschedulerconfig.VolumeBindingArgs{
|
||||
BindTimeoutSeconds: 600,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
@ -1550,7 +1675,7 @@ profiles:
|
||||
}
|
||||
return
|
||||
}
|
||||
t.Errorf("unexpected error to create a config: %v", err)
|
||||
t.Errorf("unexpected error creating config: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
27
pkg/generated/openapi/zz_generated.openapi.go
generated
27
pkg/generated/openapi/zz_generated.openapi.go
generated
@ -53495,7 +53495,16 @@ func schema_k8sio_kube_scheduler_config_v1_InterPodAffinityArgs(ref common.Refer
|
||||
Format: "int32",
|
||||
},
|
||||
},
|
||||
"ignorePreferredTermsOfExistingPods": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "IgnorePreferredTermsOfExistingPods configures the scheduler to ignore existing pods' preferred affinity rules when scoring candidate nodes, unless the incoming pod has inter-pod affinities.",
|
||||
Default: false,
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"ignorePreferredTermsOfExistingPods"},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -54599,7 +54608,16 @@ func schema_k8sio_kube_scheduler_config_v1beta2_InterPodAffinityArgs(ref common.
|
||||
Format: "int32",
|
||||
},
|
||||
},
|
||||
"ignorePreferredTermsOfExistingPods": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "IgnorePreferredTermsOfExistingPods configures the scheduler to ignore existing pods' preferred affinity rules when scoring candidate nodes, unless the incoming pod has inter-pod affinities.",
|
||||
Default: false,
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"ignorePreferredTermsOfExistingPods"},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -55710,7 +55728,16 @@ func schema_k8sio_kube_scheduler_config_v1beta3_InterPodAffinityArgs(ref common.
|
||||
Format: "int32",
|
||||
},
|
||||
},
|
||||
"ignorePreferredTermsOfExistingPods": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "IgnorePreferredTermsOfExistingPods configures the scheduler to ignore existing pods' preferred affinity rules when scoring candidate nodes, unless the incoming pod has inter-pod affinities.",
|
||||
Default: false,
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"ignorePreferredTermsOfExistingPods"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -1134,6 +1134,71 @@ profiles:
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ignorePreferredTermsOfExistingPods is enabled",
|
||||
data: []byte(`
|
||||
apiVersion: kubescheduler.config.k8s.io/v1
|
||||
kind: KubeSchedulerConfiguration
|
||||
profiles:
|
||||
- pluginConfig:
|
||||
- name: InterPodAffinity
|
||||
args:
|
||||
ignorePreferredTermsOfExistingPods: true
|
||||
`),
|
||||
wantProfiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
SchedulerName: "default-scheduler",
|
||||
Plugins: defaults.PluginsV1,
|
||||
PluginConfig: []config.PluginConfig{
|
||||
{
|
||||
Name: "InterPodAffinity",
|
||||
Args: &config.InterPodAffinityArgs{
|
||||
HardPodAffinityWeight: 1,
|
||||
IgnorePreferredTermsOfExistingPods: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DefaultPreemption",
|
||||
Args: &config.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
|
||||
},
|
||||
{
|
||||
Name: "NodeAffinity",
|
||||
Args: &config.NodeAffinityArgs{},
|
||||
},
|
||||
{
|
||||
Name: "NodeResourcesBalancedAllocation",
|
||||
Args: &config.NodeResourcesBalancedAllocationArgs{
|
||||
Resources: []config.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "NodeResourcesFit",
|
||||
Args: &config.NodeResourcesFitArgs{
|
||||
ScoringStrategy: &config.ScoringStrategy{
|
||||
Type: config.LeastAllocated,
|
||||
Resources: []config.ResourceSpec{
|
||||
{Name: "cpu", Weight: 1},
|
||||
{Name: "memory", Weight: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "PodTopologySpread",
|
||||
Args: &config.PodTopologySpreadArgs{
|
||||
DefaultingType: config.SystemDefaulting,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "VolumeBinding",
|
||||
Args: &config.VolumeBindingArgs{
|
||||
BindTimeoutSeconds: 600,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
decoder := Codecs.UniversalDecoder()
|
||||
for _, tt := range testCases {
|
||||
@ -1255,6 +1320,7 @@ profiles:
|
||||
- args:
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta2
|
||||
hardPodAffinityWeight: 5
|
||||
ignorePreferredTermsOfExistingPods: false
|
||||
kind: InterPodAffinityArgs
|
||||
name: InterPodAffinity
|
||||
- args:
|
||||
@ -1360,6 +1426,7 @@ profiles:
|
||||
- args:
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta2
|
||||
hardPodAffinityWeight: 5
|
||||
ignorePreferredTermsOfExistingPods: false
|
||||
kind: InterPodAffinityArgs
|
||||
name: InterPodAffinity
|
||||
- args:
|
||||
@ -1475,6 +1542,7 @@ profiles:
|
||||
- args:
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta3
|
||||
hardPodAffinityWeight: 5
|
||||
ignorePreferredTermsOfExistingPods: false
|
||||
kind: InterPodAffinityArgs
|
||||
name: InterPodAffinity
|
||||
- args:
|
||||
@ -1578,6 +1646,7 @@ profiles:
|
||||
- args:
|
||||
apiVersion: kubescheduler.config.k8s.io/v1beta3
|
||||
hardPodAffinityWeight: 5
|
||||
ignorePreferredTermsOfExistingPods: false
|
||||
kind: InterPodAffinityArgs
|
||||
name: InterPodAffinity
|
||||
- args:
|
||||
@ -1693,6 +1762,7 @@ profiles:
|
||||
- args:
|
||||
apiVersion: kubescheduler.config.k8s.io/v1
|
||||
hardPodAffinityWeight: 5
|
||||
ignorePreferredTermsOfExistingPods: false
|
||||
kind: InterPodAffinityArgs
|
||||
name: InterPodAffinity
|
||||
- args:
|
||||
@ -1796,6 +1866,7 @@ profiles:
|
||||
- args:
|
||||
apiVersion: kubescheduler.config.k8s.io/v1
|
||||
hardPodAffinityWeight: 5
|
||||
ignorePreferredTermsOfExistingPods: false
|
||||
kind: InterPodAffinityArgs
|
||||
name: InterPodAffinity
|
||||
- args:
|
||||
@ -1820,6 +1891,57 @@ profiles:
|
||||
foo: bar
|
||||
name: OutOfTreePlugin
|
||||
schedulerName: ""
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "v1 ignorePreferredTermsOfExistingPods is enabled",
|
||||
version: v1.SchemeGroupVersion,
|
||||
obj: &config.KubeSchedulerConfiguration{
|
||||
Parallelism: 8,
|
||||
Profiles: []config.KubeSchedulerProfile{
|
||||
{
|
||||
PluginConfig: []config.PluginConfig{
|
||||
{
|
||||
Name: "InterPodAffinity",
|
||||
Args: &config.InterPodAffinityArgs{
|
||||
HardPodAffinityWeight: 5,
|
||||
IgnorePreferredTermsOfExistingPods: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: `apiVersion: kubescheduler.config.k8s.io/v1
|
||||
clientConnection:
|
||||
acceptContentTypes: ""
|
||||
burst: 0
|
||||
contentType: ""
|
||||
kubeconfig: ""
|
||||
qps: 0
|
||||
enableContentionProfiling: false
|
||||
enableProfiling: false
|
||||
kind: KubeSchedulerConfiguration
|
||||
leaderElection:
|
||||
leaderElect: false
|
||||
leaseDuration: 0s
|
||||
renewDeadline: 0s
|
||||
resourceLock: ""
|
||||
resourceName: ""
|
||||
resourceNamespace: ""
|
||||
retryPeriod: 0s
|
||||
parallelism: 8
|
||||
podInitialBackoffSeconds: 0
|
||||
podMaxBackoffSeconds: 0
|
||||
profiles:
|
||||
- pluginConfig:
|
||||
- args:
|
||||
apiVersion: kubescheduler.config.k8s.io/v1
|
||||
hardPodAffinityWeight: 5
|
||||
ignorePreferredTermsOfExistingPods: true
|
||||
kind: InterPodAffinityArgs
|
||||
name: InterPodAffinity
|
||||
schedulerName: ""
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
@ -52,6 +52,10 @@ type InterPodAffinityArgs struct {
|
||||
// HardPodAffinityWeight is the scoring weight for existing pods with a
|
||||
// matching hard affinity to the incoming pod.
|
||||
HardPodAffinityWeight int32
|
||||
|
||||
// IgnorePreferredTermsOfExistingPods configures the scheduler to ignore existing pods' preferred affinity
|
||||
// rules when scoring candidate nodes, unless the incoming pod has inter-pod affinities.
|
||||
IgnorePreferredTermsOfExistingPods bool
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
@ -375,6 +375,7 @@ func autoConvert_v1_InterPodAffinityArgs_To_config_InterPodAffinityArgs(in *v1.I
|
||||
if err := metav1.Convert_Pointer_int32_To_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.IgnorePreferredTermsOfExistingPods = in.IgnorePreferredTermsOfExistingPods
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -387,6 +388,7 @@ func autoConvert_config_InterPodAffinityArgs_To_v1_InterPodAffinityArgs(in *conf
|
||||
if err := metav1.Convert_int32_To_Pointer_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.IgnorePreferredTermsOfExistingPods = in.IgnorePreferredTermsOfExistingPods
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -375,6 +375,7 @@ func autoConvert_v1beta2_InterPodAffinityArgs_To_config_InterPodAffinityArgs(in
|
||||
if err := v1.Convert_Pointer_int32_To_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.IgnorePreferredTermsOfExistingPods = in.IgnorePreferredTermsOfExistingPods
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -387,6 +388,7 @@ func autoConvert_config_InterPodAffinityArgs_To_v1beta2_InterPodAffinityArgs(in
|
||||
if err := v1.Convert_int32_To_Pointer_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.IgnorePreferredTermsOfExistingPods = in.IgnorePreferredTermsOfExistingPods
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -375,6 +375,7 @@ func autoConvert_v1beta3_InterPodAffinityArgs_To_config_InterPodAffinityArgs(in
|
||||
if err := v1.Convert_Pointer_int32_To_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.IgnorePreferredTermsOfExistingPods = in.IgnorePreferredTermsOfExistingPods
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -387,6 +388,7 @@ func autoConvert_config_InterPodAffinityArgs_To_v1beta3_InterPodAffinityArgs(in
|
||||
if err := v1.Convert_int32_To_Pointer_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.IgnorePreferredTermsOfExistingPods = in.IgnorePreferredTermsOfExistingPods
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -142,6 +142,15 @@ func (pl *InterPodAffinity) PreScore(
|
||||
hasPreferredAffinityConstraints := affinity != nil && affinity.PodAffinity != nil && len(affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution) > 0
|
||||
hasPreferredAntiAffinityConstraints := affinity != nil && affinity.PodAntiAffinity != nil && len(affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution) > 0
|
||||
|
||||
// Optionally ignore calculating preferences of existing pods' affinity rules
|
||||
// if the incoming pod has no inter-pod affinities.
|
||||
if pl.args.IgnorePreferredTermsOfExistingPods && !hasPreferredAffinityConstraints && !hasPreferredAntiAffinityConstraints {
|
||||
cycleState.Write(preScoreStateKey, &preScoreState{
|
||||
topologyScore: make(map[string]map[string]int64),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unless the pod being scheduled has preferred affinity terms, we only
|
||||
// need to process nodes hosting pods with affinity.
|
||||
var allNodes []*framework.NodeInfo
|
||||
|
@ -369,12 +369,13 @@ func TestPreferredAffinity(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
pod *v1.Pod
|
||||
pods []*v1.Pod
|
||||
nodes []*v1.Node
|
||||
expectedList framework.NodeScoreList
|
||||
name string
|
||||
wantStatus *framework.Status
|
||||
pod *v1.Pod
|
||||
pods []*v1.Pod
|
||||
nodes []*v1.Node
|
||||
expectedList framework.NodeScoreList
|
||||
name string
|
||||
ignorePreferredTermsOfExistingPods bool
|
||||
wantStatus *framework.Status
|
||||
}{
|
||||
{
|
||||
name: "all nodes are same priority as Affinity is nil",
|
||||
@ -736,13 +737,41 @@ func TestPreferredAffinity(t *testing.T) {
|
||||
},
|
||||
expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: framework.MaxNodeScore}},
|
||||
},
|
||||
{
|
||||
name: "Ignore preferred terms of existing pods",
|
||||
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||
pods: []*v1.Pod{
|
||||
{Spec: v1.PodSpec{NodeName: "node1", Affinity: stayWithS1InRegionAwayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||
{Spec: v1.PodSpec{NodeName: "node2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||
},
|
||||
nodes: []*v1.Node{
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||
},
|
||||
expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: 0}},
|
||||
ignorePreferredTermsOfExistingPods: true,
|
||||
},
|
||||
{
|
||||
name: "Do not ignore preferred terms of existing pods",
|
||||
pod: &v1.Pod{Spec: v1.PodSpec{NodeName: ""}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||
pods: []*v1.Pod{
|
||||
{Spec: v1.PodSpec{NodeName: "node1", Affinity: stayWithS1InRegionAwayFromS2InAz}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS1}},
|
||||
{Spec: v1.PodSpec{NodeName: "node2", Affinity: stayWithS2InRegion}, ObjectMeta: metav1.ObjectMeta{Labels: podLabelSecurityS2}},
|
||||
},
|
||||
nodes: []*v1.Node{
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: "node1", Labels: labelRgChina}},
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: "node2", Labels: labelRgIndia}},
|
||||
},
|
||||
expectedList: []framework.NodeScore{{Name: "node1", Score: 0}, {Name: "node2", Score: framework.MaxNodeScore}},
|
||||
ignorePreferredTermsOfExistingPods: false,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
state := framework.NewCycleState()
|
||||
p := plugintesting.SetupPluginWithInformers(ctx, t, New, &config.InterPodAffinityArgs{HardPodAffinityWeight: 1}, cache.NewSnapshot(test.pods, test.nodes), namespaces)
|
||||
p := plugintesting.SetupPluginWithInformers(ctx, t, New, &config.InterPodAffinityArgs{HardPodAffinityWeight: 1, IgnorePreferredTermsOfExistingPods: test.ignorePreferredTermsOfExistingPods}, cache.NewSnapshot(test.pods, test.nodes), namespaces)
|
||||
status := p.(framework.PreScorePlugin).PreScore(ctx, state, test.pod, test.nodes)
|
||||
if !status.IsSuccess() {
|
||||
if !strings.Contains(status.Message(), test.wantStatus.Message()) {
|
||||
|
@ -52,6 +52,10 @@ type InterPodAffinityArgs struct {
|
||||
// HardPodAffinityWeight is the scoring weight for existing pods with a
|
||||
// matching hard affinity to the incoming pod.
|
||||
HardPodAffinityWeight *int32 `json:"hardPodAffinityWeight,omitempty"`
|
||||
|
||||
// IgnorePreferredTermsOfExistingPods configures the scheduler to ignore existing pods' preferred affinity
|
||||
// rules when scoring candidate nodes, unless the incoming pod has inter-pod affinities.
|
||||
IgnorePreferredTermsOfExistingPods bool `json:"ignorePreferredTermsOfExistingPods"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
@ -52,6 +52,10 @@ type InterPodAffinityArgs struct {
|
||||
// HardPodAffinityWeight is the scoring weight for existing pods with a
|
||||
// matching hard affinity to the incoming pod.
|
||||
HardPodAffinityWeight *int32 `json:"hardPodAffinityWeight,omitempty"`
|
||||
|
||||
// IgnorePreferredTermsOfExistingPods configures the scheduler to ignore existing pods' preferred affinity
|
||||
// rules when scoring candidate nodes, unless the incoming pod has inter-pod affinities.
|
||||
IgnorePreferredTermsOfExistingPods bool `json:"ignorePreferredTermsOfExistingPods"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
@ -52,6 +52,10 @@ type InterPodAffinityArgs struct {
|
||||
// HardPodAffinityWeight is the scoring weight for existing pods with a
|
||||
// matching hard affinity to the incoming pod.
|
||||
HardPodAffinityWeight *int32 `json:"hardPodAffinityWeight,omitempty"`
|
||||
|
||||
// IgnorePreferredTermsOfExistingPods configures the scheduler to ignore existing pods' preferred affinity
|
||||
// rules when scoring candidate nodes, unless the incoming pod has inter-pod affinities.
|
||||
IgnorePreferredTermsOfExistingPods bool `json:"ignorePreferredTermsOfExistingPods"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
Loading…
Reference in New Issue
Block a user