Merge pull request #87939 from shaloulcy/pod_storage_indexer

add indexer for pod storage
This commit is contained in:
Kubernetes Prow Robot 2020-02-11 23:15:22 -08:00 committed by GitHub
commit 17a6248f76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 0 deletions

View File

@ -30,10 +30,12 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/features:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/generic:go_default_library", "//staging/src/k8s.io/apiserver/pkg/registry/generic:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library", "//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
], ],
) )
@ -54,6 +56,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library", "//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
], ],
) )

View File

@ -87,6 +87,7 @@ func NewStorage(optsGetter generic.RESTOptionsGetter, k client.ConnectionInfoGet
RESTOptions: optsGetter, RESTOptions: optsGetter,
AttrFunc: registrypod.GetAttrs, AttrFunc: registrypod.GetAttrs,
TriggerFunc: map[string]storage.IndexerFunc{"spec.nodeName": registrypod.NodeNameTriggerFunc}, TriggerFunc: map[string]storage.IndexerFunc{"spec.nodeName": registrypod.NodeNameTriggerFunc},
Indexers: registrypod.Indexers(),
} }
if err := store.CompleteWithOptions(options); err != nil { if err := store.CompleteWithOptions(options); err != nil {
return PodStorage{}, err return PodStorage{}, err

View File

@ -34,10 +34,12 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
utilnet "k8s.io/apimachinery/pkg/util/net" utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
genericfeatures "k8s.io/apiserver/pkg/features"
"k8s.io/apiserver/pkg/registry/generic" "k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/storage" "k8s.io/apiserver/pkg/storage"
"k8s.io/apiserver/pkg/storage/names" "k8s.io/apiserver/pkg/storage/names"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
podutil "k8s.io/kubernetes/pkg/api/pod" podutil "k8s.io/kubernetes/pkg/api/pod"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
@ -200,6 +202,25 @@ func NodeNameTriggerFunc(obj runtime.Object) string {
return obj.(*api.Pod).Spec.NodeName return obj.(*api.Pod).Spec.NodeName
} }
// NodeNameIndexFunc return value spec.nodename of given object.
func NodeNameIndexFunc(obj interface{}) ([]string, error) {
pod, ok := obj.(*api.Pod)
if !ok {
return nil, fmt.Errorf("not a pod")
}
return []string{pod.Spec.NodeName}, nil
}
// Indexers returns the indexers for pod storage.
func Indexers() *cache.Indexers {
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.SelectorIndex) {
return &cache.Indexers{
storage.FieldIndex("spec.nodeName"): NodeNameIndexFunc,
}
}
return nil
}
// ToSelectableFields returns a field set that represents the object // ToSelectableFields returns a field set that represents the object
// TODO: fields are not labels, and the validation rules for them do not apply. // TODO: fields are not labels, and the validation rules for them do not apply.
func ToSelectableFields(pod *api.Pod) fields.Set { func ToSelectableFields(pod *api.Pod) fields.Set {

View File

@ -18,6 +18,7 @@ package pod
import ( import (
"context" "context"
"fmt"
"net/http" "net/http"
"net/url" "net/url"
"reflect" "reflect"
@ -31,6 +32,7 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request" genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/client-go/tools/cache"
apitesting "k8s.io/kubernetes/pkg/api/testing" apitesting "k8s.io/kubernetes/pkg/api/testing"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/kubelet/client" "k8s.io/kubernetes/pkg/kubelet/client"
@ -629,3 +631,43 @@ var (
fakeSecureRoundTripper = fakeTransport{val: "secure"} fakeSecureRoundTripper = fakeTransport{val: "secure"}
fakeInsecureRoundTripper = fakeTransport{val: "insecure"} fakeInsecureRoundTripper = fakeTransport{val: "insecure"}
) )
func TestPodIndexFunc(t *testing.T) {
tcs := []struct {
name string
indexFunc cache.IndexFunc
pod interface{}
expectedValue string
expectedErr error
}{
{
name: "node name index",
indexFunc: NodeNameIndexFunc,
pod: &api.Pod{
Spec: api.PodSpec{
NodeName: "test-pod",
},
},
expectedValue: "test-pod",
expectedErr: nil,
},
{
name: "not a pod failed",
indexFunc: NodeNameIndexFunc,
pod: "not a pod object",
expectedValue: "test-pod",
expectedErr: fmt.Errorf("not a pod"),
},
}
for _, tc := range tcs {
indexValues, err := tc.indexFunc(tc.pod)
if !reflect.DeepEqual(err, tc.expectedErr) {
t.Errorf("name %v, expected %v, got %v", tc.name, tc.expectedErr, err)
}
if err == nil && len(indexValues) != 1 && indexValues[0] != tc.expectedValue {
t.Errorf("name %v, expected %v, got %v", tc.name, tc.expectedValue, indexValues)
}
}
}

View File

@ -140,6 +140,12 @@ const (
// //
// Deprecates and removes SelfLink from ObjectMeta and ListMeta. // Deprecates and removes SelfLink from ObjectMeta and ListMeta.
RemoveSelfLink featuregate.Feature = "RemoveSelfLink" RemoveSelfLink featuregate.Feature = "RemoveSelfLink"
// owner: @shaloulcy
// alpha: v1.18
//
// Allows label and field based indexes in apiserver watch cache to accelerate list operations.
SelectorIndex featuregate.Feature = "SelectorIndex"
) )
func init() { func init() {
@ -165,4 +171,5 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
WatchBookmark: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, WatchBookmark: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
APIPriorityAndFairness: {Default: false, PreRelease: featuregate.Alpha}, APIPriorityAndFairness: {Default: false, PreRelease: featuregate.Alpha},
RemoveSelfLink: {Default: false, PreRelease: featuregate.Alpha}, RemoveSelfLink: {Default: false, PreRelease: featuregate.Alpha},
SelectorIndex: {Default: false, PreRelease: featuregate.Alpha},
} }