TKG releases v1.25 and later enable the Pod Security Admission (PSA) controller. With PSA you can uniformly enforce pod security using namespace labels.
PSA Enabled in TKR 1.25 and Later
The Pod Security Admission controller is a Kubernetes controller that lets you apply security standards to pods running on TKG clusters. By default, TKG releases v1.25 and later enable the Pod Security Admission (PSA) controller. The PSA controller replaces the Pod Security Policy (PSP) controller, which is deprecated and removed. See also Configure PSP for TKR 1.24 and Eariler.
TKG release v1.25 is a transitional release with PSA configured to warn. Starting with TKG release v1.26, PSA is enforced. You should plan to migrate pod workloads from PSP to PSA in anticipation of upgrading TKG clusters. Refer to Migrate from Pod Security Policy to the Built-In Pod Security Admission Controller for guidance.
Configuring PSA Cluster-wide
Starting with vSphere 8 Update 3, you can configure PSA cluster-wide using the podSecurityStandard
ClusterClass variable that is available with the v1beta1 API. See Cluster v1beta1 API.
PSA Modes
enforce
,
audit
, and
warn
. The table lists and describes each PSA mode.
MODE | Description |
---|---|
enforce |
Security violations cause the pod to be rejected. |
audit |
Security violations trigger the addition of an audit annotation to the event recorded in the audit log, but are otherwise allowed. |
warn |
Security violations trigger a user-facing warning, but are otherwise allowed. |
PSA Standards
LEVEL | Description |
---|---|
privileged |
Unrestricted control, providing the widest possible level of permissions. This security standard allows for known privilege escalations. |
baseline |
Minimally restrictive control which prevents known privilege escalations. This security standard allows the default (minimally specified) pod configuration. |
restricted |
Heavily restricted control, following pod hardening best practices. |
PSA Namespace Labels
The PSA controller enforces pod security at the Kubernetes namespace level. You use namespace labels to define the PSA modes and levels you want to use for pods in a given namespace.
Kubernetes provides a set of labels that you can use to define which of the standards to use for a namespace. The label you apply defines what action the Kubernetes control plane takes if a PSA violation is detected. For a given Kubernetes namespace, you can configure any or all modes, or set a different level for different modes.
# MODE must be one of `enforce`, `audit`, or `warn`. # LEVEL must be one of `privileged`, `baseline`, or `restricted`. pod-security.kubernetes.io/<MODE>=<LEVEL>
You can also apply a per-mode version label that can be used to pin the security standard to the Kubernetes version. See Enforce Pod Security Standards with Namespace Labels for more information.
Default PSA for TKG Clusters
By default, TKG clusters provisioned with TKG release v1.25 have PSA modes warn
and audit
set to restricted
for non-system namespaces. This is a no-force setting: the PSA controller generates a warning and audit notification if a pod violates security, but the pod is not rejected.
enforce
set to
restricted
for non-system namespaces. If a pod violates security, it is rejected. You must configure PSA on the namespace to run pods with less restrictive control.
TKr Version | Default PSA |
---|---|
TKr v1.25 | mode: warn | level: restricted mode: audit | level: restricted mode: enforce | level: not set |
TKr v1.26 and later | mode: enforce | level: restricted |
Configuring PSA Using Namespace Labels
kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/audit=privileged kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/warn=privileged
restricted
to
baseline
.
kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=baseline
baseline
standard on the default namespace:
kubectl label --overwrite ns default pod-security.kubernetes.io/enforce=baseline
restricted
to
privileged
.
kubectl label --overwrite ns NAMESPACE pod-security.kubernetes.io/enforce=privileged
privileged
standard on the default namespace:
kubectl label --overwrite ns default pod-security.kubernetes.io/enforce=privileged
For TKG releases v1.26 and later, use the following example commands to relax PSA across all non-system namespaces.
kubectl label --overwrite ns --all pod-security.kubernetes.io/enforce=privileged
kubectl label --overwrite ns --all pod-security.kubernetes.io/warn=restricted
Configuring Security Context for Individual Pods
{"opType":"CREATE_POD","succeeded":false,"err":"creating pod example-pod: pods \"example-pod\" is forbidden: violates PodSecurity \"restricted:latest\": allowPrivilegeEscalation != false (container \"example-container\" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container \"example-container\" must set securityContext.capabilities.drop=[\"ALL\"]), runAsNonRoot != true (pod or container \"example-container\" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container \"example-container\" must set securityContext.seccompProfile.type to \"RuntimeDefault\" or \"Localhost\")","events":[]}
apiVersion: v1 kind: Pod metadata: name: example-pod spec: containers: - image: gcr.io/google_containers/busybox:1.24 name: example-container command: ["/bin/sh", "-c", "echo 'hello' > /mnt/volume1/index.html && chmod o+rX /mnt /mnt/volume1/index.html && while true ; do sleep 2 ; done"] securityContext: allowPrivilegeEscalation: false runAsNonRoot: true seccompProfile: type: "RuntimeDefault" capabilities: drop: [all] volumeMounts: - name: example-volume-mount mountPath: /mnt/volume1 restartPolicy: Never volumes: - name: example-volume persistentVolumeClaim: claimName: example-pvc