From 1ce7585924e6607bb9c129565c1850951079c1be Mon Sep 17 00:00:00 2001 From: "Bobby (Babak) Salamat" Date: Thu, 28 Jun 2018 11:11:22 -0700 Subject: [PATCH] Limit usage of system critical priority classes to the system namespace --- plugin/pkg/admission/priority/admission.go | 10 +++++++ .../pkg/admission/priority/admission_test.go | 29 ++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/plugin/pkg/admission/priority/admission.go b/plugin/pkg/admission/priority/admission.go index 8f3d62469b..bd45721209 100644 --- a/plugin/pkg/admission/priority/admission.go +++ b/plugin/pkg/admission/priority/admission.go @@ -21,6 +21,7 @@ import ( "io" "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apiserver/pkg/admission" utilfeature "k8s.io/apiserver/pkg/util/feature" @@ -162,6 +163,15 @@ func (p *priorityPlugin) admitPod(a admission.Attributes) error { return fmt.Errorf("failed to get default priority class: %v", err) } } else { + pcName := pod.Spec.PriorityClassName + // Only allow system priorities in the system namespace. This is to prevent abuse or incorrect + // usage of these priorities. Pods created at these priorities could preempt system critical + // components. + for _, spc := range scheduling.SystemPriorityClasses() { + if spc.Name == pcName && a.GetNamespace() != metav1.NamespaceSystem { + return admission.NewForbidden(a, fmt.Errorf("pods with %v priorityClass can only be created in %v namespace", spc.Name, metav1.NamespaceSystem)) + } + } // Try resolving the priority class name. pc, err := p.lister.Get(pod.Spec.PriorityClassName) if err != nil { diff --git a/plugin/pkg/admission/priority/admission_test.go b/plugin/pkg/admission/priority/admission_test.go index 2a9e3a1b33..21e5bf2e72 100644 --- a/plugin/pkg/admission/priority/admission_test.go +++ b/plugin/pkg/admission/priority/admission_test.go @@ -314,7 +314,7 @@ func TestPodAdmission(t *testing.T) { { ObjectMeta: metav1.ObjectMeta{ Name: "pod-w-system-priority", - Namespace: "namespace", + Namespace: metav1.NamespaceSystem, }, Spec: api.PodSpec{ Containers: []api.Container{ @@ -329,7 +329,7 @@ func TestPodAdmission(t *testing.T) { { ObjectMeta: metav1.ObjectMeta{ Name: "mirror-pod-w-system-priority", - Namespace: "namespace", + Namespace: metav1.NamespaceSystem, Annotations: map[string]string{api.MirrorPodAnnotationKey: ""}, }, Spec: api.PodSpec{ @@ -374,6 +374,21 @@ func TestPodAdmission(t *testing.T) { }, }, }, + // pod[8]: Pod with a system priority class name in non-system namespace + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod-w-system-priority-in-nonsystem-namespace", + Namespace: "non-system-namespace", + }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: containerName, + }, + }, + PriorityClassName: scheduling.SystemClusterCritical, + }, + }, } // Enable PodPriority feature gate. utilfeature.DefaultFeatureGate.Set(fmt.Sprintf("%s=true", features.PodPriority)) @@ -459,6 +474,13 @@ func TestPodAdmission(t *testing.T) { scheduling.SystemCriticalPriority, false, }, + { + "pod with system critical priority in non-system namespace", + []*scheduling.PriorityClass{systemClusterCritical}, + *pods[8], + scheduling.SystemCriticalPriority, + true, + }, } for _, test := range tests { @@ -485,8 +507,7 @@ func TestPodAdmission(t *testing.T) { if !test.expectError { if err != nil { t.Errorf("Test %q: unexpected error received: %v", test.name, err) - } - if *test.pod.Spec.Priority != test.expectedPriority { + } else if *test.pod.Spec.Priority != test.expectedPriority { t.Errorf("Test %q: expected priority is %d, but got %d.", test.name, test.expectedPriority, *test.pod.Spec.Priority) } }