Merge pull request #2390 from Poor12/set-default-model-for-cluster
Set default model for cluster
This commit is contained in:
commit
f6b7511906
|
@ -14057,16 +14057,22 @@
|
|||
"com.github.karmada-io.karmada.pkg.apis.cluster.v1alpha1.AllocatableModeling": {
|
||||
"description": "AllocatableModeling represents the number of nodes in which allocatable resources in a specific resource model grade. E.g. AllocatableModeling{Grade: 2, Count: 10} means 10 nodes belong to resource model in grade 2.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"grade",
|
||||
"count"
|
||||
],
|
||||
"properties": {
|
||||
"count": {
|
||||
"description": "Count is the number of nodes that own the resources delineated by this modeling.",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"grade": {
|
||||
"description": "Grade is the index of ResourceModel.",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -14291,11 +14297,16 @@
|
|||
"com.github.karmada-io.karmada.pkg.apis.cluster.v1alpha1.ResourceModel": {
|
||||
"description": "ResourceModel describes the modeling that you want to statistics.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"grade",
|
||||
"ranges"
|
||||
],
|
||||
"properties": {
|
||||
"grade": {
|
||||
"description": "Grade is the index for the resource modeling.",
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"ranges": {
|
||||
"description": "Ranges describes the resource quota ranges.",
|
||||
|
@ -14310,6 +14321,11 @@
|
|||
"com.github.karmada-io.karmada.pkg.apis.cluster.v1alpha1.ResourceModelRange": {
|
||||
"description": "ResourceModelRange describes the detail of each modeling quota that ranges from min to max. Please pay attention, by default, the value of min can be inclusive, and the value of max cannot be inclusive. E.g. in an interval, min = 2, max =10 is set, which means the interval [2,10). This rule ensure that all intervals have the same meaning. If the last interval is +∞, it is definitely unreachable. Therefore, we define the right interval as the open interval. For a valid interval, the value on the right is greater than the value on the left, in other words, max must be greater than min. It is strongly recommended that the [Min, Max) of all ResourceModelRanges can make a continuous interval.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"min",
|
||||
"max"
|
||||
],
|
||||
"properties": {
|
||||
"max": {
|
||||
"description": "Max is the maximum amount of this resource represented by resource name. Special Instructions, for the last ResourceModelRange, which no matter what Max value you pass, the meaning is infinite. Because for the last item, any ResourceModelRange's quota larger than Min will be classified to the last one. Of course, the value of the Max field is always greater than the value of the Min field. It should be true in any case.",
|
||||
|
@ -14323,7 +14339,8 @@
|
|||
},
|
||||
"name": {
|
||||
"description": "Name is the name for the resource that you want to categorize.",
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
|
||||
"github.com/karmada-io/karmada/pkg/aggregatedapiserver"
|
||||
clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
|
||||
pkgfeatures "github.com/karmada-io/karmada/pkg/features"
|
||||
clientset "github.com/karmada-io/karmada/pkg/generated/clientset/versioned"
|
||||
informers "github.com/karmada-io/karmada/pkg/generated/informers/externalversions"
|
||||
generatedopenapi "github.com/karmada-io/karmada/pkg/generated/openapi"
|
||||
|
@ -66,6 +67,7 @@ func (o *Options) AddFlags(flags *pflag.FlagSet) {
|
|||
|
||||
flags.Float32Var(&o.KubeAPIQPS, "kube-api-qps", 40.0, "QPS to use while talking with karmada-apiserver. Doesn't cover events and node heartbeat apis which rate limiting is controlled by a different set of flags.")
|
||||
flags.IntVar(&o.KubeAPIBurst, "kube-api-burst", 60, "Burst to use while talking with karmada-apiserver. Doesn't cover events and node heartbeat apis which rate limiting is controlled by a different set of flags.")
|
||||
_ = utilfeature.DefaultMutableFeatureGate.Add(pkgfeatures.DefaultFeatureGates)
|
||||
utilfeature.DefaultMutableFeatureGate.AddFlag(flags)
|
||||
o.ProfileOpts.AddFlags(flags)
|
||||
}
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
package mutation
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
clusterapis "github.com/karmada-io/karmada/pkg/apis/cluster"
|
||||
)
|
||||
|
||||
const (
|
||||
// GB is a conversion value from GB to Bytes.
|
||||
GB = 1024 * 1024 * 1024
|
||||
)
|
||||
|
||||
// MutateCluster mutates required fields of the Cluster.
|
||||
func MutateCluster(cluster *clusterapis.Cluster) {
|
||||
MutateClusterTaints(cluster.Spec.Taints)
|
||||
|
@ -21,3 +29,147 @@ func MutateClusterTaints(taints []corev1.Taint) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetDefaultClusterResourceModels set default cluster resource models for cluster.
|
||||
func SetDefaultClusterResourceModels(cluster *clusterapis.Cluster) {
|
||||
if cluster.Spec.ResourceModels != nil {
|
||||
return
|
||||
}
|
||||
cluster.Spec.ResourceModels = []clusterapis.ResourceModel{
|
||||
{
|
||||
Grade: 0,
|
||||
Ranges: []clusterapis.ResourceModelRange{
|
||||
{
|
||||
Name: clusterapis.ResourceCPU,
|
||||
Min: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
Max: *resource.NewQuantity(1, resource.DecimalSI),
|
||||
},
|
||||
{
|
||||
Name: clusterapis.ResourceMemory,
|
||||
Min: *resource.NewQuantity(0, resource.BinarySI),
|
||||
Max: *resource.NewQuantity(4*GB, resource.BinarySI),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Grade: 1,
|
||||
Ranges: []clusterapis.ResourceModelRange{
|
||||
{
|
||||
Name: clusterapis.ResourceCPU,
|
||||
Min: *resource.NewQuantity(1, resource.DecimalSI),
|
||||
Max: *resource.NewQuantity(2, resource.DecimalSI),
|
||||
},
|
||||
{
|
||||
Name: clusterapis.ResourceMemory,
|
||||
Min: *resource.NewQuantity(4*GB, resource.BinarySI),
|
||||
Max: *resource.NewQuantity(16*GB, resource.BinarySI),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Grade: 2,
|
||||
Ranges: []clusterapis.ResourceModelRange{
|
||||
{
|
||||
Name: clusterapis.ResourceCPU,
|
||||
Min: *resource.NewQuantity(2, resource.DecimalSI),
|
||||
Max: *resource.NewQuantity(4, resource.DecimalSI),
|
||||
},
|
||||
{
|
||||
Name: clusterapis.ResourceMemory,
|
||||
Min: *resource.NewQuantity(16*GB, resource.BinarySI),
|
||||
Max: *resource.NewQuantity(32*GB, resource.BinarySI),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Grade: 3,
|
||||
Ranges: []clusterapis.ResourceModelRange{
|
||||
{
|
||||
Name: clusterapis.ResourceCPU,
|
||||
Min: *resource.NewQuantity(4, resource.DecimalSI),
|
||||
Max: *resource.NewQuantity(8, resource.DecimalSI),
|
||||
},
|
||||
{
|
||||
Name: clusterapis.ResourceMemory,
|
||||
Min: *resource.NewQuantity(32*GB, resource.BinarySI),
|
||||
Max: *resource.NewQuantity(64*GB, resource.BinarySI),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Grade: 4,
|
||||
Ranges: []clusterapis.ResourceModelRange{
|
||||
{
|
||||
Name: clusterapis.ResourceCPU,
|
||||
Min: *resource.NewQuantity(8, resource.DecimalSI),
|
||||
Max: *resource.NewQuantity(16, resource.DecimalSI),
|
||||
},
|
||||
{
|
||||
Name: clusterapis.ResourceMemory,
|
||||
Min: *resource.NewQuantity(64*GB, resource.BinarySI),
|
||||
Max: *resource.NewQuantity(128*GB, resource.BinarySI),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Grade: 5,
|
||||
Ranges: []clusterapis.ResourceModelRange{
|
||||
{
|
||||
Name: clusterapis.ResourceCPU,
|
||||
Min: *resource.NewQuantity(16, resource.DecimalSI),
|
||||
Max: *resource.NewQuantity(32, resource.DecimalSI),
|
||||
},
|
||||
{
|
||||
Name: clusterapis.ResourceMemory,
|
||||
Min: *resource.NewQuantity(128*GB, resource.BinarySI),
|
||||
Max: *resource.NewQuantity(256*GB, resource.BinarySI),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Grade: 6,
|
||||
Ranges: []clusterapis.ResourceModelRange{
|
||||
{
|
||||
Name: clusterapis.ResourceCPU,
|
||||
Min: *resource.NewQuantity(32, resource.DecimalSI),
|
||||
Max: *resource.NewQuantity(64, resource.DecimalSI),
|
||||
},
|
||||
{
|
||||
Name: clusterapis.ResourceMemory,
|
||||
Min: *resource.NewQuantity(256*GB, resource.BinarySI),
|
||||
Max: *resource.NewQuantity(512*GB, resource.BinarySI),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Grade: 7,
|
||||
Ranges: []clusterapis.ResourceModelRange{
|
||||
{
|
||||
Name: clusterapis.ResourceCPU,
|
||||
Min: *resource.NewQuantity(64, resource.DecimalSI),
|
||||
Max: *resource.NewQuantity(128, resource.DecimalSI),
|
||||
},
|
||||
{
|
||||
Name: clusterapis.ResourceMemory,
|
||||
Min: *resource.NewQuantity(512*GB, resource.BinarySI),
|
||||
Max: *resource.NewQuantity(1024*GB, resource.BinarySI),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Grade: 8,
|
||||
Ranges: []clusterapis.ResourceModelRange{
|
||||
{
|
||||
Name: clusterapis.ResourceCPU,
|
||||
Min: *resource.NewQuantity(128, resource.DecimalSI),
|
||||
Max: *resource.NewQuantity(math.MaxInt64, resource.DecimalSI),
|
||||
},
|
||||
{
|
||||
Name: clusterapis.ResourceMemory,
|
||||
Min: *resource.NewQuantity(1024*GB, resource.BinarySI),
|
||||
Max: *resource.NewQuantity(math.MaxInt64, resource.BinarySI),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -188,11 +188,11 @@ type ClusterSpec struct {
|
|||
// ResourceModel describes the modeling that you want to statistics.
|
||||
type ResourceModel struct {
|
||||
// Grade is the index for the resource modeling.
|
||||
// +optional
|
||||
Grade int
|
||||
// +required
|
||||
Grade uint
|
||||
|
||||
// Ranges describes the resource quota ranges.
|
||||
// +optional
|
||||
// +required
|
||||
Ranges []ResourceModelRange
|
||||
}
|
||||
|
||||
|
@ -206,13 +206,13 @@ type ResourceModel struct {
|
|||
// It is strongly recommended that the [Min, Max) of all ResourceModelRanges can make a continuous interval.
|
||||
type ResourceModelRange struct {
|
||||
// Name is the name for the resource that you want to categorize.
|
||||
// +optional
|
||||
// +required
|
||||
Name ResourceName
|
||||
|
||||
// Min is the minimum amount of this resource represented by resource name.
|
||||
// Note: The Min value of first grade(usually 0) always acts as zero.
|
||||
// E.g. [1,2) equal to [0,2).
|
||||
// +optional
|
||||
// +required
|
||||
Min resource.Quantity
|
||||
|
||||
// Max is the maximum amount of this resource represented by resource name.
|
||||
|
@ -221,7 +221,7 @@ type ResourceModelRange struct {
|
|||
// any ResourceModelRange's quota larger than Min will be classified to the last one.
|
||||
// Of course, the value of the Max field is always greater than the value of the Min field.
|
||||
// It should be true in any case.
|
||||
// +optional
|
||||
// +required
|
||||
Max resource.Quantity
|
||||
}
|
||||
|
||||
|
@ -345,11 +345,11 @@ type ResourceSummary struct {
|
|||
// E.g. AllocatableModeling{Grade: 2, Count: 10} means 10 nodes belong to resource model in grade 2.
|
||||
type AllocatableModeling struct {
|
||||
// Grade is the index of ResourceModel.
|
||||
// +optional
|
||||
Grade int
|
||||
// +required
|
||||
Grade uint
|
||||
|
||||
// Count is the number of nodes that own the resources delineated by this modeling.
|
||||
// +optional
|
||||
// +required
|
||||
Count int
|
||||
}
|
||||
|
||||
|
|
|
@ -200,12 +200,12 @@ type ClusterSpec struct {
|
|||
// ResourceModel describes the modeling that you want to statistics.
|
||||
type ResourceModel struct {
|
||||
// Grade is the index for the resource modeling.
|
||||
// +optional
|
||||
Grade int `json:"grade,omitempty"`
|
||||
// +required
|
||||
Grade uint `json:"grade"`
|
||||
|
||||
// Ranges describes the resource quota ranges.
|
||||
// +optional
|
||||
Ranges []ResourceModelRange `json:"ranges,omitempty"`
|
||||
// +required
|
||||
Ranges []ResourceModelRange `json:"ranges"`
|
||||
}
|
||||
|
||||
// ResourceModelRange describes the detail of each modeling quota that ranges from min to max.
|
||||
|
@ -218,14 +218,14 @@ type ResourceModel struct {
|
|||
// It is strongly recommended that the [Min, Max) of all ResourceModelRanges can make a continuous interval.
|
||||
type ResourceModelRange struct {
|
||||
// Name is the name for the resource that you want to categorize.
|
||||
// +optional
|
||||
Name ResourceName `json:"name,omitempty"`
|
||||
// +required
|
||||
Name ResourceName `json:"name"`
|
||||
|
||||
// Min is the minimum amount of this resource represented by resource name.
|
||||
// Note: The Min value of first grade(usually 0) always acts as zero.
|
||||
// E.g. [1,2) equal to [0,2).
|
||||
// +optional
|
||||
Min resource.Quantity `json:"min,omitempty"`
|
||||
// +required
|
||||
Min resource.Quantity `json:"min"`
|
||||
|
||||
// Max is the maximum amount of this resource represented by resource name.
|
||||
// Special Instructions, for the last ResourceModelRange, which no matter what Max value you pass,
|
||||
|
@ -233,8 +233,8 @@ type ResourceModelRange struct {
|
|||
// any ResourceModelRange's quota larger than Min will be classified to the last one.
|
||||
// Of course, the value of the Max field is always greater than the value of the Min field.
|
||||
// It should be true in any case.
|
||||
// +optional
|
||||
Max resource.Quantity `json:"max,omitempty"`
|
||||
// +required
|
||||
Max resource.Quantity `json:"max"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -354,12 +354,12 @@ type ResourceSummary struct {
|
|||
// E.g. AllocatableModeling{Grade: 2, Count: 10} means 10 nodes belong to resource model in grade 2.
|
||||
type AllocatableModeling struct {
|
||||
// Grade is the index of ResourceModel.
|
||||
// +optional
|
||||
Grade int `json:"grade,omitempty"`
|
||||
// +required
|
||||
Grade uint `json:"grade"`
|
||||
|
||||
// Count is the number of nodes that own the resources delineated by this modeling.
|
||||
// +optional
|
||||
Count int `json:"count,omitempty"`
|
||||
// +required
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
|
|
@ -24,7 +24,8 @@ var (
|
|||
// FeatureGate is a shared global FeatureGate.
|
||||
FeatureGate featuregate.MutableFeatureGate = featuregate.NewFeatureGate()
|
||||
|
||||
defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
|
||||
// DefaultFeatureGates is the default feature gates of Karmada.
|
||||
DefaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
|
||||
Failover: {Default: false, PreRelease: featuregate.Alpha},
|
||||
GracefulEviction: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PropagateDeps: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
@ -33,5 +34,5 @@ var (
|
|||
)
|
||||
|
||||
func init() {
|
||||
runtime.Must(FeatureGate.Add(defaultFeatureGates))
|
||||
runtime.Must(FeatureGate.Add(DefaultFeatureGates))
|
||||
}
|
||||
|
|
|
@ -516,6 +516,7 @@ func schema_pkg_apis_cluster_v1alpha1_AllocatableModeling(ref common.ReferenceCa
|
|||
"grade": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Grade is the index of ResourceModel.",
|
||||
Default: 0,
|
||||
Type: []string{"integer"},
|
||||
Format: "int32",
|
||||
},
|
||||
|
@ -523,11 +524,13 @@ func schema_pkg_apis_cluster_v1alpha1_AllocatableModeling(ref common.ReferenceCa
|
|||
"count": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Count is the number of nodes that own the resources delineated by this modeling.",
|
||||
Default: 0,
|
||||
Type: []string{"integer"},
|
||||
Format: "int32",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"grade", "count"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -925,6 +928,7 @@ func schema_pkg_apis_cluster_v1alpha1_ResourceModel(ref common.ReferenceCallback
|
|||
"grade": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Grade is the index for the resource modeling.",
|
||||
Default: 0,
|
||||
Type: []string{"integer"},
|
||||
Format: "int32",
|
||||
},
|
||||
|
@ -944,6 +948,7 @@ func schema_pkg_apis_cluster_v1alpha1_ResourceModel(ref common.ReferenceCallback
|
|||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"grade", "ranges"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
|
@ -961,6 +966,7 @@ func schema_pkg_apis_cluster_v1alpha1_ResourceModelRange(ref common.ReferenceCal
|
|||
"name": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Name is the name for the resource that you want to categorize.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
|
@ -980,6 +986,7 @@ func schema_pkg_apis_cluster_v1alpha1_ResourceModelRange(ref common.ReferenceCal
|
|||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"name", "min", "max"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
|
|
|
@ -11,11 +11,13 @@ import (
|
|||
"k8s.io/apiserver/pkg/registry/generic"
|
||||
"k8s.io/apiserver/pkg/storage"
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
|
||||
|
||||
clusterapis "github.com/karmada-io/karmada/pkg/apis/cluster"
|
||||
"github.com/karmada-io/karmada/pkg/apis/cluster/mutation"
|
||||
"github.com/karmada-io/karmada/pkg/apis/cluster/validation"
|
||||
"github.com/karmada-io/karmada/pkg/features"
|
||||
)
|
||||
|
||||
// NewStrategy creates and returns a ClusterStrategy instance.
|
||||
|
@ -70,6 +72,10 @@ func (Strategy) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
|
|||
|
||||
// PrepareForCreate is invoked on create before validation to normalize the object.
|
||||
func (Strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {
|
||||
cluster := obj.(*clusterapis.Cluster)
|
||||
if utilfeature.DefaultMutableFeatureGate.Enabled(features.CustomizedClusterResourceModeling) {
|
||||
mutation.SetDefaultClusterResourceModels(cluster)
|
||||
}
|
||||
}
|
||||
|
||||
// PrepareForUpdate is invoked on update before validation to normalize the object.
|
||||
|
|
Loading…
Reference in New Issue