Hi.
I still can't find the way to add PluginArgs in my plugin.
I absolutely need the community help.
I did all things what I understand from the following guides.
But my-scheduler still occurs error as belows :
bandwidth_fit.go:117] NewBandwidthFit called
couldn't create scheduler using provider "DefaultProvider": initializing profiles: creating profile for scheduler name my-scheduler: error initializing plugin "NodeBandwidthFit": want args to be of type BandwidthFitArgs, got *runtime.Unknown%!(EXTRA bool=false)
I attached scheduler-config.yaml and my code and diffs from the out-of-tree scheduler.
Would you let me know how I can add PluginArgs for my plugin ?
My plugin's source tree is :
I attached the bandwidth_fit.go file on the last section.
My scheduler-config.yaml file is :
=======================================
kind: KubeSchedulerConfiguration
leaderElection:
leaderElect: false
clientConnection:
kubeconfig: "/etc/kubernetes/scheduler.conf"
profiles:
- schedulerName: my-scheduler
plugins:
preFilter:
enabled:
- name: NodeBandwidthFit
filter:
enabled:
- name: NodeBandwidthFit
score:
enabled:
- name: NodeBandwidthFit
pluginConfig:
- name: NodeBandwidthFit
args:
nodeBandwidth: "1Gi"
reservedBandwidthForSystem: "100Mi"
=======================================
Belows are diffs of source codes.
===================================================================
--- cmd/scheduler/main.go (revision 248)
+++ cmd/scheduler/main.go (working copy)
@@ -29,6 +29,7 @@
// Ensure scheme package is initialized.
@@ -47,7 +48,8 @@
app.WithPlugin(crossnodepreemption.Name, crossnodepreemption.New),
app.WithPlugin(podstate.Name, podstate.New),
app.WithPlugin(qos.Name, qos.New),
- app.WithPlugin(noderesources.BandwidthFitName, noderesources.NewBandwidthFit),
+ app.WithPlugin(bandwidth.BandwidthFitName, bandwidth.NewBandwidthFit),
+ //app.WithPlugin(noderesources.BandwidthFitName, noderesources.NewBandwidthFit),
)
===================================================================
--- pkg/apis/config/register.go (revision 248)
+++ pkg/apis/config/register.go (working copy)
@@ -40,6 +40,7 @@
&CoschedulingArgs{},
&NodeResourcesAllocatableArgs{},
&CapacitySchedulingArgs{},
+ &BandwidthFitArgs{},
)
return nil
}
===================================================================
--- pkg/apis/config/types.go (revision 248)
+++ pkg/apis/config/types.go (working copy)
@@ -73,3 +73,13 @@
// KubeConfigPath is the path of kubeconfig.
KubeConfigPath string
}
+
+
+// BandwidthFitArgs defines the scheduling parameters for BandwidthFit plugin.
+type BandwidthFitArgs struct {
+ metav1.TypeMeta
+
+ NodeBandwidth string `json:"nodeBandwidth,omitempty"`
+ ReservedBandwidthForSystem string `json:"reservedBandwidthForSystem,omitempty"`
+}
===================================================================
--- pkg/apis/config/v1beta1/defaults.go (revision 248)
+++ pkg/apis/config/v1beta1/defaults.go (working copy)
@@ -38,6 +38,9 @@
}
defaultKubeConfigPath string = "/etc/kubernetes/scheduler.conf"
+
+ defaultNodeBandwidth string ="1Gi"
+ defaultReservedBandwidthForSystem string="100Mi"
)
// SetDefaultsCoschedulingArgs sets the default parameters for Coscheduling plugin.
@@ -69,3 +72,13 @@
obj.KubeConfigPath = &defaultKubeConfigPath
}
}
+
+// SetDefaultsBandwidthFitArgs sets the default parameters for BandwidthFit plugin.
+func SetDefaultsBandwidthFitArgs(obj *BandwidthFitArgs) {
+ if obj.NodeBandwidth == nil {
+ obj.NodeBandwidth = &defaultNodeBandwidth
+ }
+ if obj.ReservedBandwidthForSystem == nil {
+ obj.ReservedBandwidthForSystem = &defaultReservedBandwidthForSystem
+ }
+}
===================================================================
--- pkg/apis/config/v1beta1/register.go (revision 248)
+++ pkg/apis/config/v1beta1/register.go (working copy)
@@ -40,6 +40,7 @@
&CoschedulingArgs{},
&NodeResourcesAllocatableArgs{},
&CapacitySchedulingArgs{},
+ &BandwidthFitArgs{},
)
return nil
}
===================================================================
--- pkg/apis/config/v1beta1/types.go (revision 248)
+++ pkg/apis/config/v1beta1/types.go (working copy)
@@ -73,3 +73,13 @@
// KubeConfigPath is the path of kubeconfig.
KubeConfigPath *string `json:"kubeConfigPath,omitempty"`
}
+
+
+// BandwidthFitArgs defines the scheduling parameters for NodeBandwidthFit plugin.
+type BandwidthFitArgs struct {
+ metav1.TypeMeta `json:",inline"`
+
+ NodeBandwidth *string `json:"nodeBandwidth,omitempty"`
+ ReservedBandwidthForSystem *string `json:"reservedBandwidthForSystem,omitempty"`
+}
===================================================================
--- pkg/apis/config/v1beta1/zz_generated.conversion.go (revision 248)
+++ pkg/apis/config/v1beta1/zz_generated.conversion.go (working copy)
@@ -37,6 +37,16 @@
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(s *runtime.Scheme) error {
+ if err := s.AddGeneratedConversionFunc((*BandwidthFitArgs)(nil), (*config.BandwidthFitArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_v1beta1_BandwidthFitArgs_To_config_BandwidthFitArgs(a.(*BandwidthFitArgs), b.(*config.BandwidthFitArgs), scope)
+ }); err != nil {
+ return err
+ }
+ if err := s.AddGeneratedConversionFunc((*config.BandwidthFitArgs)(nil), (*BandwidthFitArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
+ return Convert_config_BandwidthFitArgs_To_v1beta1_BandwidthFitArgs(a.(*config.BandwidthFitArgs), b.(*BandwidthFitArgs), scope)
+ }); err != nil {
+ return err
+ }
if err := s.AddGeneratedConversionFunc((*CapacitySchedulingArgs)(nil), (*config.CapacitySchedulingArgs)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1beta1_CapacitySchedulingArgs_To_config_CapacitySchedulingArgs(a.(*CapacitySchedulingArgs), b.(*config.CapacitySchedulingArgs), scope)
}); err != nil {
@@ -70,6 +80,36 @@
return nil
}
+func autoConvert_v1beta1_BandwidthFitArgs_To_config_BandwidthFitArgs(in *BandwidthFitArgs, out *config.BandwidthFitArgs, s conversion.Scope) error {
+ if err := v1.Convert_Pointer_string_To_string(&in.NodeBandwidth, &out.NodeBandwidth, s); err != nil {
+ return err
+ }
+ if err := v1.Convert_Pointer_string_To_string(&in.ReservedBandwidthForSystem, &out.ReservedBandwidthForSystem, s); err != nil {
+ return err
+ }
+ return nil
+}
+
+// Convert_v1beta1_BandwidthFitArgs_To_config_BandwidthFitArgs is an autogenerated conversion function.
+func Convert_v1beta1_BandwidthFitArgs_To_config_BandwidthFitArgs(in *BandwidthFitArgs, out *config.BandwidthFitArgs, s conversion.Scope) error {
+ return autoConvert_v1beta1_BandwidthFitArgs_To_config_BandwidthFitArgs(in, out, s)
+}
+
+func autoConvert_config_BandwidthFitArgs_To_v1beta1_BandwidthFitArgs(in *config.BandwidthFitArgs, out *BandwidthFitArgs, s conversion.Scope) error {
+ if err := v1.Convert_string_To_Pointer_string(&in.NodeBandwidth, &out.NodeBandwidth, s); err != nil {
+ return err
+ }
+ if err := v1.Convert_string_To_Pointer_string(&in.ReservedBandwidthForSystem, &out.ReservedBandwidthForSystem, s); err != nil {
+ return err
+ }
+ return nil
+}
+
+// Convert_config_BandwidthFitArgs_To_v1beta1_BandwidthFitArgs is an autogenerated conversion function.
+func Convert_config_BandwidthFitArgs_To_v1beta1_BandwidthFitArgs(in *config.BandwidthFitArgs, out *BandwidthFitArgs, s conversion.Scope) error {
+ return autoConvert_config_BandwidthFitArgs_To_v1beta1_BandwidthFitArgs(in, out, s)
+}
+
func autoConvert_v1beta1_CapacitySchedulingArgs_To_config_CapacitySchedulingArgs(in *CapacitySchedulingArgs, out *config.CapacitySchedulingArgs, s conversion.Scope) error {
if err := v1.Convert_Pointer_string_To_string(&in.KubeConfigPath, &out.KubeConfigPath, s); err != nil {
return err
===================================================================
--- pkg/apis/config/v1beta1/zz_generated.deepcopy.go (revision 248)
+++ pkg/apis/config/v1beta1/zz_generated.deepcopy.go (working copy)
@@ -26,6 +26,41 @@
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BandwidthFitArgs) DeepCopyInto(out *BandwidthFitArgs) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ if in.NodeBandwidth != nil {
+ in, out := &in.NodeBandwidth, &out.NodeBandwidth
+ *out = new(string)
+ **out = **in
+ }
+ if in.ReservedBandwidthForSystem != nil {
+ in, out := &in.ReservedBandwidthForSystem, &out.ReservedBandwidthForSystem
+ *out = new(string)
+ **out = **in
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BandwidthFitArgs.
+func (in *BandwidthFitArgs) DeepCopy() *BandwidthFitArgs {
+ if in == nil {
+ return nil
+ }
+ out := new(BandwidthFitArgs)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *BandwidthFitArgs) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CapacitySchedulingArgs) DeepCopyInto(out *CapacitySchedulingArgs) {
*out = *in
out.TypeMeta = in.TypeMeta
@@ -69,6 +104,16 @@
*out = new(int64)
**out = **in
}
+ if in.KubeMaster != nil {
+ in, out := &in.KubeMaster, &out.KubeMaster
+ *out = new(string)
+ **out = **in
+ }
+ if in.KubeConfigPath != nil {
+ in, out := &in.KubeConfigPath, &out.KubeConfigPath
+ *out = new(string)
+ **out = **in
+ }
return
}
Index: pkg/apis/config/v1beta1/zz_generated.defaults.go
===================================================================
--- pkg/apis/config/v1beta1/zz_generated.defaults.go (revision 248)
+++ pkg/apis/config/v1beta1/zz_generated.defaults.go (working copy)
@@ -28,22 +28,5 @@
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
- scheme.AddTypeDefaultingFunc(&CapacitySchedulingArgs{}, func(obj interface{}) { SetObjectDefaultsCapacitySchedulingArgs(obj.(*CapacitySchedulingArgs)) })
- scheme.AddTypeDefaultingFunc(&CoschedulingArgs{}, func(obj interface{}) { SetObjectDefaultsCoschedulingArgs(obj.(*CoschedulingArgs)) })
- scheme.AddTypeDefaultingFunc(&NodeResourcesAllocatableArgs{}, func(obj interface{}) {
- SetObjectDefaultsNodeResourcesAllocatableArgs(obj.(*NodeResourcesAllocatableArgs))
- })
return nil
}
-
-func SetObjectDefaultsCapacitySchedulingArgs(in *CapacitySchedulingArgs) {
- SetDefaultsCapacitySchedulingArgs(in)
-}
-
-func SetObjectDefaultsCoschedulingArgs(in *CoschedulingArgs) {
- SetDefaultsCoschedulingArgs(in)
-}
-
-func SetObjectDefaultsNodeResourcesAllocatableArgs(in *NodeResourcesAllocatableArgs) {
- SetDefaultsNodeResourcesAllocatableArgs(in)
-}
Index: pkg/apis/config/zz_generated.deepcopy.go
===================================================================
--- pkg/apis/config/zz_generated.deepcopy.go (revision 248)
+++ pkg/apis/config/zz_generated.deepcopy.go (working copy)
@@ -26,6 +26,31 @@
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BandwidthFitArgs) DeepCopyInto(out *BandwidthFitArgs) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BandwidthFitArgs.
+func (in *BandwidthFitArgs) DeepCopy() *BandwidthFitArgs {
+ if in == nil {
+ return nil
+ }
+ out := new(BandwidthFitArgs)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *BandwidthFitArgs) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CapacitySchedulingArgs) DeepCopyInto(out *CapacitySchedulingArgs) {
*out = *in
out.TypeMeta = in.TypeMeta
--------------------------------------------------------------------------------
This is the bandwidth_fit.go !
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package bandwidth
import (
"context"
"fmt"
/*
"strings"
*/
)
var _ framework.PreFilterPlugin = &BandwidthFit{}
var _ framework.FilterPlugin = &BandwidthFit{}
var _ framework.ScorePlugin = &BandwidthFit{}
const (
// BandwidthFitName is the name of the plugin used in the plugin registry and configurations.
BandwidthFitName = "NodeBandwidthFit"
DefaultNodeBandwidth int64 = 1*1024*1024*1024 // 1Gbps : Default Node Bandwidth
DefaultReservedBandwidthForSystem int64 = 100*1024*1024 // 100Mbps
preFilterStateKey = "Filter" + BandwidthFitName
)
// BandwidthFit is a plugin that checks if a node has sufficient egress bandwidth resources.
type BandwidthFit struct {
handle framework.FrameworkHandle
nodeBandwidth int64
reservedBandwidth int64
}
// preFilterState computed at preFilter and used at Filter
// nodeAllocatedBandwidth[] computed at Filter and used at Score
type preFilterState struct {
podName string // pod Name
requestedBandwidth int64 // bandwidth reqeust of the pod
qosClass PodQOSClass
nodeAllocatedBandwidth map[string]int64 // Allocated Bandwidth sum of each node, map[key] : nodeName
}
// Clone the prefilter state
func (s *preFilterState) Clone() framework.StateData {
return s
}
// Name returns name of the plugin. It is used in logs, etc.
func (f *BandwidthFit) Name() string {
return BandwidthFitName
}
func validateBandwidthArgs(args *config.BandwidthFitArgs) (nodeBandwidth int64, reservedBandwidth int64, e error) {
return 0, 0, nil
nodeBW, err := resource.ParseQuantity(args.NodeBandwidth)
if err != nil {
return 0, 0, fmt.Errorf("cannot parse nodeBandwidth %v", args.NodeBandwidth)
}
if err := validateBandwidthIsReasonable(&nodeBW); err != nil {
return 0, 0, fmt.Errorf("invalid range nodeBandwidth %v", nodeBW)
}
nodeBandwidth = int64(nodeBW.Value())
reservedBW, err := resource.ParseQuantity(args.ReservedBandwidthForSystem)
if err != nil {
return 0, 0, fmt.Errorf("cannot parse ReservedBandwidthForSystem %v", args.ReservedBandwidthForSystem)
}
if err := validateBandwidthIsReasonable(&reservedBW); err != nil {
return 0, 0, fmt.Errorf("invalid range ReservedBandwidthForSystem %v", reservedBW)
}
reservedBandwidth = int64(reservedBW.Value())
return nodeBandwidth, reservedBandwidth, nil
}
// NewBandwidthFit initializes a new plugin and returns it.
func NewBandwidthFit(plArgs runtime.Object, h framework.FrameworkHandle) (framework.Plugin, error) {
klog.V(2).Infof("NewBandwidthFit called")
var nodeBandwidth int64 = 0
var reservedBandwidth int64 = 0
var err error
if plArgs != nil {
args, ok := plArgs.(*config.BandwidthFitArgs)
if !ok {
return nil, fmt.Errorf("want args to be of type BandwidthFitArgs, got %T", plArgs, ok)
}
// validating arguments
nodeBandwidth, reservedBandwidth, err = validateBandwidthArgs(args)
if err != nil {
return nil, err
}
} else {
klog.V(2).Infof("NewBandwidthFit plArgs is nil")
}
if nodeBandwidth == 0 { nodeBandwidth = DefaultNodeBandwidth }
if reservedBandwidth == 0 { reservedBandwidth = DefaultReservedBandwidthForSystem }
klog.V(2).Infof("NewBandwidthFit: nodeBW(%d), reservedBW(%d)", nodeBandwidth, reservedBandwidth)
return &BandwidthFit{
handle: h,
nodeBandwidth: nodeBandwidth,
reservedBandwidth: reservedBandwidth,
}, nil
}
// PreFilter invoked at the prefilter extension point.
func (f *BandwidthFit) PreFilter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod) *framework.Status {
//klog.V(2).Infof("PreFilter called")
state := &preFilterState{
nodeAllocatedBandwidth: make(map[string]int64),
}
egressRequest, egressLimit, err := ExtractPodBandwidthResources(pod.ObjectMeta.Annotations)
if err != nil {
return framework.NewStatus(framework.Error, fmt.Sprintf("getting pod %q bandwidth request %v",
pod.ObjectMeta.Name, err))
}
var requestedBandwidth int64 = 0
if egressLimit != 0 {
requestedBandwidth = egressLimit
} else if egressRequest != 0 {
requestedBandwidth = egressRequest
}
state.requestedBandwidth = requestedBandwidth
var qosClass PodQOSClass
if egressRequest == 0 && egressLimit == 0 {
qosClass = PodQOSBestEffort
} else if egressRequest == egressLimit {
qosClass = PodQOSGuaranteed
} else {
qosClass = PodQOSBurstable
}
state.qosClass = qosClass
klog.V(2).Infof("PreFilter: pod %q, egressRequest: %d, egressLimit: %d, requestedBW: %d, qosClass: %q",
pod.ObjectMeta.Name, egressRequest, egressLimit, requestedBandwidth, qosClass)
cycleState.Write(preFilterStateKey, state)
return nil
}
func getPreFilterState(cycleState *framework.CycleState) (*preFilterState, error) {
c, err := cycleState.Read(preFilterStateKey)
if err != nil {
// preFilterState doesn't exist, likely PreFilter wasn't invoked.
return nil, fmt.Errorf("error reading %q from cycleState: %v", preFilterStateKey, err)
}
s, ok := c.(*preFilterState)
if !ok {
return nil, fmt.Errorf("%+v convert to BandwidthFit.preFilterState error", c)
}
return s, nil
}
// PreFilterExtensions returns prefilter extensions, pod add and remove.
func (f *BandwidthFit) PreFilterExtensions() framework.PreFilterExtensions {
return nil
}
// Score invoked at the score extension point.
func (f *BandwidthFit) Score(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodeName string) (int64, *framework.Status) {
/*
nodeInfo, err := f.handle.SnapshotSharedLister().NodeInfos().Get(nodeName)
if err != nil {
return 0, framework.NewStatus(framework.Error, fmt.Sprintf("getting node %q from Snapshot: %v", nodeName, err))
}
*/
state, err := getPreFilterState(cycleState)
if err != nil {
return 0, framework.NewStatus(framework.Error, err.Error())
}
// we favor the node which the bandwidth will be used less.
var score int64
score = ( f.nodeBandwidth - (state.nodeAllocatedBandwidth[nodeName] + state.requestedBandwidth + f.reservedBandwidth) ) * framework.MaxNodeScore / f.nodeBandwidth
klog.V(2).Infof("Score: Score of Node %q for Pod %q : %d(DefaultBW(%d), reqeustedBW(%d), allocatedBW(%d)", nodeName,
pod.ObjectMeta.Name, score, f.nodeBandwidth, state.requestedBandwidth, state.nodeAllocatedBandwidth[nodeName])
return score, nil
}
// ScoreExtensions of the Score plugin.
func (f *BandwidthFit) ScoreExtensions() framework.ScoreExtensions {
return f
}
// NormalizeScore invoked after scoring all nodes.
func (f *BandwidthFit) NormalizeScore(ctx context.Context, state *framework.CycleState, pod *v1.Pod, scores framework.NodeScoreList) *framework.Status {
return pluginhelper.DefaultNormalizeScore(framework.MaxNodeScore, false, scores)
}
// Filter invoked at the filter extension point.
// Checks if a node has sufficient egress bandwidth resource to run a pod.
// It returns a list of insufficient resources, if empty, then the node has all the resources requested by the pod.
func (f *BandwidthFit) Filter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status {
klog.V(2).Infof("BandwidthFit Filter called")
state, err := getPreFilterState(cycleState)
if err != nil {
return framework.NewStatus(framework.Error, err.Error())
}
insufficientResources := f.fitsRequest(state, cycleState, pod, nodeInfo)
if len(insufficientResources) != 0 {
// We will keep all failure reasons.
failureReasons := make([]string, 0, len(insufficientResources))
for _, r := range insufficientResources {
failureReasons = append(failureReasons, r.Reason)
}
return framework.NewStatus(framework.Unschedulable, failureReasons...)
}
return nil
}
// InsufficientResource describes what kind of resource limit is hit and caused the pod to not fit the node.
type InsufficientResource struct {
ResourceName v1.ResourceName
// We explicitly have a parameter for reason to avoid formatting a message on the fly
// for common resources, which is expensive for cluster autoscaler simulations.
Reason string
Requested int64
Used int64
Capacity int64
}
// PodQOSClass defines the supported qos classes of Pods.
type PodQOSClass string
// These are valid values for PodQOSClass
const (
// PodQOSGuaranteed is the Guaranteed qos class.
PodQOSGuaranteed PodQOSClass = "Guaranteed"
// PodQOSBurstable is the Burstable qos class.
PodQOSBurstable PodQOSClass = "Burstable"
// PodQOSBestEffort is the BestEffort qos class.
PodQOSBestEffort PodQOSClass = "BestEffort"
)
func (f *BandwidthFit) fitsRequest(state *preFilterState, cycleState *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) []InsufficientResource {
insufficientResources := make([]InsufficientResource, 0, 1)
if state.requestedBandwidth == 0 {
return insufficientResources
}
var bandwidthSum int64 = 0
for _, pod := range nodeInfo.Pods {
request, limit, err := ExtractPodBandwidthResources(pod.Pod.ObjectMeta.Annotations)
if err != nil {
continue
}
if limit != 0 {
bandwidthSum += limit
} else if request != 0 {
bandwidthSum += request
}
}
klog.V(2).Infof("fitsReqeust: pod %q, requestedBW(%d), qosClass(%q), node %q, DefaultNodeBW(%d), allocatedBW(%d)",
pod.ObjectMeta.Name, state.requestedBandwidth, state.qosClass, nodeInfo.Node().ObjectMeta.Name, f.nodeBandwidth, bandwidthSum)
if (state.requestedBandwidth + bandwidthSum + f.reservedBandwidth) > f.nodeBandwidth &&
state.qosClass == PodQOSGuaranteed {
insufficientResources = append(insufficientResources, InsufficientResource{
"nodeBandwidth",
"Insufficient bandwidth",
state.requestedBandwidth,
bandwidthSum,
f.nodeBandwidth - bandwidthSum - f.reservedBandwidth,
})
}
state.nodeAllocatedBandwidth[nodeInfo.Node().ObjectMeta.Name] = bandwidthSum
cycleState.Write(preFilterStateKey, state)
return insufficientResources
}
var minRsrc = resource.MustParse("1k")
var maxRsrc = resource.MustParse("1P")
func validateBandwidthIsReasonable(rsrc *resource.Quantity) error {
if rsrc.Value() < minRsrc.Value() {
return fmt.Errorf("resource is unreasonably small (< 1kbit)")
}
if rsrc.Value() > maxRsrc.Value() {
return fmt.Errorf("resoruce is unreasonably large (> 1Pbit)")
}
return nil
}
// ExtractPodBandwidthResources extracts the egress-request and egress-limit from the given pod annotations
func ExtractPodBandwidthResources(podAnnotations map[string]string) (request, limit int64, err error) {
var egressRequest, egressLimit *resource.Quantity
request = 0
limit = 0
if podAnnotations == nil {
return request, limit, nil
}
str, found := podAnnotations[BandwidthRequestKey]
if found {
egressRequestValue, err := resource.ParseQuantity(str)
if err != nil {
return request, limit, err
}
egressRequest = &egressRequestValue
if err := validateBandwidthIsReasonable(egressRequest); err != nil {
return request, limit, err
}
request = int64(egressRequest.Value())
}
str, found = podAnnotations[BandwidthLimitKey]
if found {
egressLimitValue, err := resource.ParseQuantity(str)
if err != nil {
return request, limit, err
}
egressLimit = &egressLimitValue
if err := validateBandwidthIsReasonable(egressLimit); err != nil {
return request, limit, err
}
limit = int64(egressLimit.Value())
}
return request, limit, nil
}