Change:
When updating policy labels on a namespace, existing pods are evaluated to see if they are compatible with the new policy. If there are too many pods, or if evaluation takes too long, we short circuit and warn that not all pods were checked. For that reason, we want to prioritize checking a variety of pods before checking essentially identical pods, so that unique warnings can be surfaced before reaching the pod count cutoff or evaluation timeout. Pods created by the same controller are most likely to be identical (e.g. replicas from a replicaset or job, copies of pods from a statefulset or daemonset, etc) cc
This is an interesting fix I'd like to take this up Can I take this up? I am fairly new to Kubernetes source code so might need some help
I am guessing this is where the logic you mentioned should be implemented right?
thanks for the interest; this is targeted at the beta version... right now, effort is going toward the alpha-blocking work for 1.22
Should I wait for the code freeze before working on this? Sorry for lame questions
If you want to start looking at it, that's fine, but it's possible the code in the ValidateNamespace function will change before we're ready to start merging 1.23 work, and there isn't really reviewer bandwidth to take a look at work-in-progress stuff for next release yet.
Sure, I'll just for code freeze before I start with implementation By the time I'll just assign this to myself /assign
Does it make sense to take it up now? I think we already have a couple of RC builds after the code freeze
sure, it's fine to start work in a branch in your fork and have a WIP PR open, even before master reopens for 1.23 work
Awesome, I'll start working on it Thank you
Hello! Are you still working on this? If you don't have time, I can take this issue. If not, maybe I can give some help
Since this was not an urgent issue I was working on some other issues last week I have started on this, Will be raising a PR maybe today or tomorrow I Will ask you if I get stuck Thank you

Discussion:
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" <ins> "k8s.io/apimachinery/pkg/types" </ins> "k8s.io/apimachinery/pkg/util/validation/field" admissionapi "k8s.io/pod-security-admission/admission/api" "k8s.io/pod-security-admission/admission/api/validation"

podWarnings        []string podWarningsToCount = make(map[string]podCount) <ins> prioritizedPods    = a.prioritizePods(pods) </ins> ) <del> totalPods := len(pods) if len(pods) > a.namespaceMaxPodsToCheck { pods = pods[0:a.namespaceMaxPodsToCheck] </del> <ins> totalPods := len(prioritizedPods) if len(prioritizedPods) > a.namespaceMaxPodsToCheck { prioritizedPods = prioritizedPods[0:a.namespaceMaxPodsToCheck] </ins> } <del> checkedPods := len(pods) for i, pod := range pods { // short-circuit on exempt runtimeclass if a.exemptRuntimeClass(pod.Spec.RuntimeClassName) { continue } </del> <ins> checkedPods := len(prioritizedPods) for i, pod := range prioritizedPods { </ins> r := policy.AggregateCheckResults(a.Evaluator.EvaluatePod(enforce, &pod.ObjectMeta, &pod.Spec)) if !r.Allowed { warning := r.ForbiddenReason()

// TODO: consider optimizing to O(1) lookup return containsString(*runtimeClass, a.Configuration.Exemptions.RuntimeClasses) } <ins> // Filter and prioritize pods based on runtimeclass and uniqueness of the controller respectively for evaluation. // The input slice is modified in place and should not be reused. func (a *Admission) prioritizePods(pods []*corev1.Pod) []*corev1.Pod { // accumulate the list of prioritized pods in-place to avoid double-allocating prioritizedPods := pods[:0] // accumulate any additional replicated pods after the first one encountered for a given controller uid var duplicateReplicatedPods []*corev1.Pod evaluatedControllers := make(map[types.UID]bool) for _, pod := range pods { // short-circuit on exempt runtimeclass if a.exemptRuntimeClass(pod.Spec.RuntimeClassName) { continue } // short-circuit if pod from the same controller is evaluated podOwnerControllerRef := metav1.GetControllerOfNoCopy(pod) if podOwnerControllerRef == nil { prioritizedPods = append(prioritizedPods, pod) continue } if evaluatedControllers[podOwnerControllerRef.UID] { duplicateReplicatedPods = append(duplicateReplicatedPods, pod) continue } prioritizedPods = append(prioritizedPods, pod) evaluatedControllers[podOwnerControllerRef.UID] = true } return append(prioritizedPods, duplicateReplicatedPods...) } </ins> func containsString(needle string, haystack []string) bool { for _, s := range haystack { if s == needle {

import ( "context" <ins> "math/rand" </ins> "reflect" "strings" "testing"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" <ins> "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/uuid" </ins> admissionapi "k8s.io/pod-security-admission/admission/api" "k8s.io/pod-security-admission/api" "k8s.io/pod-security-admission/metrics"

`pod1 (and 3 other pods): message`, }, }, <del> // TODO: test for prioritizing evaluating pods from unique controllers </del> <ins> { name:                 "prioritized pods", exemptRuntimeClasses: []string{"runtimeclass1"}, newLabels:            map[string]string{api.EnforceLevelLabel: string(api.LevelRestricted)}, oldLabels:            map[string]string{api.EnforceLevelLabel: string(api.LevelBaseline)}, pods: []*corev1.Pod{ // ensure exempt pods don't use up the limit of evaluated pods {ObjectMeta: metav1.ObjectMeta{Name: "exemptpod1", Annotations: map[string]string{"error": "message1"}}, Spec: corev1.PodSpec{RuntimeClassName: pointer.String("runtimeclass1")}}, {ObjectMeta: metav1.ObjectMeta{Name: "exemptpod2", Annotations: map[string]string{"error": "message1"}}, Spec: corev1.PodSpec{RuntimeClassName: pointer.String("runtimeclass1")}}, {ObjectMeta: metav1.ObjectMeta{Name: "exemptpod3", Annotations: map[string]string{"error": "message1"}}, Spec: corev1.PodSpec{RuntimeClassName: pointer.String("runtimeclass1")}}, {ObjectMeta: metav1.ObjectMeta{Name: "exemptpod4", Annotations: map[string]string{"error": "message1"}}, Spec: corev1.PodSpec{RuntimeClassName: pointer.String("runtimeclass1")}}, // ensure replicas from the same controller don't use up limit of evaluated pods {ObjectMeta: metav1.ObjectMeta{Name: "replicaset1pod1", Annotations: map[string]string{"error": "replicaset1error"}, OwnerReferences: []metav1.OwnerReference{{UID: types.UID("1"), Controller: pointer.Bool(true)}}}}, {ObjectMeta: metav1.ObjectMeta{Name: "replicaset1pod2", Annotations: map[string]string{"error": "replicaset1error"}, OwnerReferences: []metav1.OwnerReference{{UID: types.UID("1"), Controller: pointer.Bool(true)}}}}, {ObjectMeta: metav1.ObjectMeta{Name: "replicaset1pod3", Annotations: map[string]string{"error": "replicaset1error"}, OwnerReferences: []metav1.OwnerReference{{UID: types.UID("1"), Controller: pointer.Bool(true)}}}}, {ObjectMeta: metav1.ObjectMeta{Name: "replicaset1pod4", Annotations: map[string]string{"error": "replicaset1error"}, OwnerReferences: []metav1.OwnerReference{{UID: types.UID("1"), Controller: pointer.Bool(true)}}}}, {ObjectMeta: metav1.ObjectMeta{Name: "replicaset2pod1", Annotations: map[string]string{"error": "replicaset2error"}, OwnerReferences: []metav1.OwnerReference{{UID: types.UID("2"), Controller: pointer.Bool(true)}}}}, {ObjectMeta: metav1.ObjectMeta{Name: "replicaset2pod2", Annotations: map[string]string{"error": "replicaset2error"}, OwnerReferences: []metav1.OwnerReference{{UID: types.UID("2"), Controller: pointer.Bool(true)}}}}, {ObjectMeta: metav1.ObjectMeta{Name: "replicaset2pod3", Annotations: map[string]string{"error": "replicaset2error"}, OwnerReferences: []metav1.OwnerReference{{UID: types.UID("2"), Controller: pointer.Bool(true)}}}}, {ObjectMeta: metav1.ObjectMeta{Name: "replicaset2pod4", Annotations: map[string]string{"error": "replicaset2error"}, OwnerReferences: []metav1.OwnerReference{{UID: types.UID("2"), Controller: pointer.Bool(true)}}}}, // ensure unique pods are prioritized before additional replicas {ObjectMeta: metav1.ObjectMeta{Name: "uniquepod1", Annotations: map[string]string{"error": "uniquemessage1"}}}, {ObjectMeta: metav1.ObjectMeta{Name: "uniquepod2", Annotations: map[string]string{"error": "uniquemessage2"}}}, {ObjectMeta: metav1.ObjectMeta{Name: "uniquepod3", Annotations: map[string]string{"error": "uniquemessage3"}}}, {ObjectMeta: metav1.ObjectMeta{Name: "uniquepod4", Annotations: map[string]string{"error": "uniquemessage4"}}}, }, expectAllowed:  true, expectListPods: true, expectEvaluate: api.LevelVersion{Level: api.LevelRestricted, Version: api.LatestVersion()}, expectWarnings: []string{ `new PodSecurity enforce level only checked against the first 4 of 12 existing pods`, `existing pods in namespace "test" violate the new PodSecurity enforce level "restricted:latest"`, `replicaset1pod1: replicaset1error`, `replicaset2pod1: replicaset2error`, `uniquepod1: uniquemessage1`, `uniquepod2: uniquemessage2`, }, }, </ins> } for _, tc := range testcases {

t.Errorf("expected to evaluate %v, got %v", tc.expectEvaluate, evaluator.lv) } if !reflect.DeepEqual(result.Warnings, tc.expectWarnings) { <del> t.Errorf("expected warnings:n%vngotn%v", tc.expectWarnings, result.Warnings) </del> <ins> t.Errorf("expected warnings:n%vngotn%v", strings.Join(tc.expectWarnings, "n"), strings.Join(result.Warnings, "n")) </ins> } }) }

t.Helper() assert.ElementsMatch(t, expected, r.evaluations) } <ins> func TestPrioritizePods(t *testing.T) { isController := true sampleOwnerReferences := []struct { ownerRefs []metav1.OwnerReference }{ { ownerRefs: []metav1.OwnerReference{ { UID:        uuid.NewUUID(), Controller: &isController, }, }, }, { ownerRefs: []metav1.OwnerReference{ { UID:        uuid.NewUUID(), Controller: &isController, }, }, }, { ownerRefs: []metav1.OwnerReference{ { UID:        uuid.NewUUID(), Controller: &isController, }, }, }, } var pods []*corev1.Pod randomSource := rand.NewSource(time.Now().Unix()) for _, sampleOwnerRef := range sampleOwnerReferences { // Generate multiple pods for a controller for i := 0; i < rand.New(randomSource).Intn(5)+len(sampleOwnerReferences); i++ { pods = append(pods, &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ OwnerReferences: sampleOwnerRef.ownerRefs, }, Spec: corev1.PodSpec{}, }) } } a := &Admission{} prioritizedPods := a.prioritizePods(pods) controllerRef := make(map[types.UID]bool) for i := 0; i < len(sampleOwnerReferences); i++ { if controllerRef[metav1.GetControllerOfNoCopy(prioritizedPods[i]).UID] { assert.Fail(t, "Pods are not prioritized based on uniqueness of the controller") } controllerRef[metav1.GetControllerOfNoCopy(prioritizedPods[i]).UID] = true } if len(prioritizedPods) != len(pods) { assert.Fail(t, "Pod count is not the same after prioritization") } } </ins>