Skip to main content

We Enabled Restricted and ServiceLB Died: The K3s Pod Security Admission Gap No Generic Guide Mentions

The moment many operators enable the restricted Pod Security Admission (PSA) profile on a K3s cluster, every LoadBalancer-type Service loses its external IP. They followed the official Kubernetes documentation to the letter, labeling namespaces exactly as instructed — so why does only K3s break? This article walks through the Pod Security Admission pitfall that only shows up when you compare K3s against standard Kubernetes.

1. What Pod Security Admission Is — and Why K3s Starts From a Different Baseline

section01

Pod Security Admission (PSA) is an admission controller that inspects every Pod creation request against a security baseline. It defines three levels — privileged (unrestricted), baseline (blocks known privilege escalations), and restricted (enforces current Pod hardening best practices) — each of which can run in enforce (block violations), audit (log violations), or warn (warn only) mode (kubernetes.io official documentation).

PSA graduated to stable in Kubernetes v1.25, released in 2022, replacing the older PodSecurityPolicy (PSP), which had languished in beta for years (TechTarget's coverage). PSP's complex binding model tied to users and service accounts made it hard to operate, and it was fully removed in v1.25 (Teleport's migration guide).

The key design point to remember: PSA enforces nothing by default. No policy applies until an administrator explicitly labels a namespace, by design, so that existing workloads aren't broken during gradual adoption.

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: v1.37

Most PSA walkthroughs written for standard kubeadm clusters are built on this "nothing happens unless you ask" assumption. K3s is different. K3s's official CIS hardening guide states plainly that K3s ships with no pod security or network policies by default — and it's precisely the components K3s bundles on top of that default-open posture that create the trap described below. Chasing down this kind of configuration gap on your own, release after release, is exactly the kind of operational overhead that makes a managed K3s service like Kubo worth considering.

2. Following the Standard Kubernetes Steps, Restricted Killed K3s's ServiceLB

section02

The typical incident plays out like this: to satisfy a CIS benchmark requirement, a team applies restricted cluster-wide on K3s, following the official kubernetes.io steps and running kubectl label across every namespace. Even at the baseline level, hostPath volumes are already forbidden — spec.volumes[*].hostPath must be undefined (official Pod Security Standards documentation) — and restricted tightens this further.

Immediately after, LoadBalancer-type Services across the cluster start losing their external IPs one by one. Tracing the cause leads to K3s's bundled load balancer, ServiceLB: its svclb-* pods can no longer be created. ServiceLB works by scheduling a dedicated pod per Service that binds the host port directly (K3s's official networking documentation) — a mechanism that collides head-on with what restricted allows.

On a standard Kubernetes cluster, the external load balancer is typically delegated to the cloud provider, so no pod like this exists inside the cluster at all. In other words, something that's a non-issue on standard Kubernetes becomes a critical outage on K3s — and ServiceLB is the textbook example.

3. The Root Cause: ServiceLB Needs NET_ADMIN and Unsafe Sysctls

section03

K3s's official CIS hardening guide spells out three policy examples needed before enabling restricted:

  • restricted-psp: the standard restrictive policy
  • system-unrestricted-psp: a relaxed policy for system pods running in kube-system
  • svclb-psp: dedicated to ServiceLB, explicitly permitting:
yaml
allowedCapabilities:
  - NET_ADMIN
allowedUnsafeSysctls:
  - net.ipv4.ip_forward
  - net.ipv6.conf.all.forwarding

Because ServiceLB binds ports directly and manages IP forwarding, it needs the NET_ADMIN capability and specific unsafe sysctls — both of which restricted forbids by default. Without an explicit exception, pod creation is rejected outright.

What matters here is that svclb-psp only appears in K3s's own documentation. No amount of reading generic Pod Security Admission explainers, or CIS benchmark guides written for standard Kubernetes, will mention ServiceLB. When evaluating K3s as a managed K8s option, assuming "standard Kubernetes knowledge is enough" is exactly what causes this kind of bundled-component exception to go unnoticed. A service built on a Kubo Cloud-style Pure Kubernetes configuration has room to ship with these known gaps already accounted for.

4. Another Easy-to-Miss Gap in K3s's PSA Rollout

section04

ServiceLB isn't the only K3s-bundled component worth watching when rolling out PSA.

K3s's default storage class, local-path-provisioner, provisions PVCs internally using a helper pod that relies on hostPath. Since application pods never mount a hostPath volume themselves, this doesn't typically trigger restricted-policy violations for app workloads directly. Still, misconfiguration here carries real risk: a vulnerability (CVE-2026-44543) was reported in which a user with write access to the local-path-config ConfigMap could manipulate the helper pod template to inject a privileged container or hostPath mount, and it was fixed in version 0.0.36 (OSV.dev vulnerability database). Running restricted PSA properly also narrows this kind of misconfiguration-driven attack path.

Separately, common monitoring DaemonSets like node-exporter need hostNetwork and hostPath to collect host-level metrics, making them non-compliant with both baseline and restricted (OneUptime's technical writeup). This isn't K3s-specific — it happens on standard Kubernetes too — but it's worth inventorying alongside ServiceLB before flipping an entire K3s cluster to restricted.

5. A K3s Checklist for Rolling Out Pod Security Admission Safely

section05

To introduce PSA safely on a K3s cluster:

  1. On v1.25+, prepare a PSA configuration file: point --kube-apiserver-arg="admission-control-config-file=..." at an AdmissionConfiguration that already includes a svclb-psp-equivalent exception (K3s's official hardening guide)
  2. Don't jump straight to enforce: apply warn and audit modes cluster-wide first and identify which workloads violate the policy (kubernetes.io official documentation)
  3. Treat kube-system and ServiceLB-related namespaces separately: design exceptions for namespaces running system components instead of applying one blanket label
  4. Inventory hostPath/hostNetwork-dependent components: list out local-path-provisioner's helper pods, monitoring agents, and similar workloads ahead of time
  5. Roll out enforce gradually: switch namespaces to enforce one at a time, starting with those that already show zero violations

Building this process from scratch every time, and tracking how the exception policy needs to shift with each K3s upgrade, is a non-trivial amount of ongoing operational work. A K3s-based managed service like Kubo has room to ship a configuration that already accounts for these known gaps.

6. Conclusion — "Standard Kubernetes Knowledge" Isn't Enough on Its Own

K3s is a CNCF-certified lightweight Kubernetes distribution that's highly compatible with standard Kubernetes at the API level. But bundled components like ServiceLB operate on fundamentally different assumptions than the cloud-dependent load balancer setup standard Kubernetes relies on. Even rolling out a "standard Kubernetes feature" like Pod Security Admission can trigger an outage because of this architectural gap.

When evaluating K3s against standard Kubernetes, it's worth going beyond feature lists and benchmark numbers to ask specifically how bundled components interact with your security policy.

If you'd rather hand off the ongoing work of auditing security settings and maintaining exception policies, Kubo Cloud's Pure Kubernetes configuration with AI-Driven Deployment is one option — you get a genuine, production-grade Kubernetes built on K3s without the cost and complexity of EKS or AKS.

For organizations in finance or healthcare that need data sovereignty or air-gapped environments, Kubo On-Premise offers a hardened configuration that stays entirely within your own infrastructure. Before building out CIS benchmark compliance and PSA exception policies from scratch, it's worth weighing these options first.

If you're actively reviewing your security posture or considering a move to K3s, feel free to get in touch.

Related articles

← Back to all posts