Skip to content

Commit 32847aa

Browse files
author
Kubernetes Submit Queue
authored
Merge pull request kubernetes#51783 from jiulongzaitian/myfeature3
Automatic merge from submit-queue (batch tested with PRs 54081, 54271, 51783, 54600, 54594). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. move getMaxVols function to predicates.go and add some NewVolumeCount… …Predicate funcs Signed-off-by: zhangjie <zhangjie0619@yeah.net> **What this PR does / why we need it**: **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes # **Special notes for your reviewer**: **Release note**: ```release-note move getMaxVols function to predicates.go and add some NewVolumeCountPredicate funcs ```
2 parents a0aee05 + 968df82 commit 32847aa

File tree

6 files changed

+110
-97
lines changed

6 files changed

+110
-97
lines changed

plugin/pkg/scheduler/algorithm/predicates/BUILD

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ go_library(
1818
deps = [
1919
"//pkg/api/v1/helper:go_default_library",
2020
"//pkg/api/v1/helper/qos:go_default_library",
21+
"//pkg/cloudprovider/providers/aws:go_default_library",
2122
"//pkg/features:go_default_library",
2223
"//pkg/kubelet/apis:go_default_library",
2324
"//pkg/volume/util:go_default_library",

plugin/pkg/scheduler/algorithm/predicates/predicates.go

+60-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package predicates
1919
import (
2020
"errors"
2121
"fmt"
22+
"os"
23+
"strconv"
2224
"sync"
2325

2426
"k8s.io/api/core/v1"
@@ -31,6 +33,7 @@ import (
3133
"k8s.io/client-go/util/workqueue"
3234
v1helper "k8s.io/kubernetes/pkg/api/v1/helper"
3335
v1qos "k8s.io/kubernetes/pkg/api/v1/helper/qos"
36+
"k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
3437
"k8s.io/kubernetes/pkg/features"
3538
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
3639
volumeutil "k8s.io/kubernetes/pkg/volume/util"
@@ -45,6 +48,24 @@ import (
4548

4649
const (
4750
MatchInterPodAffinity = "MatchInterPodAffinity"
51+
52+
// DefaultMaxGCEPDVolumes defines the maximum number of PD Volumes for GCE
53+
// GCE instances can have up to 16 PD volumes attached.
54+
DefaultMaxGCEPDVolumes = 16
55+
// DefaultMaxAzureDiskVolumes defines the maximum number of PD Volumes for Azure
56+
// Larger Azure VMs can actually have much more disks attached.
57+
// TODO We should determine the max based on VM size
58+
DefaultMaxAzureDiskVolumes = 16
59+
60+
// KubeMaxPDVols defines the maximum number of PD Volumes per kubelet
61+
KubeMaxPDVols = "KUBE_MAX_PD_VOLS"
62+
63+
// for EBSVolumeFilter
64+
EBSVolumeFilterType = "EBS"
65+
// for GCEPDVolumeFilter
66+
GCEPDVolumeFilterType = "GCE"
67+
// for AzureDiskVolumeFilter
68+
AzureDiskVolumeFilterType = "AzureDisk"
4869
)
4970

5071
// IMPORTANT NOTE for predicate developers:
@@ -193,13 +214,33 @@ type VolumeFilter struct {
193214
}
194215

195216
// NewMaxPDVolumeCountPredicate creates a predicate which evaluates whether a pod can fit based on the
196-
// number of volumes which match a filter that it requests, and those that are already present. The
197-
// maximum number is configurable to accommodate different systems.
217+
// number of volumes which match a filter that it requests, and those that are already present.
198218
//
199219
// The predicate looks for both volumes used directly, as well as PVC volumes that are backed by relevant volume
200220
// types, counts the number of unique volumes, and rejects the new pod if it would place the total count over
201221
// the maximum.
202-
func NewMaxPDVolumeCountPredicate(filter VolumeFilter, maxVolumes int, pvInfo PersistentVolumeInfo, pvcInfo PersistentVolumeClaimInfo) algorithm.FitPredicate {
222+
func NewMaxPDVolumeCountPredicate(filterName string, pvInfo PersistentVolumeInfo, pvcInfo PersistentVolumeClaimInfo) algorithm.FitPredicate {
223+
224+
var filter VolumeFilter
225+
var maxVolumes int
226+
227+
switch filterName {
228+
229+
case EBSVolumeFilterType:
230+
filter = EBSVolumeFilter
231+
maxVolumes = getMaxVols(aws.DefaultMaxEBSVolumes)
232+
case GCEPDVolumeFilterType:
233+
filter = GCEPDVolumeFilter
234+
maxVolumes = getMaxVols(DefaultMaxGCEPDVolumes)
235+
case AzureDiskVolumeFilterType:
236+
filter = AzureDiskVolumeFilter
237+
maxVolumes = getMaxVols(DefaultMaxAzureDiskVolumes)
238+
default:
239+
glog.Fatalf("Wrong filterName, Only Support %v %v %v ", EBSVolumeFilterType,
240+
GCEPDVolumeFilterType, AzureDiskVolumeFilterType)
241+
return nil
242+
243+
}
203244
c := &MaxPDVolumeCountChecker{
204245
filter: filter,
205246
maxVolumes: maxVolumes,
@@ -211,7 +252,23 @@ func NewMaxPDVolumeCountPredicate(filter VolumeFilter, maxVolumes int, pvInfo Pe
211252
return c.predicate
212253
}
213254

255+
// getMaxVols checks the max PD volumes environment variable, otherwise returning a default value
256+
func getMaxVols(defaultVal int) int {
257+
if rawMaxVols := os.Getenv(KubeMaxPDVols); rawMaxVols != "" {
258+
if parsedMaxVols, err := strconv.Atoi(rawMaxVols); err != nil {
259+
glog.Errorf("Unable to parse maximum PD volumes value, using default of %v: %v", defaultVal, err)
260+
} else if parsedMaxVols <= 0 {
261+
glog.Errorf("Maximum PD volumes must be a positive value, using default of %v", defaultVal)
262+
} else {
263+
return parsedMaxVols
264+
}
265+
}
266+
267+
return defaultVal
268+
}
269+
214270
func (c *MaxPDVolumeCountChecker) filterVolumes(volumes []v1.Volume, namespace string, filteredVolumes map[string]bool) error {
271+
215272
for i := range volumes {
216273
vol := &volumes[i]
217274
if id, ok := c.filter.FilterVolume(vol); ok {

plugin/pkg/scheduler/algorithm/predicates/predicates_test.go

+44-15
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ package predicates
1818

1919
import (
2020
"fmt"
21+
"os"
2122
"reflect"
23+
"strconv"
2224
"testing"
2325

2426
"k8s.io/api/core/v1"
@@ -1989,24 +1991,11 @@ func TestEBSVolumeCountConflicts(t *testing.T) {
19891991
},
19901992
}
19911993

1992-
filter := VolumeFilter{
1993-
FilterVolume: func(vol *v1.Volume) (string, bool) {
1994-
if vol.AWSElasticBlockStore != nil {
1995-
return vol.AWSElasticBlockStore.VolumeID, true
1996-
}
1997-
return "", false
1998-
},
1999-
FilterPersistentVolume: func(pv *v1.PersistentVolume) (string, bool) {
2000-
if pv.Spec.AWSElasticBlockStore != nil {
2001-
return pv.Spec.AWSElasticBlockStore.VolumeID, true
2002-
}
2003-
return "", false
2004-
},
2005-
}
20061994
expectedFailureReasons := []algorithm.PredicateFailureReason{ErrMaxVolumeCountExceeded}
20071995

20081996
for _, test := range tests {
2009-
pred := NewMaxPDVolumeCountPredicate(filter, test.maxVols, pvInfo, pvcInfo)
1997+
os.Setenv(KubeMaxPDVols, strconv.Itoa(test.maxVols))
1998+
pred := NewMaxPDVolumeCountPredicate(EBSVolumeFilterType, pvInfo, pvcInfo)
20101999
fits, reasons, err := pred(test.newPod, PredicateMetadata(test.newPod, nil), schedulercache.NewNodeInfo(test.existingPods...))
20112000
if err != nil {
20122001
t.Errorf("%s: unexpected error: %v", test.test, err)
@@ -3893,3 +3882,43 @@ func TestVolumeZonePredicateMultiZone(t *testing.T) {
38933882

38943883
}
38953884
}
3885+
3886+
func TestGetMaxVols(t *testing.T) {
3887+
previousValue := os.Getenv(KubeMaxPDVols)
3888+
defaultValue := 39
3889+
3890+
tests := []struct {
3891+
rawMaxVols string
3892+
expected int
3893+
test string
3894+
}{
3895+
{
3896+
rawMaxVols: "invalid",
3897+
expected: defaultValue,
3898+
test: "Unable to parse maximum PD volumes value, using default value",
3899+
},
3900+
{
3901+
rawMaxVols: "-2",
3902+
expected: defaultValue,
3903+
test: "Maximum PD volumes must be a positive value, using default value",
3904+
},
3905+
{
3906+
rawMaxVols: "40",
3907+
expected: 40,
3908+
test: "Parse maximum PD volumes value from env",
3909+
},
3910+
}
3911+
3912+
for _, test := range tests {
3913+
os.Setenv(KubeMaxPDVols, test.rawMaxVols)
3914+
result := getMaxVols(defaultValue)
3915+
if result != test.expected {
3916+
t.Errorf("%s: expected %v got %v", test.test, test.expected, result)
3917+
}
3918+
}
3919+
3920+
os.Unsetenv(KubeMaxPDVols)
3921+
if previousValue != "" {
3922+
os.Setenv(KubeMaxPDVols, previousValue)
3923+
}
3924+
}

plugin/pkg/scheduler/algorithmprovider/defaults/BUILD

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ go_library(
1111
srcs = ["defaults.go"],
1212
importpath = "k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults",
1313
deps = [
14-
"//pkg/cloudprovider/providers/aws:go_default_library",
1514
"//pkg/features:go_default_library",
1615
"//plugin/pkg/scheduler/algorithm:go_default_library",
1716
"//plugin/pkg/scheduler/algorithm/predicates:go_default_library",

plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go

+5-37
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,9 @@ limitations under the License.
1717
package defaults
1818

1919
import (
20-
"os"
21-
"strconv"
22-
2320
"k8s.io/apimachinery/pkg/util/sets"
2421
utilfeature "k8s.io/apiserver/pkg/util/feature"
25-
"k8s.io/kubernetes/pkg/cloudprovider/providers/aws"
22+
2623
"k8s.io/kubernetes/pkg/features"
2724
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm"
2825
"k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates"
@@ -34,19 +31,11 @@ import (
3431
)
3532

3633
const (
37-
// DefaultMaxGCEPDVolumes defines the maximum number of PD Volumes for GCE
38-
// GCE instances can have up to 16 PD volumes attached.
39-
DefaultMaxGCEPDVolumes = 16
40-
// DefaultMaxAzureDiskVolumes defines the maximum number of PD Volumes for Azure
41-
// Larger Azure VMs can actually have much more disks attached.
42-
// TODO We should determine the max based on VM size
43-
DefaultMaxAzureDiskVolumes = 16
34+
4435
// ClusterAutoscalerProvider defines the default autoscaler provider
4536
ClusterAutoscalerProvider = "ClusterAutoscalerProvider"
4637
// StatefulSetKind defines the name of 'StatefulSet' kind
4738
StatefulSetKind = "StatefulSet"
48-
// KubeMaxPDVols defines the maximum number of PD Volumes per kubelet
49-
KubeMaxPDVols = "KUBE_MAX_PD_VOLS"
5039
)
5140

5241
func init() {
@@ -133,27 +122,21 @@ func defaultPredicates() sets.String {
133122
factory.RegisterFitPredicateFactory(
134123
"MaxEBSVolumeCount",
135124
func(args factory.PluginFactoryArgs) algorithm.FitPredicate {
136-
// TODO: allow for generically parameterized scheduler predicates, because this is a bit ugly
137-
maxVols := getMaxVols(aws.DefaultMaxEBSVolumes)
138-
return predicates.NewMaxPDVolumeCountPredicate(predicates.EBSVolumeFilter, maxVols, args.PVInfo, args.PVCInfo)
125+
return predicates.NewMaxPDVolumeCountPredicate(predicates.EBSVolumeFilterType, args.PVInfo, args.PVCInfo)
139126
},
140127
),
141128
// Fit is determined by whether or not there would be too many GCE PD volumes attached to the node
142129
factory.RegisterFitPredicateFactory(
143130
"MaxGCEPDVolumeCount",
144131
func(args factory.PluginFactoryArgs) algorithm.FitPredicate {
145-
// TODO: allow for generically parameterized scheduler predicates, because this is a bit ugly
146-
maxVols := getMaxVols(DefaultMaxGCEPDVolumes)
147-
return predicates.NewMaxPDVolumeCountPredicate(predicates.GCEPDVolumeFilter, maxVols, args.PVInfo, args.PVCInfo)
132+
return predicates.NewMaxPDVolumeCountPredicate(predicates.GCEPDVolumeFilterType, args.PVInfo, args.PVCInfo)
148133
},
149134
),
150135
// Fit is determined by whether or not there would be too many Azure Disk volumes attached to the node
151136
factory.RegisterFitPredicateFactory(
152137
"MaxAzureDiskVolumeCount",
153138
func(args factory.PluginFactoryArgs) algorithm.FitPredicate {
154-
// TODO: allow for generically parameterized scheduler predicates, because this is a bit ugly
155-
maxVols := getMaxVols(DefaultMaxAzureDiskVolumes)
156-
return predicates.NewMaxPDVolumeCountPredicate(predicates.AzureDiskVolumeFilter, maxVols, args.PVInfo, args.PVCInfo)
139+
return predicates.NewMaxPDVolumeCountPredicate(predicates.AzureDiskVolumeFilterType, args.PVInfo, args.PVCInfo)
157140
},
158141
),
159142
// Fit is determined by inter-pod affinity.
@@ -262,21 +245,6 @@ func defaultPriorities() sets.String {
262245
)
263246
}
264247

265-
// getMaxVols checks the max PD volumes environment variable, otherwise returning a default value
266-
func getMaxVols(defaultVal int) int {
267-
if rawMaxVols := os.Getenv(KubeMaxPDVols); rawMaxVols != "" {
268-
if parsedMaxVols, err := strconv.Atoi(rawMaxVols); err != nil {
269-
glog.Errorf("Unable to parse maximum PD volumes value, using default of %v: %v", defaultVal, err)
270-
} else if parsedMaxVols <= 0 {
271-
glog.Errorf("Maximum PD volumes must be a positive value, using default of %v", defaultVal)
272-
} else {
273-
return parsedMaxVols
274-
}
275-
}
276-
277-
return defaultVal
278-
}
279-
280248
func copyAndReplace(set sets.String, replaceWhat, replaceWith string) sets.String {
281249
result := sets.NewString(set.List()...)
282250
if result.Has(replaceWhat) {

plugin/pkg/scheduler/algorithmprovider/defaults/defaults_test.go

-41
Original file line numberDiff line numberDiff line change
@@ -17,52 +17,11 @@ limitations under the License.
1717
package defaults
1818

1919
import (
20-
"os"
2120
"testing"
2221

2322
"k8s.io/apimachinery/pkg/util/sets"
2423
)
2524

26-
func TestGetMaxVols(t *testing.T) {
27-
previousValue := os.Getenv(KubeMaxPDVols)
28-
defaultValue := 39
29-
30-
tests := []struct {
31-
rawMaxVols string
32-
expected int
33-
test string
34-
}{
35-
{
36-
rawMaxVols: "invalid",
37-
expected: defaultValue,
38-
test: "Unable to parse maximum PD volumes value, using default value",
39-
},
40-
{
41-
rawMaxVols: "-2",
42-
expected: defaultValue,
43-
test: "Maximum PD volumes must be a positive value, using default value",
44-
},
45-
{
46-
rawMaxVols: "40",
47-
expected: 40,
48-
test: "Parse maximum PD volumes value from env",
49-
},
50-
}
51-
52-
for _, test := range tests {
53-
os.Setenv(KubeMaxPDVols, test.rawMaxVols)
54-
result := getMaxVols(defaultValue)
55-
if result != test.expected {
56-
t.Errorf("%s: expected %v got %v", test.test, test.expected, result)
57-
}
58-
}
59-
60-
os.Unsetenv(KubeMaxPDVols)
61-
if previousValue != "" {
62-
os.Setenv(KubeMaxPDVols, previousValue)
63-
}
64-
}
65-
6625
func TestCopyAndReplace(t *testing.T) {
6726
testCases := []struct {
6827
set sets.String

0 commit comments

Comments
 (0)