From 9cee6cb97df28ab90bcf71261421d1d917d5d6fd Mon Sep 17 00:00:00 2001 From: Pawan Prakash Sharma Date: Tue, 8 Mar 2022 12:46:47 +0530 Subject: [PATCH] feat(scheduler): adding SpaceWeighted scheduler (#178) adding a new scheduler logic which selects the node which has max free space available. This is better scheduling algorithm than the volumeweighted and capacity weighted where we don't check for the free space available on the node. Signed-off-by: Pawan --- deploy/lvm-operator.yaml | 2 ++ pkg/driver/schd_helper.go | 47 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/deploy/lvm-operator.yaml b/deploy/lvm-operator.yaml index 7401b8f0..2f3a27ed 100644 --- a/deploy/lvm-operator.yaml +++ b/deploy/lvm-operator.yaml @@ -1160,7 +1160,9 @@ metadata: value: 900000000 globalDefault: false description: "This priority class should be used for the OpenEBS LVM localPV CSI driver controller deployment only." + --- + kind: StatefulSet apiVersion: apps/v1 metadata: diff --git a/pkg/driver/schd_helper.go b/pkg/driver/schd_helper.go index 8996f004..f26bdf83 100644 --- a/pkg/driver/schd_helper.go +++ b/pkg/driver/schd_helper.go @@ -17,11 +17,13 @@ limitations under the License. package driver import ( + "math" "regexp" "strconv" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/openebs/lvm-localpv/pkg/builder/nodebuilder" "github.com/openebs/lvm-localpv/pkg/builder/volbuilder" "github.com/openebs/lvm-localpv/pkg/lvm" ) @@ -32,8 +34,11 @@ const ( VolumeWeighted = "VolumeWeighted" // pick the node where total provisioned volumes have occupied less capacity from the given volume group - // this will be the default scheduler when none provided CapacityWeighted = "CapacityWeighted" + + // pick the node which is less loaded space wise + // this will be the default scheduler when none provided + SpaceWeightedMap = "SpaceWeighted" ) // getVolumeWeightedMap goes through all the volumegroup on all the nodes @@ -92,6 +97,40 @@ func getCapacityWeightedMap(re *regexp.Regexp) (map[string]int64, error) { return nmap, nil } +// getSpaceWeightedMap returns how weighted a node is space wise. +// The node which has max free space available is less loaded and +// can accumulate more volumes. +func getSpaceWeightedMap(re *regexp.Regexp) (map[string]int64, error) { + nmap := map[string]int64{} + + nodeList, err := nodebuilder.NewKubeclient(). + WithNamespace(lvm.LvmNamespace). + List(metav1.ListOptions{}) + + if err != nil { + return nmap, err + } + + for _, node := range nodeList.Items { + var maxFree int64 = 0 + for _, vg := range node.VolumeGroups { + if re.MatchString(vg.Name) { + freeCapacity := vg.Free.Value() + if maxFree < freeCapacity { + maxFree = freeCapacity + } + } + } + if maxFree > 0 { + // converting to SpaceWeighted by subtracting it with MaxInt64 + // as the node which has max free space available is less loaded. + nmap[node.Name] = math.MaxInt64 - maxFree + } + } + + return nmap, nil +} + // getNodeMap returns the node mapping for the given scheduling algorithm func getNodeMap(schd string, vgPattern *regexp.Regexp) (map[string]int64, error) { switch schd { @@ -99,7 +138,9 @@ func getNodeMap(schd string, vgPattern *regexp.Regexp) (map[string]int64, error) return getVolumeWeightedMap(vgPattern) case CapacityWeighted: return getCapacityWeightedMap(vgPattern) + case SpaceWeightedMap: + return getSpaceWeightedMap(vgPattern) } - // return CapacityWeighted(default) if not specified - return getCapacityWeightedMap(vgPattern) + // return getSpaceWeightedMap(default) if not specified + return getSpaceWeightedMap(vgPattern) }