diff --git a/pkg/scheduler/framework/plugins/volumezone/BUILD b/pkg/scheduler/framework/plugins/volumezone/BUILD index 7c2400e9cd5..b2afa78edb3 100644 --- a/pkg/scheduler/framework/plugins/volumezone/BUILD +++ b/pkg/scheduler/framework/plugins/volumezone/BUILD @@ -12,6 +12,7 @@ go_library( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/storage/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library", "//staging/src/k8s.io/client-go/listers/storage/v1:go_default_library", "//staging/src/k8s.io/cloud-provider/volume/helpers:go_default_library", diff --git a/pkg/scheduler/framework/plugins/volumezone/volume_zone.go b/pkg/scheduler/framework/plugins/volumezone/volume_zone.go index 1340f5421f0..8a782ad0cdb 100644 --- a/pkg/scheduler/framework/plugins/volumezone/volume_zone.go +++ b/pkg/scheduler/framework/plugins/volumezone/volume_zone.go @@ -23,6 +23,7 @@ import ( v1 "k8s.io/api/core/v1" storage "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/sets" corelisters "k8s.io/client-go/listers/core/v1" storagelisters "k8s.io/client-go/listers/storage/v1" volumehelpers "k8s.io/cloud-provider/volume/helpers" @@ -49,6 +50,13 @@ const ( ErrReasonConflict = "node(s) had no available volume zone" ) +var volumeZoneLabels = sets.NewString( + v1.LabelZoneFailureDomain, + v1.LabelZoneRegion, + v1.LabelZoneFailureDomainStable, + v1.LabelZoneRegionStable, +) + // Name returns name of the plugin. It is used in logs, etc. func (pl *VolumeZone) Name() string { return Name @@ -82,7 +90,7 @@ func (pl *VolumeZone) Filter(ctx context.Context, _ *framework.CycleState, pod * } nodeConstraints := make(map[string]string) for k, v := range node.ObjectMeta.Labels { - if k != v1.LabelZoneFailureDomain && k != v1.LabelZoneRegion { + if !volumeZoneLabels.Has(k) { continue } nodeConstraints[k] = v @@ -145,7 +153,7 @@ func (pl *VolumeZone) Filter(ctx context.Context, _ *framework.CycleState, pod * } for k, v := range pv.ObjectMeta.Labels { - if k != v1.LabelZoneFailureDomain && k != v1.LabelZoneRegion { + if !volumeZoneLabels.Has(k) { continue } nodeV, _ := nodeConstraints[k] diff --git a/pkg/scheduler/framework/plugins/volumezone/volume_zone_test.go b/pkg/scheduler/framework/plugins/volumezone/volume_zone_test.go index 4c395b9985c..7e9ce56c6b2 100644 --- a/pkg/scheduler/framework/plugins/volumezone/volume_zone_test.go +++ b/pkg/scheduler/framework/plugins/volumezone/volume_zone_test.go @@ -53,10 +53,16 @@ func TestSingleZone(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "Vol_1", Labels: map[string]string{v1.LabelZoneFailureDomain: "us-west1-a"}}, }, { - ObjectMeta: metav1.ObjectMeta{Name: "Vol_2", Labels: map[string]string{v1.LabelZoneRegion: "us-west1-b", "uselessLabel": "none"}}, + ObjectMeta: metav1.ObjectMeta{Name: "Vol_2", Labels: map[string]string{v1.LabelZoneRegion: "us-west1", "uselessLabel": "none"}}, }, { - ObjectMeta: metav1.ObjectMeta{Name: "Vol_3", Labels: map[string]string{v1.LabelZoneRegion: "us-west1-c"}}, + ObjectMeta: metav1.ObjectMeta{Name: "Vol_3", Labels: map[string]string{v1.LabelZoneRegion: "us-west1"}}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "Vol_Stable_1", Labels: map[string]string{v1.LabelZoneFailureDomainStable: "us-west1-a"}}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "Vol_Stable_2", Labels: map[string]string{v1.LabelZoneRegionStable: "us-west1", "uselessLabel": "none"}}, }, } @@ -77,6 +83,14 @@ func TestSingleZone(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "PVC_4", Namespace: "default"}, Spec: v1.PersistentVolumeClaimSpec{VolumeName: "Vol_not_exist"}, }, + { + ObjectMeta: metav1.ObjectMeta{Name: "PVC_Stable_1", Namespace: "default"}, + Spec: v1.PersistentVolumeClaimSpec{VolumeName: "Vol_Stable_1"}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "PVC_Stable_2", Namespace: "default"}, + Spec: v1.PersistentVolumeClaimSpec{VolumeName: "Vol_Stable_2"}, + }, } tests := []struct { @@ -107,7 +121,7 @@ func TestSingleZone(t *testing.T) { }, }, { - name: "label zone failure domain matched", + name: "beta zone label matched", Pod: createPodWithVolume("pod_1", "vol_1", "PVC_1"), Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ @@ -117,28 +131,28 @@ func TestSingleZone(t *testing.T) { }, }, { - name: "label zone region matched", + name: "beta region label matched", Pod: createPodWithVolume("pod_1", "vol_1", "PVC_2"), Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: "host1", - Labels: map[string]string{v1.LabelZoneRegion: "us-west1-b", "uselessLabel": "none"}, + Labels: map[string]string{v1.LabelZoneRegion: "us-west1", "uselessLabel": "none"}, }, }, }, { - name: "label zone region failed match", + name: "beta region label doesn't match", Pod: createPodWithVolume("pod_1", "vol_1", "PVC_2"), Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: "host1", - Labels: map[string]string{v1.LabelZoneRegion: "no_us-west1-b", "uselessLabel": "none"}, + Labels: map[string]string{v1.LabelZoneRegion: "no_us-west1", "uselessLabel": "none"}, }, }, wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonConflict), }, { - name: "label zone failure domain failed match", + name: "beta zone label doesn't match", Pod: createPodWithVolume("pod_1", "vol_1", "PVC_1"), Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ @@ -148,6 +162,48 @@ func TestSingleZone(t *testing.T) { }, wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonConflict), }, + { + name: "zone label matched", + Pod: createPodWithVolume("pod_1", "Vol_Stable_1", "PVC_Stable_1"), + Node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "host1", + Labels: map[string]string{v1.LabelZoneFailureDomainStable: "us-west1-a", "uselessLabel": "none"}, + }, + }, + }, + { + name: "region label matched", + Pod: createPodWithVolume("pod_1", "Vol_Stable_2", "PVC_Stable_2"), + Node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "host1", + Labels: map[string]string{v1.LabelZoneRegionStable: "us-west1", "uselessLabel": "none"}, + }, + }, + }, + { + name: "region label doesn't match", + Pod: createPodWithVolume("pod_1", "Vol_Stable_2", "PVC_Stable_2"), + Node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "host1", + Labels: map[string]string{v1.LabelZoneRegionStable: "no_us-west1", "uselessLabel": "none"}, + }, + }, + wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonConflict), + }, + { + name: "zone label doesn't match", + Pod: createPodWithVolume("pod_1", "Vol_Stable_1", "PVC_Stable_1"), + Node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "host1", + Labels: map[string]string{v1.LabelZoneFailureDomainStable: "no_us-west1-a", "uselessLabel": "none"}, + }, + }, + wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonConflict), + }, } for _, test := range tests { @@ -178,6 +234,12 @@ func TestMultiZone(t *testing.T) { { ObjectMeta: metav1.ObjectMeta{Name: "Vol_3", Labels: map[string]string{v1.LabelZoneFailureDomain: "us-west1-c__us-west1-a"}}, }, + { + ObjectMeta: metav1.ObjectMeta{Name: "Vol_Stable_1", Labels: map[string]string{v1.LabelZoneFailureDomainStable: "us-west1-a"}}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "Vol_Stable_2", Labels: map[string]string{v1.LabelZoneFailureDomainStable: "us-west1-c__us-west1-a"}}, + }, } pvcLister := fakelisters.PersistentVolumeClaimLister{ @@ -197,6 +259,14 @@ func TestMultiZone(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "PVC_4", Namespace: "default"}, Spec: v1.PersistentVolumeClaimSpec{VolumeName: "Vol_not_exist"}, }, + { + ObjectMeta: metav1.ObjectMeta{Name: "PVC_Stable_1", Namespace: "default"}, + Spec: v1.PersistentVolumeClaimSpec{VolumeName: "Vol_Stable_1"}, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "PVC_Stable_2", Namespace: "default"}, + Spec: v1.PersistentVolumeClaimSpec{VolumeName: "Vol_Stable_2"}, + }, } tests := []struct { @@ -215,7 +285,7 @@ func TestMultiZone(t *testing.T) { }, }, { - name: "label zone failure domain matched", + name: "beta zone label matched", Pod: createPodWithVolume("pod_1", "Vol_3", "PVC_3"), Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ @@ -225,7 +295,7 @@ func TestMultiZone(t *testing.T) { }, }, { - name: "label zone failure domain failed match", + name: "beta zone label doesn't match", Pod: createPodWithVolume("pod_1", "vol_1", "PVC_1"), Node: &v1.Node{ ObjectMeta: metav1.ObjectMeta{ @@ -235,6 +305,27 @@ func TestMultiZone(t *testing.T) { }, wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonConflict), }, + { + name: "zone label matched", + Pod: createPodWithVolume("pod_1", "Vol_Stable_2", "PVC_Stable_2"), + Node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "host1", + Labels: map[string]string{v1.LabelZoneFailureDomainStable: "us-west1-a", "uselessLabel": "none"}, + }, + }, + }, + { + name: "zone label doesn't match", + Pod: createPodWithVolume("pod_1", "Vol_Stable_1", "PVC_Stable_1"), + Node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "host1", + Labels: map[string]string{v1.LabelZoneFailureDomainStable: "us-west1-b", "uselessLabel": "none"}, + }, + }, + wantStatus: framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonConflict), + }, } for _, test := range tests {