Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apis/config/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&NetworkOverheadArgs{},
&SySchedArgs{},
&PeaksArgs{},
&NodeMetadataArgs{},
)
return nil
}
Expand Down
90 changes: 90 additions & 0 deletions apis/config/scheme/scheme_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,78 @@ profiles:
},
},
},
{
name: "v1 NodeMetadata plugin args",
data: []byte(`
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: scheduler-plugins
pluginConfig:
- name: NodeMetadata
args:
metadataKey: "priority"
metadataSource: "Label"
metadataType: "Number"
scoringStrategy: "Highest"
`),
wantProfiles: []schedconfig.KubeSchedulerProfile{
{
SchedulerName: "scheduler-plugins",
Plugins: defaults.PluginsV1,
PluginConfig: []schedconfig.PluginConfig{
{
Name: "NodeMetadata",
Args: &config.NodeMetadataArgs{
MetadataKey: "priority",
MetadataSource: config.MetadataSourceLabel,
MetadataType: config.MetadataTypeNumber,
ScoringStrategy: config.ScoringStrategyHighest,
},
},
{
Name: "DefaultPreemption",
Args: &schedconfig.DefaultPreemptionArgs{MinCandidateNodesPercentage: 10, MinCandidateNodesAbsolute: 100},
},
{
Name: "DynamicResources",
Args: &schedconfig.DynamicResourcesArgs{
FilterTimeout: ptr.To(metav1.Duration{Duration: 10 * time.Second}),
},
},
{
Name: "InterPodAffinity",
Args: &schedconfig.InterPodAffinityArgs{HardPodAffinityWeight: 1},
},
{
Name: "NodeAffinity",
Args: &schedconfig.NodeAffinityArgs{},
},
{
Name: "NodeResourcesBalancedAllocation",
Args: &schedconfig.NodeResourcesBalancedAllocationArgs{Resources: []schedconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}}},
},
{
Name: "NodeResourcesFit",
Args: &schedconfig.NodeResourcesFitArgs{
ScoringStrategy: &schedconfig.ScoringStrategy{
Type: schedconfig.LeastAllocated,
Resources: []schedconfig.ResourceSpec{{Name: "cpu", Weight: 1}, {Name: "memory", Weight: 1}},
},
},
},
{
Name: "PodTopologySpread",
Args: &schedconfig.PodTopologySpreadArgs{DefaultingType: schedconfig.SystemDefaulting},
},
{
Name: "VolumeBinding",
Args: &schedconfig.VolumeBindingArgs{BindTimeoutSeconds: 600},
},
},
},
},
},
}
decoder := Codecs.UniversalDecoder()
for _, tt := range testCases {
Expand Down Expand Up @@ -348,6 +420,15 @@ func TestCodecsEncodePluginConfig(t *testing.T) {
NetworkTopologyName: "net-topology-v1",
},
},
{
Name: "NodeMetadata",
Args: &config.NodeMetadataArgs{
MetadataKey: "priority",
MetadataSource: config.MetadataSourceLabel,
MetadataType: config.MetadataTypeNumber,
ScoringStrategy: config.ScoringStrategyHighest,
},
},
},
},
},
Expand Down Expand Up @@ -445,6 +526,15 @@ profiles:
networkTopologyName: net-topology-v1
weightsName: netCosts
name: NetworkOverhead
- args:
apiVersion: kubescheduler.config.k8s.io/v1
kind: NodeMetadataArgs
metadataKey: priority
metadataSource: Label
metadataType: Number
scoringStrategy: Highest
timestampFormat: ""
name: NodeMetadata
schedulerName: scheduler-plugins
`,
},
Expand Down
66 changes: 66 additions & 0 deletions apis/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,69 @@ type PowerModel struct {
// Power = K0 + K1 * e ^(K2 * x) : where x is utilisation
// Idle power of node will be K0 + K1
}

// MetadataSourceType defines where to look for metadata
type MetadataSourceType string

const (
// MetadataSourceLabel indicates metadata should be read from node labels
MetadataSourceLabel MetadataSourceType = "Label"
// MetadataSourceAnnotation indicates metadata should be read from node annotations
MetadataSourceAnnotation MetadataSourceType = "Annotation"
)

// MetadataValueType defines the type of metadata value
type MetadataValueType string

const (
// MetadataTypeNumber indicates the metadata value is a numeric value
MetadataTypeNumber MetadataValueType = "Number"
// MetadataTypeTimestamp indicates the metadata value is a timestamp
MetadataTypeTimestamp MetadataValueType = "Timestamp"
)

// MetadataScoringStrategy defines how to score nodes based on metadata values
type MetadataScoringStrategy string

const (
// ScoringStrategyHighest favors nodes with highest numeric values
ScoringStrategyHighest MetadataScoringStrategy = "Highest"
// ScoringStrategyLowest favors nodes with lowest numeric values
ScoringStrategyLowest MetadataScoringStrategy = "Lowest"
// ScoringStrategyNewest favors nodes with newest (most recent) timestamps
ScoringStrategyNewest MetadataScoringStrategy = "Newest"
// ScoringStrategyOldest favors nodes with oldest timestamps
ScoringStrategyOldest MetadataScoringStrategy = "Oldest"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// NodeMetadataArgs holds arguments used to configure the NodeMetadata plugin.
type NodeMetadataArgs struct {
metav1.TypeMeta

// MetadataKey is the name of the label or annotation to use for scoring
MetadataKey string `json:"metadataKey"`

// MetadataSource indicates whether to read from labels or annotations
// Valid values: "Label", "Annotation"
MetadataSource MetadataSourceType `json:"metadataSource"`

// MetadataType indicates the type of value in the metadata
// Valid values: "Number", "Timestamp"
MetadataType MetadataValueType `json:"metadataType"`

// ScoringStrategy defines how nodes should be scored
// For Number type: "Highest" or "Lowest"
// For Timestamp type: "Newest" or "Oldest"
ScoringStrategy MetadataScoringStrategy `json:"scoringStrategy"`

// TimestampFormat is the Go time format string for parsing timestamps
// Only used when MetadataType is "Timestamp"
// Default: time.RFC3339 ("2006-01-02T15:04:05Z07:00")
// Examples:
// - RFC3339: "2006-01-02T15:04:05Z07:00"
// - Unix timestamp: Use MetadataType "Number" instead
// - Custom: "2006-01-02 15:04:05"
TimestampFormat string `json:"timestampFormat,omitempty"`
}
28 changes: 28 additions & 0 deletions apis/config/v1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,31 @@ func Convert_config_NodeResourceTopologyMatchArgs_To_v1_NodeResourceTopologyMatc
out.ScoringStrategy = (*ScoringStrategy)(unsafe.Pointer(&in.ScoringStrategy))
return nil
}

func Convert_v1_NodeMetadataArgs_To_config_NodeMetadataArgs(in *NodeMetadataArgs, out *config.NodeMetadataArgs, s conversion.Scope) error {
if err := autoConvert_v1_NodeMetadataArgs_To_config_NodeMetadataArgs(in, out, s); err != nil {
return err
}
// Manual conversions for enum types.
if in.MetadataSource != nil {
out.MetadataSource = *(*config.MetadataSourceType)(unsafe.Pointer(in.MetadataSource))
}
if in.MetadataType != nil {
out.MetadataType = *(*config.MetadataValueType)(unsafe.Pointer(in.MetadataType))
}
if in.ScoringStrategy != nil {
out.ScoringStrategy = *(*config.MetadataScoringStrategy)(unsafe.Pointer(in.ScoringStrategy))
}
return nil
}

func Convert_config_NodeMetadataArgs_To_v1_NodeMetadataArgs(in *config.NodeMetadataArgs, out *NodeMetadataArgs, s conversion.Scope) error {
if err := autoConvert_config_NodeMetadataArgs_To_v1_NodeMetadataArgs(in, out, s); err != nil {
return err
}
// Manual conversions for enum types.
out.MetadataSource = (*MetadataSourceType)(unsafe.Pointer(&in.MetadataSource))
out.MetadataType = (*MetadataValueType)(unsafe.Pointer(&in.MetadataType))
out.ScoringStrategy = (*MetadataScoringStrategy)(unsafe.Pointer(&in.ScoringStrategy))
return nil
}
10 changes: 10 additions & 0 deletions apis/config/v1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ package v1

import (
"strconv"
"time"

v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"

schedulerconfigv1 "k8s.io/kube-scheduler/config/v1"
k8sschedulerconfigv1 "k8s.io/kubernetes/pkg/scheduler/apis/config/v1"
)
Expand Down Expand Up @@ -250,3 +253,10 @@ func SetDefaults_SySchedArgs(obj *SySchedArgs) {
obj.DefaultProfileName = &DefaultSySchedProfileName
}
}

// SetDefaults_NodeMetadataArgs sets the default parameters for NodeMetadataArgs plugin.
func SetDefaults_NodeMetadataArgs(obj *NodeMetadataArgs) {
if obj.TimestampFormat == nil && obj.MetadataType != nil && *obj.MetadataType == MetadataTypeTimestamp {
obj.TimestampFormat = ptr.To(time.RFC3339)
}
}
1 change: 1 addition & 0 deletions apis/config/v1/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&NetworkOverheadArgs{},
&SySchedArgs{},
&PeaksArgs{},
&NodeMetadataArgs{},
)
return nil
}
Expand Down
66 changes: 66 additions & 0 deletions apis/config/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,69 @@ type PowerModel struct {
// Power = K0 + K1 * e ^(K2 * x) : where x is utilisation
// Idle power of node will be K0 + K1
}

// MetadataSourceType defines where to look for metadata
type MetadataSourceType string

const (
// MetadataSourceLabel indicates metadata should be read from node labels
MetadataSourceLabel MetadataSourceType = "Label"
// MetadataSourceAnnotation indicates metadata should be read from node annotations
MetadataSourceAnnotation MetadataSourceType = "Annotation"
)

// MetadataValueType defines the type of metadata value
type MetadataValueType string

const (
// MetadataTypeNumber indicates the metadata value is a numeric value
MetadataTypeNumber MetadataValueType = "Number"
// MetadataTypeTimestamp indicates the metadata value is a timestamp
MetadataTypeTimestamp MetadataValueType = "Timestamp"
)

// MetadataScoringStrategy defines how to score nodes based on metadata values
type MetadataScoringStrategy string

const (
// ScoringStrategyHighest favors nodes with highest numeric values
ScoringStrategyHighest MetadataScoringStrategy = "Highest"
// ScoringStrategyLowest favors nodes with lowest numeric values
ScoringStrategyLowest MetadataScoringStrategy = "Lowest"
// ScoringStrategyNewest favors nodes with newest (most recent) timestamps
ScoringStrategyNewest MetadataScoringStrategy = "Newest"
// ScoringStrategyOldest favors nodes with oldest timestamps
ScoringStrategyOldest MetadataScoringStrategy = "Oldest"
)

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// NodeMetadataArgs holds arguments used to configure the NodeMetadata plugin.
type NodeMetadataArgs struct {
metav1.TypeMeta `json:",inline"`

// MetadataKey is the name of the label or annotation to use for scoring
MetadataKey *string `json:"metadataKey,omitempty"`

// MetadataSource indicates whether to read from labels or annotations
// Valid values: "Label", "Annotation"
MetadataSource *MetadataSourceType `json:"metadataSource,omitempty"`

// MetadataType indicates the type of value in the metadata
// Valid values: "Number", "Timestamp"
MetadataType *MetadataValueType `json:"metadataType,omitempty"`

// ScoringStrategy defines how nodes should be scored
// For Number type: "Highest" or "Lowest"
// For Timestamp type: "Newest" or "Oldest"
ScoringStrategy *MetadataScoringStrategy `json:"scoringStrategy,omitempty"`

// TimestampFormat is the Go time format string for parsing timestamps
// Only used when MetadataType is "Timestamp"
// Default: time.RFC3339 ("2006-01-02T15:04:05Z07:00")
// Examples:
// - RFC3339: "2006-01-02T15:04:05Z07:00"
// - Unix timestamp: Use MetadataType "Number" instead
// - Custom: "2006-01-02 15:04:05"
TimestampFormat *string `json:"timestampFormat,omitempty"`
}
36 changes: 36 additions & 0 deletions apis/config/v1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading