Skip to content

Commit

Permalink
feat: SidecarSet updateStrategy support priorityStrategy (#1325)
Browse files Browse the repository at this point in the history
* feat: SidecarSet updateStrategy support priorityStrategy

Signed-off-by: ricky <yricky509@gmail.com>

* add ut for sidecarset priority strategy

Signed-off-by: ricky <yricky509@gmail.com>

---------

Signed-off-by: ricky <yricky509@gmail.com>
  • Loading branch information
y-ykcir committed Jul 4, 2023
1 parent 6ca91fe commit 5e8a991
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 1 deletion.
5 changes: 4 additions & 1 deletion apis/apps/v1alpha1/sidecarset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1

import (
appspub "github.com/openkruise/kruise/apis/apps/pub"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
Expand Down Expand Up @@ -252,7 +253,9 @@ type SidecarSetUpdateStrategy struct {
// This cannot be 0.
// Default value is 1.
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`

// Priorities are the rules for calculating the priority of updating pods.
// Each pod to be updated, will pass through these terms and get a sum of weights.
PriorityStrategy *appspub.UpdatePriorityStrategy `json:"priorityStrategy,omitempty"`
// ScatterStrategy defines the scatter rules to make pods been scattered when update.
// This will avoid pods with the same key-value to be updated in one batch.
// - Note that pods will be scattered after priority sort. So, although priority strategy and scatter strategy can be applied together, we suggest to use either one of them.
Expand Down
5 changes: 5 additions & 0 deletions apis/apps/v1alpha1/zz_generated.deepcopy.go

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

90 changes: 90 additions & 0 deletions config/crd/bases/apps.kruise.io_sidecarsets.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,96 @@ spec:
update the injected pods, but it don't affect the webhook inject
sidecar container into the newly created pods. default is false
type: boolean
priorityStrategy:
description: Priorities are the rules for calculating the priority
of updating pods. Each pod to be updated, will pass through
these terms and get a sum of weights.
properties:
orderPriority:
description: 'Order priority terms, pods will be sorted by
the value of orderedKey. For example: ``` orderPriority:
- orderedKey: key1 - orderedKey: key2 ``` First, all pods
which have key1 in labels will be sorted by the value of
key1. Then, the left pods which have no key1 but have key2
in labels will be sorted by the value of key2 and put behind
those pods have key1.'
items:
description: UpdatePriorityOrderTerm defines order priority.
properties:
orderedKey:
description: Calculate priority by value of this key.
Values of this key, will be sorted by GetInt(val).
GetInt method will find the last int in value, such
as getting 5 in value '5', getting 10 in value 'sts-10'.
type: string
required:
- orderedKey
type: object
type: array
weightPriority:
description: Weight priority terms, pods will be sorted by
the sum of all terms weight.
items:
description: UpdatePriorityWeightTerm defines weight priority.
properties:
matchSelector:
description: MatchSelector is used to select by pod's
labels.
properties:
matchExpressions:
description: matchExpressions is a list of label
selector requirements. The requirements are ANDed.
items:
description: A label selector requirement is a
selector that contains values, a key, and an
operator that relates the key and values.
properties:
key:
description: key is the label key that the
selector applies to.
type: string
operator:
description: operator represents a key's relationship
to a set of values. Valid operators are
In, NotIn, Exists and DoesNotExist.
type: string
values:
description: values is an array of string
values. If the operator is In or NotIn,
the values array must be non-empty. If the
operator is Exists or DoesNotExist, the
values array must be empty. This array is
replaced during a strategic merge patch.
items:
type: string
type: array
required:
- key
- operator
type: object
type: array
matchLabels:
additionalProperties:
type: string
description: matchLabels is a map of {key,value}
pairs. A single {key,value} in the matchLabels
map is equivalent to an element of matchExpressions,
whose key field is "key", the operator is "In",
and the values array contains only "value". The
requirements are ANDed.
type: object
type: object
weight:
description: Weight associated with matching the corresponding
matchExpressions, in the range 1-100.
format: int32
type: integer
required:
- matchSelector
- weight
type: object
type: array
type: object
scatterStrategy:
description: ScatterStrategy defines the scatter rules to make
pods been scattered when update. This will avoid pods with the
Expand Down
5 changes: 5 additions & 0 deletions pkg/controller/sidecarset/sidecarset_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ func SortUpdateIndexes(strategy appsv1alpha1.SidecarSetUpdateStrategy, pods []*c
// - Empty creation time pods < newer pods < older pods
sort.Slice(waitUpdateIndexes, sidecarcontrol.GetPodsSortFunc(pods, waitUpdateIndexes))

//sort waitUpdateIndexes based on the priority rules
if strategy.PriorityStrategy != nil {
waitUpdateIndexes = updatesort.NewPrioritySorter(strategy.PriorityStrategy).Sort(pods, waitUpdateIndexes)
}

//sort waitUpdateIndexes based on the scatter rules
if strategy.ScatterStrategy != nil {
// convert regular terms to scatter terms
Expand Down
67 changes: 67 additions & 0 deletions pkg/controller/sidecarset/sidecarset_strategy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"reflect"
"testing"

appspub "github.com/openkruise/kruise/apis/apps/pub"
appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
"github.com/openkruise/kruise/pkg/control/sidecarcontrol"

Expand Down Expand Up @@ -517,6 +518,72 @@ func testSortNextUpgradePods(t *testing.T, factoryPods FactoryPods, factorySidec
},
exceptNextUpgradePods: []string{"pod-13", "pod-10", "pod-19", "pod-18", "pod-17", "pod-16", "pod-15"},
},
{
name: "with weight priority strategy, maxUnavailable(int=10) and pods(count=20, upgraded=10, upgradedAndReady=2)",
getPods: func() []*corev1.Pod {
pods := factoryPods(20, 10, 2)
pods[15].Labels["test-key"] = "bar"
pods[16].Labels["test-key"] = "foo"
return Random(pods)
},
getSidecarset: func() *appsv1alpha1.SidecarSet {
sidecarSet := factorySidecar()
sidecarSet.Spec.UpdateStrategy.MaxUnavailable = &intstr.IntOrString{
Type: intstr.Int,
IntVal: 10,
}
sidecarSet.Spec.UpdateStrategy.PriorityStrategy = &appspub.UpdatePriorityStrategy{
WeightPriority: []appspub.UpdatePriorityWeightTerm{
{
Weight: 50,
MatchSelector: metav1.LabelSelector{
MatchLabels: map[string]string{
"test-key": "foo",
},
},
},
{
Weight: 30,
MatchSelector: metav1.LabelSelector{
MatchLabels: map[string]string{
"test-key": "bar",
},
},
},
},
}
return sidecarSet
},
exceptNextUpgradePods: []string{"pod-16", "pod-15"},
},
{
name: "with order priority strategy, maxUnavailable(int=10) and pods(count=20, upgraded=10, upgradedAndReady=2)",
getPods: func() []*corev1.Pod {
pods := factoryPods(20, 10, 2)
for i := 0; i < 20; i++ {
pods[i].Labels["key1"] = "5"
}
pods[17].Labels["key1"] = "10"
pods[18].Labels["key1"] = "20"
return Random(pods)
},
getSidecarset: func() *appsv1alpha1.SidecarSet {
sidecarSet := factorySidecar()
sidecarSet.Spec.UpdateStrategy.MaxUnavailable = &intstr.IntOrString{
Type: intstr.Int,
IntVal: 10,
}
sidecarSet.Spec.UpdateStrategy.PriorityStrategy = &appspub.UpdatePriorityStrategy{
OrderPriority: []appspub.UpdatePriorityOrderTerm{
{
OrderedKey: "key1",
},
},
}
return sidecarSet
},
exceptNextUpgradePods: []string{"pod-18", "pod-17"},
},
}

strategy := NewStrategy()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ func validateSidecarSetUpdateStrategy(strategy *appsv1alpha1.SidecarSetUpdateStr
if strategy.MaxUnavailable != nil {
allErrs = append(allErrs, appsvalidation.ValidatePositiveIntOrPercent(*(strategy.MaxUnavailable), fldPath.Child("maxUnavailable"))...)
}
if err := strategy.PriorityStrategy.FieldsValidation(); err != nil {
allErrs = append(allErrs, field.Required(fldPath.Child("priorityStrategy"), err.Error()))
}
if strategy.ScatterStrategy != nil {
if err := strategy.ScatterStrategy.FieldsValidation(); err != nil {
allErrs = append(allErrs, field.Required(fldPath.Child("scatterStrategy"), err.Error()))
Expand Down

0 comments on commit 5e8a991

Please sign in to comment.