Merge pull request #67842 from xmudrii/extern-priority

admission/priority: externalize priority admission controller
pull/58/head
k8s-ci-robot 2018-09-25 01:27:31 -07:00 committed by GitHub
commit 38d2f05d52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 26 deletions

View File

@ -13,13 +13,15 @@ go_test(
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/scheduling:go_default_library", "//pkg/apis/scheduling:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library", "//pkg/apis/scheduling/v1beta1:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//staging/src/k8s.io/api/scheduling/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user: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/informers:go_default_library",
"//vendor/github.com/golang/glog:go_default_library", "//vendor/github.com/golang/glog:go_default_library",
], ],
) )
@ -31,17 +33,18 @@ go_library(
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/scheduling:go_default_library", "//pkg/apis/scheduling:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
"//pkg/client/listers/scheduling/internalversion:go_default_library",
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//pkg/kubelet/types:go_default_library", "//pkg/kubelet/types:go_default_library",
"//staging/src/k8s.io/api/scheduling/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library", "//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/admission/initializer: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/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/listers/scheduling/v1beta1:go_default_library",
], ],
) )

View File

@ -20,18 +20,19 @@ import (
"fmt" "fmt"
"io" "io"
schedulingv1beta1 "k8s.io/api/scheduling/v1beta1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
genericadmissioninitializers "k8s.io/apiserver/pkg/admission/initializer"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
schedulingv1beta1listers "k8s.io/client-go/listers/scheduling/v1beta1"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/scheduling" "k8s.io/kubernetes/pkg/apis/scheduling"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
schedulinglisters "k8s.io/kubernetes/pkg/client/listers/scheduling/internalversion"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
kubelettypes "k8s.io/kubernetes/pkg/kubelet/types" kubelettypes "k8s.io/kubernetes/pkg/kubelet/types"
) )
@ -50,14 +51,14 @@ func Register(plugins *admission.Plugins) {
// priorityPlugin is an implementation of admission.Interface. // priorityPlugin is an implementation of admission.Interface.
type priorityPlugin struct { type priorityPlugin struct {
*admission.Handler *admission.Handler
client internalclientset.Interface client kubernetes.Interface
lister schedulinglisters.PriorityClassLister lister schedulingv1beta1listers.PriorityClassLister
} }
var _ admission.MutationInterface = &priorityPlugin{} var _ admission.MutationInterface = &priorityPlugin{}
var _ admission.ValidationInterface = &priorityPlugin{} var _ admission.ValidationInterface = &priorityPlugin{}
var _ = kubeapiserveradmission.WantsInternalKubeInformerFactory(&priorityPlugin{}) var _ = genericadmissioninitializers.WantsExternalKubeInformerFactory(&priorityPlugin{})
var _ = kubeapiserveradmission.WantsInternalKubeClientSet(&priorityPlugin{}) var _ = genericadmissioninitializers.WantsExternalKubeClientSet(&priorityPlugin{})
// NewPlugin creates a new priority admission plugin. // NewPlugin creates a new priority admission plugin.
func newPlugin() *priorityPlugin { func newPlugin() *priorityPlugin {
@ -78,13 +79,13 @@ func (p *priorityPlugin) ValidateInitialization() error {
} }
// SetInternalKubeClientSet implements the WantsInternalKubeClientSet interface. // SetInternalKubeClientSet implements the WantsInternalKubeClientSet interface.
func (p *priorityPlugin) SetInternalKubeClientSet(client internalclientset.Interface) { func (p *priorityPlugin) SetExternalKubeClientSet(client kubernetes.Interface) {
p.client = client p.client = client
} }
// SetInternalKubeInformerFactory implements the WantsInternalKubeInformerFactory interface. // SetInternalKubeInformerFactory implements the WantsInternalKubeInformerFactory interface.
func (p *priorityPlugin) SetInternalKubeInformerFactory(f informers.SharedInformerFactory) { func (p *priorityPlugin) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
priorityInformer := f.Scheduling().InternalVersion().PriorityClasses() priorityInformer := f.Scheduling().V1beta1().PriorityClasses()
p.lister = priorityInformer.Lister() p.lister = priorityInformer.Lister()
p.SetReadyFunc(priorityInformer.Informer().HasSynced) p.SetReadyFunc(priorityInformer.Informer().HasSynced)
} }
@ -241,14 +242,14 @@ func (p *priorityPlugin) validatePriorityClass(a admission.Attributes) error {
return nil return nil
} }
func (p *priorityPlugin) getDefaultPriorityClass() (*scheduling.PriorityClass, error) { func (p *priorityPlugin) getDefaultPriorityClass() (*schedulingv1beta1.PriorityClass, error) {
list, err := p.lister.List(labels.Everything()) list, err := p.lister.List(labels.Everything())
if err != nil { if err != nil {
return nil, err return nil, err
} }
// In case more than one global default priority class is added as a result of a race condition, // In case more than one global default priority class is added as a result of a race condition,
// we pick the one with the lowest priority value. // we pick the one with the lowest priority value.
var defaultPC *scheduling.PriorityClass var defaultPC *schedulingv1beta1.PriorityClass
for _, pci := range list { for _, pci := range list {
if pci.GlobalDefault { if pci.GlobalDefault {
if defaultPC == nil || defaultPC.Value > pci.Value { if defaultPC == nil || defaultPC.Value > pci.Value {

View File

@ -22,24 +22,31 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
schedulingv1beta1 "k8s.io/api/scheduling/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/admission"
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/scheduling" "k8s.io/kubernetes/pkg/apis/scheduling"
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion" "k8s.io/kubernetes/pkg/apis/scheduling/v1beta1"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
) )
func addPriorityClasses(ctrl *priorityPlugin, priorityClasses []*scheduling.PriorityClass) { func addPriorityClasses(ctrl *priorityPlugin, priorityClasses []*scheduling.PriorityClass) error {
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc()) informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
ctrl.SetInternalKubeInformerFactory(informerFactory) ctrl.SetExternalKubeInformerFactory(informerFactory)
// First add the existing classes to the cache. // First add the existing classes to the cache.
for _, c := range priorityClasses { for _, c := range priorityClasses {
informerFactory.Scheduling().InternalVersion().PriorityClasses().Informer().GetStore().Add(c) s := &schedulingv1beta1.PriorityClass{}
if err := v1beta1.Convert_scheduling_PriorityClass_To_v1beta1_PriorityClass(c, s, nil); err != nil {
return err
}
informerFactory.Scheduling().V1beta1().PriorityClasses().Informer().GetStore().Add(s)
} }
return nil
} }
var defaultClass1 = &scheduling.PriorityClass{ var defaultClass1 = &scheduling.PriorityClass{
@ -135,7 +142,9 @@ func TestPriorityClassAdmission(t *testing.T) {
ctrl := newPlugin() ctrl := newPlugin()
// Add existing priority classes. // Add existing priority classes.
addPriorityClasses(ctrl, test.existingClasses) if err := addPriorityClasses(ctrl, test.existingClasses); err != nil {
t.Errorf("Test %q: unable to add object to informer: %v", test.name, err)
}
// Now add the new class. // Now add the new class.
attrs := admission.NewAttributesRecord( attrs := admission.NewAttributesRecord(
test.newClass, test.newClass,
@ -220,7 +229,9 @@ func TestDefaultPriority(t *testing.T) {
for _, test := range tests { for _, test := range tests {
glog.V(4).Infof("starting test %q", test.name) glog.V(4).Infof("starting test %q", test.name)
ctrl := newPlugin() ctrl := newPlugin()
addPriorityClasses(ctrl, test.classesBefore) if err := addPriorityClasses(ctrl, test.classesBefore); err != nil {
t.Errorf("Test %q: unable to add object to informer: %v", test.name, err)
}
defaultPriority, err := ctrl.getDefaultPriority() defaultPriority, err := ctrl.getDefaultPriority()
if err != nil { if err != nil {
t.Errorf("Test %q: unexpected error while getting default priority: %v", test.name, err) t.Errorf("Test %q: unexpected error while getting default priority: %v", test.name, err)
@ -234,7 +245,9 @@ func TestDefaultPriority(t *testing.T) {
t.Errorf("Test %q: unexpected error received: %v", test.name, err) t.Errorf("Test %q: unexpected error received: %v", test.name, err)
} }
} }
addPriorityClasses(ctrl, test.classesAfter) if err := addPriorityClasses(ctrl, test.classesAfter); err != nil {
t.Errorf("Test %q: unable to add object to informer: %v", test.name, err)
}
defaultPriority, err = ctrl.getDefaultPriority() defaultPriority, err = ctrl.getDefaultPriority()
if err != nil { if err != nil {
t.Errorf("Test %q: unexpected error while getting default priority: %v", test.name, err) t.Errorf("Test %q: unexpected error while getting default priority: %v", test.name, err)
@ -557,7 +570,9 @@ func TestPodAdmission(t *testing.T) {
ctrl := newPlugin() ctrl := newPlugin()
// Add existing priority classes. // Add existing priority classes.
addPriorityClasses(ctrl, test.existingClasses) if err := addPriorityClasses(ctrl, test.existingClasses); err != nil {
t.Errorf("Test %q: unable to add object to informer: %v", test.name, err)
}
// Create pod. // Create pod.
attrs := admission.NewAttributesRecord( attrs := admission.NewAttributesRecord(