Skip to content

Commit

Permalink
feature: Optimizing Pod SidecarSet webhook performance (openkruise#1547)
Browse files Browse the repository at this point in the history
Signed-off-by: acejilam <[email protected]>
  • Loading branch information
ls-2018 authored Apr 8, 2024
1 parent 0d0031a commit 8bb8964
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 26 deletions.
14 changes: 12 additions & 2 deletions pkg/controller/sidecarset/sidecarset_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
controlutil "github.com/openkruise/kruise/pkg/controller/util"
"github.com/openkruise/kruise/pkg/util"
utilclient "github.com/openkruise/kruise/pkg/util/client"
"github.com/openkruise/kruise/pkg/util/fieldindex"
historyutil "github.com/openkruise/kruise/pkg/util/history"
webhookutil "github.com/openkruise/kruise/pkg/webhook/util"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
Expand Down Expand Up @@ -225,14 +226,23 @@ func (p *Processor) updatePodSidecarAndHash(control sidecarcontrol.SidecarContro

func (p *Processor) listMatchedSidecarSets(pod *corev1.Pod) string {
sidecarSetList := &appsv1alpha1.SidecarSetList{}
if err := p.Client.List(context.TODO(), sidecarSetList); err != nil {
sidecarSetList2 := &appsv1alpha1.SidecarSetList{}
podNamespace := pod.Namespace
if podNamespace == "" {
podNamespace = "default"
}
if err := p.Client.List(context.TODO(), sidecarSetList, client.MatchingFields{fieldindex.IndexNameForSidecarSetNamespace: podNamespace}, utilclient.DisableDeepCopy); err != nil {
klog.Errorf("List SidecarSets failed: %s", err.Error())
return ""
}
if err := p.Client.List(context.TODO(), sidecarSetList2, client.MatchingFields{fieldindex.IndexNameForSidecarSetNamespace: fieldindex.IndexValueSidecarSetClusterScope}, utilclient.DisableDeepCopy); err != nil {
klog.Errorf("List SidecarSets failed: %s", err.Error())
return ""
}

//matched SidecarSet.Name list
sidecarSetNames := make([]string, 0)
for _, sidecarSet := range sidecarSetList.Items {
for _, sidecarSet := range append(sidecarSetList.Items, sidecarSetList2.Items...) {
if matched, _ := sidecarcontrol.PodMatchedSidecarSet(p.Client, pod, &sidecarSet); matched {
sidecarSetNames = append(sidecarSetNames, sidecarSet.Name)
}
Expand Down
50 changes: 44 additions & 6 deletions pkg/util/fieldindex/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,24 @@ import (
"context"
"sync"

"sigs.k8s.io/controller-runtime/pkg/client"

appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
utildiscovery "github.com/openkruise/kruise/pkg/util/discovery"

batchv1 "k8s.io/api/batch/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client"
)

const (
IndexNameForPodNodeName = "spec.nodeName"
IndexNameForOwnerRefUID = "ownerRefUID"
IndexNameForController = ".metadata.controller"
IndexNameForIsActive = "isActive"
IndexNameForPodNodeName = "spec.nodeName"
IndexNameForOwnerRefUID = "ownerRefUID"
IndexNameForController = ".metadata.controller"
IndexNameForIsActive = "isActive"
IndexNameForSidecarSetNamespace = "namespace"
IndexValueSidecarSetClusterScope = "clusterScope"
LabelMetadataName = v1.LabelMetadataName
)

var (
Expand Down Expand Up @@ -87,6 +90,12 @@ func RegisterFieldIndexes(c cache.Cache) error {
return
}
}
// sidecar spec namespaces
if utildiscovery.DiscoverObject(&appsv1alpha1.SidecarSet{}) {
if err = indexSidecarSet(c); err != nil {
return
}
}
})
return err
}
Expand Down Expand Up @@ -152,3 +161,32 @@ func indexImagePullJobActive(c cache.Cache) error {
return []string{isActive}
})
}

func IndexSidecarSet(rawObj client.Object) []string {
obj := rawObj.(*appsv1alpha1.SidecarSet)
if obj == nil {
return nil
}
if obj.Spec.Namespace != "" {
return []string{obj.Spec.Namespace}
}
if obj.Spec.NamespaceSelector != nil {
if obj.Spec.NamespaceSelector.MatchLabels != nil {
if v, ok := obj.Spec.NamespaceSelector.MatchLabels[LabelMetadataName]; ok {
return []string{v}
}
}
for _, item := range obj.Spec.NamespaceSelector.MatchExpressions {
if item.Key == LabelMetadataName && item.Operator == metav1.LabelSelectorOpIn {
return item.Values
}
}
}
return []string{IndexValueSidecarSetClusterScope}
}

func indexSidecarSet(c cache.Cache) error {
return c.IndexField(context.TODO(), &appsv1alpha1.SidecarSet{}, IndexNameForSidecarSetNamespace, func(rawObj client.Object) []string {
return IndexSidecarSet(rawObj)
})
}
96 changes: 96 additions & 0 deletions pkg/util/fieldindex/register_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package fieldindex

import (
"fmt"
"reflect"
"testing"

appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestIndexSidecarSet(t *testing.T) {
type args struct {
workload *appsv1alpha1.SidecarSet
}
tests := []struct {
name string
args args
want []string
}{
{
name: "nil obj",
args: args{
workload: nil,
},
want: nil,
},
{
name: "namespace is specified in SidecarSet",
args: args{
workload: &appsv1alpha1.SidecarSet{
Spec: appsv1alpha1.SidecarSetSpec{
Namespace: "default",
},
},
},
want: []string{"default"},
},
{
name: fmt.Sprintf("namespaceSelector is specified in SidecarSet and exists labels: %s", LabelMetadataName),
args: args{
workload: &appsv1alpha1.SidecarSet{
Spec: appsv1alpha1.SidecarSetSpec{
NamespaceSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{
LabelMetadataName: "default",
},
MatchExpressions: nil,
},
},
},
},
want: []string{"default"},
},
{
name: fmt.Sprintf("namespaceSelector is specified in SidecarSet and exists labels: %s", LabelMetadataName),
args: args{
workload: &appsv1alpha1.SidecarSet{
Spec: appsv1alpha1.SidecarSetSpec{
NamespaceSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Key: LabelMetadataName,
Operator: metav1.LabelSelectorOpIn,
Values: []string{
"default",
},
},
},
},
},
},
},
want: []string{"default"},
},
{
name: "namespace and namespaceSelector not specified",
args: args{
workload: &appsv1alpha1.SidecarSet{
Spec: appsv1alpha1.SidecarSetSpec{
NamespaceSelector: &metav1.LabelSelector{},
},
},
},
want: []string{IndexValueSidecarSetClusterScope},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := IndexSidecarSet(tt.args.workload)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("IndexSidecarSet() = %v, want %v", got, tt.want)
}
})
}
}
18 changes: 14 additions & 4 deletions pkg/webhook/pod/mutating/sidecarset.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/openkruise/kruise/pkg/control/sidecarcontrol"
"github.com/openkruise/kruise/pkg/util"
utilclient "github.com/openkruise/kruise/pkg/util/client"
"github.com/openkruise/kruise/pkg/util/fieldindex"
"github.com/openkruise/kruise/pkg/util/history"

admissionv1 "k8s.io/api/admission/v1"
Expand All @@ -35,6 +36,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

Expand Down Expand Up @@ -64,13 +66,21 @@ func (h *PodCreateHandler) sidecarsetMutatingPod(ctx context.Context, req admiss
}

// DisableDeepCopy:true, indicates must be deep copy before update sidecarSet objection
sidecarsetList := &appsv1alpha1.SidecarSetList{}
if err = h.Client.List(ctx, sidecarsetList, utilclient.DisableDeepCopy); err != nil {

sidecarSetList := &appsv1alpha1.SidecarSetList{}
sidecarSetList2 := &appsv1alpha1.SidecarSetList{}
podNamespace := pod.Namespace
if podNamespace == "" {
podNamespace = "default"
}
if err := h.Client.List(ctx, sidecarSetList, client.MatchingFields{fieldindex.IndexNameForSidecarSetNamespace: podNamespace}, utilclient.DisableDeepCopy); err != nil {
return false, err
}
if err := h.Client.List(ctx, sidecarSetList2, client.MatchingFields{fieldindex.IndexNameForSidecarSetNamespace: fieldindex.IndexValueSidecarSetClusterScope}, utilclient.DisableDeepCopy); err != nil {
return false, err
}

matchedSidecarSets := make([]sidecarcontrol.SidecarControl, 0)
for _, sidecarSet := range sidecarsetList.Items {
for _, sidecarSet := range append(sidecarSetList.Items, sidecarSetList2.Items...) {
if sidecarSet.Spec.InjectionStrategy.Paused {
continue
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/webhook/pod/mutating/sidecarset_hotupgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

appsv1alpha1 "github.com/openkruise/kruise/apis/apps/v1alpha1"
"github.com/openkruise/kruise/pkg/control/sidecarcontrol"
"github.com/openkruise/kruise/pkg/util/fieldindex"

admissionv1 "k8s.io/api/admission/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -41,7 +42,9 @@ func TestInjectHotUpgradeSidecar(t *testing.T) {
func testInjectHotUpgradeSidecar(t *testing.T, sidecarSetIn *appsv1alpha1.SidecarSet) {
podIn := pod1.DeepCopy()
decoder, _ := admission.NewDecoder(scheme.Scheme)
client := fake.NewClientBuilder().WithObjects(sidecarSetIn).Build()
client := fake.NewClientBuilder().WithObjects(sidecarSetIn).WithIndex(
&appsv1alpha1.SidecarSet{}, fieldindex.IndexNameForSidecarSetNamespace, fieldindex.IndexSidecarSet,
).Build()
podOut := podIn.DeepCopy()
podHandler := &PodCreateHandler{Decoder: decoder, Client: client}
req := newAdmission(admissionv1.Create, runtime.RawExtension{}, runtime.RawExtension{}, "")
Expand Down
Loading

0 comments on commit 8bb8964

Please sign in to comment.