Merge pull request #76310 from ravisantoshgudimetla/fix-priority-quota

Relax namespace restriction for critical pods
This commit is contained in:
Kubernetes Prow Robot 2019-11-12 19:00:11 -08:00 committed by GitHub
commit bb55aa7c54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 10 deletions

View File

@ -44,10 +44,10 @@ go_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/admission/initializer: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/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/listers/scheduling/v1:go_default_library", "//staging/src/k8s.io/client-go/listers/scheduling/v1:go_default_library",
"//staging/src/k8s.io/component-base/featuregate:go_default_library",
], ],
) )

View File

@ -28,10 +28,10 @@ import (
"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" genericadmissioninitializers "k8s.io/apiserver/pkg/admission/initializer"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
schedulingv1listers "k8s.io/client-go/listers/scheduling/v1" schedulingv1listers "k8s.io/client-go/listers/scheduling/v1"
"k8s.io/component-base/featuregate"
"k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core"
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"
@ -54,12 +54,15 @@ func Register(plugins *admission.Plugins) {
// Plugin is an implementation of admission.Interface. // Plugin is an implementation of admission.Interface.
type Plugin struct { type Plugin struct {
*admission.Handler *admission.Handler
client kubernetes.Interface client kubernetes.Interface
lister schedulingv1listers.PriorityClassLister lister schedulingv1listers.PriorityClassLister
resourceQuotaFeatureGateEnabled bool
nonPreemptingPriority bool
} }
var _ admission.MutationInterface = &Plugin{} var _ admission.MutationInterface = &Plugin{}
var _ admission.ValidationInterface = &Plugin{} var _ admission.ValidationInterface = &Plugin{}
var _ genericadmissioninitializers.WantsFeatures = &Plugin{}
var _ = genericadmissioninitializers.WantsExternalKubeInformerFactory(&Plugin{}) var _ = genericadmissioninitializers.WantsExternalKubeInformerFactory(&Plugin{})
var _ = genericadmissioninitializers.WantsExternalKubeClientSet(&Plugin{}) var _ = genericadmissioninitializers.WantsExternalKubeClientSet(&Plugin{})
@ -81,6 +84,12 @@ func (p *Plugin) ValidateInitialization() error {
return nil return nil
} }
// InspectFeatureGates allows setting bools without taking a dep on a global variable
func (p *Plugin) InspectFeatureGates(featureGates featuregate.FeatureGate) {
p.nonPreemptingPriority = featureGates.Enabled(features.NonPreemptingPriority)
p.resourceQuotaFeatureGateEnabled = featureGates.Enabled(features.ResourceQuotaScopeSelectors)
}
// SetExternalKubeClientSet implements the WantsInternalKubeClientSet interface. // SetExternalKubeClientSet implements the WantsInternalKubeClientSet interface.
func (p *Plugin) SetExternalKubeClientSet(client kubernetes.Interface) { func (p *Plugin) SetExternalKubeClientSet(client kubernetes.Interface) {
p.client = client p.client = client
@ -106,7 +115,6 @@ func (p *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission.
if len(a.GetSubresource()) != 0 { if len(a.GetSubresource()) != 0 {
return nil return nil
} }
switch a.GetResource().GroupResource() { switch a.GetResource().GroupResource() {
case podResource: case podResource:
if operation == admission.Create || operation == admission.Update { if operation == admission.Create || operation == admission.Update {
@ -189,8 +197,12 @@ func (p *Plugin) admitPod(a admission.Attributes) error {
pod.Spec.PriorityClassName = pcName pod.Spec.PriorityClassName = pcName
} else { } else {
pcName := pod.Spec.PriorityClassName pcName := pod.Spec.PriorityClassName
if !priorityClassPermittedInNamespace(pcName, a.GetNamespace()) { // If ResourceQuotaScopeSelectors is enabled, we should let pods with critical priorityClass to be created
return admission.NewForbidden(a, fmt.Errorf("pods with %v priorityClass is not permitted in %v namespace", pcName, a.GetNamespace())) // any namespace where administrator wants it to be created.
if !p.resourceQuotaFeatureGateEnabled {
if !priorityClassPermittedInNamespace(pcName, a.GetNamespace()) {
return admission.NewForbidden(a, fmt.Errorf("pods with %v priorityClass is not permitted in %v namespace", pcName, a.GetNamespace()))
}
} }
// Try resolving the priority class name. // Try resolving the priority class name.
@ -212,7 +224,7 @@ func (p *Plugin) admitPod(a admission.Attributes) error {
} }
pod.Spec.Priority = &priority pod.Spec.Priority = &priority
if utilfeature.DefaultFeatureGate.Enabled(features.NonPreemptingPriority) { if p.nonPreemptingPriority {
var corePolicy core.PreemptionPolicy var corePolicy core.PreemptionPolicy
if preemptionPolicy != nil { if preemptionPolicy != nil {
corePolicy = core.PreemptionPolicy(*preemptionPolicy) corePolicy = core.PreemptionPolicy(*preemptionPolicy)

View File

@ -626,7 +626,7 @@ func TestPodAdmission(t *testing.T) {
[]*scheduling.PriorityClass{systemClusterCritical}, []*scheduling.PriorityClass{systemClusterCritical},
*pods[7], *pods[7],
scheduling.SystemCriticalPriority, scheduling.SystemCriticalPriority,
true, false,
nil, nil,
}, },
{ {
@ -681,8 +681,9 @@ func TestPodAdmission(t *testing.T) {
for _, test := range tests { for _, test := range tests {
klog.V(4).Infof("starting test %q", test.name) klog.V(4).Infof("starting test %q", test.name)
ctrl := NewPlugin() ctrl := NewPlugin()
ctrl.resourceQuotaFeatureGateEnabled = true
ctrl.nonPreemptingPriority = true
// Add existing priority classes. // Add existing priority classes.
if err := addPriorityClasses(ctrl, test.existingClasses); err != nil { if err := addPriorityClasses(ctrl, test.existingClasses); err != nil {
t.Errorf("Test %q: unable to add object to informer: %v", test.name, err) t.Errorf("Test %q: unable to add object to informer: %v", test.name, err)
@ -704,6 +705,7 @@ func TestPodAdmission(t *testing.T) {
) )
err := admissiontesting.WithReinvocationTesting(t, ctrl).Admit(context.TODO(), attrs, nil) err := admissiontesting.WithReinvocationTesting(t, ctrl).Admit(context.TODO(), attrs, nil)
klog.Infof("Got %v", err) klog.Infof("Got %v", err)
if !test.expectError { if !test.expectError {
if err != nil { if err != nil {
t.Errorf("Test %q: unexpected error received: %v", test.name, err) t.Errorf("Test %q: unexpected error received: %v", test.name, err)