Register for our August 27th webinar -  Why Kubernetes Docs Keep Losing You (And What We Did About It)

Kubernetes Security: Defense Models And Best Practices

5 min read
August 16, 2026
Portainer Team
Portainer Team
,
Portainer.io
Follow on LinkedIn
Table of Contents
Share this post
This is some text inside of a div block.

Key takeaways

  • Kubernetes security spans four layers (cloud, cluster, container, and code) and three lifecycle phases (build, admission, and runtime). Every layer wraps the one inside it, and skipping any phase leaves an open entry point for attackers.
  • The Kubernetes attack surface where clusters get compromised includes the API server, etcd, kubelet, workloads and pods, container images, the network fabric, Secrets and ConfigMaps, and the software supply chain. Each component carries a distinct risk that a hardening strategy has to account for.
  • To harden a Kubernetes cluster, follow this six-step framework: lock down authentication and RBAC, protect the control plane, set workload defaults, isolate the network with default-deny policies, verify every image before it runs, and monitor runtime activity with a clear response path.
  • Portainer is a container management platform that sits in front of every Kubernetes, Docker, and Swarm cluster you manage. It applies security constraints, RBAC, and audit logging across every connected cluster from a single control plane, and new clusters inherit your existing policies automatically at onboarding.

According to the 2024 edition of Red Hat’s State of Kubernetes Security Report, 89% of organizations running Kubernetes experienced at least one security incident in the past 12 months, with 67% delaying or slowing down deployment because of it.

A failure rate this high reflects something structural. Kubernetes runs permissive by default, spreads sensitive controls across dozens of components, and gets harder to secure as clusters multiply. The third problem is where most platform teams struggle, because a policy set in one cluster rarely makes it to the next.

This guide covers what Kubernetes security is, how to enforce security policies consistently across clusters, and a step-by-step framework to harden a Kubernetes cluster.

What Is Kubernetes Security?

Kubernetes security is the set of practices, policies, and controls that protect a cluster, its workloads, and its data across the whole stack. 

It’s usually mapped to the 4Cs model from Kubernetes: cloud, cluster, container, and code. Each layer wraps the one inside it, and a weakness at any level can compromise everything above.

  • Cloud covers the host machines, networks, and provider APIs the cluster runs on.
  • Cluster covers the control plane, API server, etcd, and the RBAC model governing who can do what.
  • Container covers image provenance, base image hygiene, and workload privileges at runtime.
  • Code covers the application itself: dependencies, secrets handling, and vulnerabilities inside images.
What Is Kubernetes Security

Security also spans three lifecycle phases: build time (what goes into an image), admission time (whether Kubernetes allows a workload to run), and runtime (what the workload does once executing). Skipping any phase leaves an entry point for attackers, which is why securing Kubernetes is treated as a lifecycle discipline.

New to how Kubernetes fits together? See our full Kubernetes Architecture guide for a breakdown of the control plane, worker nodes, and how they connect.

Why Kubernetes Is a Top Target for Attackers

Kubernetes has become a top target for attackers because of the number of clusters it runs, and, more importantly, how much sits inside those clusters and how often the defaults leave doors open. Here are two reasons this stands out:

1. Misconfiguration Is the Default State

In 2024, 40% of organizations detected misconfigurations in their container or Kubernetes environments, with 27% naming incorrectly configured components as one of their top security concerns. 

Here’s the core reasoning behind this:

By itself, each of these is a relatively minor oversight, but attackers don’t need many to begin with. 

2. A Single Cluster Compromise Cascades

Kubernetes centralizes access through a single API server that holds the credentials, policies, and workloads for everything the cluster runs, with etcd storing it all in one place. An attacker who reaches either one can effectively own the entire platform. 

Things get exponentially worse when you take into account that modern clusters host dozens of apps, service accounts, and secrets of multiple teams, all sharing the same control plane. 

Reports show 52% of organizations experienced unauthorized process execution, and 46% experienced unauthorized lateral movement in their environments. A single compromised workload becomes the pivot point for the rest.

The Kubernetes Attack Surface: Where Clusters Get Compromised

Knowing that Kubernetes gets attacked is one thing, but knowing where the attacks actually happen is another. Here’s a layer-by-layer map of what attackers go after and what a compromise at each point ends up costing you:

Layer / Component Main Risk
API server Cluster-wide takeover through exposed endpoints or leaked tokens
etcd Full data exposure, including every secret in the cluster
kubelet Node-level command execution and container breakout
Workloads and pods Privileged containers used as a launchpad for lateral movement
Container images Malicious or vulnerable code pulled from untrusted registries
Network fabric Unrestricted pod-to-pod traffic that lets attackers move freely
Secrets and ConfigMaps Credentials stored in plaintext or base64 (easy to lift)
Supply chain Compromised dependencies, images, or CI/CD pipelines
  • API server. Every kubectl command, controller, and service account talks to the API server. An attacker with a valid token or an exposed endpoint can do anything a legitimate admin can do.
  • etcd. Kubernetes stores Secrets in etcd as base64. They are encoded but not encrypted. So anyone with etcd access can easily read them, which is why encryption at rest is non-negotiable.
  • kubelet. The agent running on every node that takes instructions from the API server and executes them. If the kubelet’s read-write port is exposed without authentication, an attacker can run commands on the node directly. Container breakout attacks usually end here, on the node itself.
  • Workloads and pods. A pod running an outdated image or a container with a known CVE is where most attackers get their first foothold. Once inside, privileged mode and hostPath mounts turn a container compromise into a node compromise.
  • Container images. Every image you run is code you trust. If you’re pulling from unverified registries, using stale base images, or skipping vulnerability scans, this lets attackers plant malicious code before the workload ever reaches the cluster.
  • Network fabric. Kubernetes doesn’t restrict pod-to-pod traffic by default. Without NetworkPolicies, a compromised pod in one namespace can talk to every other pod in the cluster, which is exactly how attackers pivot from a foothold to lateral movement.
  • Secrets and ConfigMaps. Credentials, API keys, database passwords all live here. Without etcd encryption at rest and proper RBAC on Kubernetes Secret objects, anyone with cluster-read access can pull them.
  • Supply chain. This is the path from source code to running container. A compromised dependency, a poisoned base image, or a CI/CD pipeline with weak controls here allows attackers to get code into your cluster without any direct access to Kubernetes.
For a hands-on look at how attackers actually exploit the API server, service account tokens, and network fabric, read our Kubernetes API Hacking breakdown.

How to Enforce Security Policies Across Kubernetes Clusters

Enforcing the same security policy across every cluster (without drift) is easier said than done. Here are the two mechanisms platform teams use to make it work:

1. Pod Security Admission

Pod Security Admission is Kubernetes’ own policy engine, built into the API server since v1.25 replaced PodSecurityPolicies. It runs at admission time, checking every pod spec before Kubernetes lets it start. If the spec breaks the rules, the pod never runs.

You get three predefined levels: privileged for trusted system workloads, baseline for blocking the obvious risks like privileged containers and hostPath mounts, and restricted for the hardened defaults the Kubernetes community recommends. You apply a level per namespace by adding a label:

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

The good news is it’s built in, standardized, and free. No CRDs, extra controllers, or anything to patch. The catch, however, is that PSA only enforces the three levels as written. 

You can’t write a rule like “block any image from a registry outside our approved list” or “require every pod to carry an owner label.” For anything past the baseline, you need a policy-as-code engine.

2. OPA Gatekeeper and Kyverno

When PSA isn’t enough, teams reach for an engine that plugs into the same admission point but lets you write custom rules. The two dominant options are OPA Gatekeeper and Kyverno.

  • Gatekeeper is built on Open Policy Agent, writes policies in a language called Rego, and is used by 35% of organizations. 
  • Kyverno does the same job but writes policies in YAML instead of Rego, which matches how Kubernetes admins already think. It’s easier to pick up and better for teams without a dedicated platform engineer.

Either one lets you write the rules PSA can’t. Here are some examples:

  • Block containers with privileged: true
  • Restrict image pulls to your internal registry
  • Require every namespace to have resource quotas
  • Enforce specific labels for cost tracking or ownership
  • Prevent hostPath volume mounts anywhere in production

Policies live as Kubernetes objects, so they’re version-controlled, reviewable, and applied like any other manifest.

o understand how these engines evaluate admission requests and maintain compliance across your environments, read this detailed breakdown on Kubernetes policy enforcement.

Making It Stick Across Every Cluster with Portainer

Both engines run per cluster. Installing Gatekeeper in one cluster does nothing for the twenty others sitting alongside it, and this is where security programs start to fray.

Someone writes a Gatekeeper policy that blocks privileged containers. It gets applied to the main production cluster. Then a new cluster spins up for a different team, a regional deployment, or an edge site, and the policy isn’t there. Six months later, a privileged container is running in production somewhere, and nobody knows how it got approved. 

Most teams try to fix this with GitOps, pushing manifests through Argo CD or Flux, which works when every cluster is wired to the same GitOps controller. When they aren’t, or when different teams manage different clusters with different tools, policies drift.

Portainer closes this gap. Under Security Constraints in the cluster settings, Portainer wraps OPA Gatekeeper into a set of toggles that apply across every connected cluster at once. Instead of writing Rego, an admin picks the policies they want enforced:

  • Block privileged containers
  • Restrict which registries pods can pull from
  • Require specific labels or annotations for governance
  • Prevent hostPath volume mounts
Making It Stick Across Every Cluster with Portainer

Portainer pushes the underlying Gatekeeper manifests into the cluster and reconciles them. So, when a new cluster gets onboarded, the policies attach automatically, and when someone changes a policy in Portainer, the change takes place in every cluster in the group at the same time. The result is a single toggle that blocks privileged containers everywhere and stays that way.

{{article-cta}}

Step-by-Step Framework to Harden a Kubernetes Cluster

Here’s a repeatable, step-by-step framework you can use to harden a Kubernetes cluster from scratch, based on the priorities in the NSA and CISA Kubernetes Hardening Guide:

Step 1: Lock Down Authentication and RBAC

Every request to your cluster hits the API server, and the API server needs to know two things about it: who’s asking, and what they’re allowed to do.

For authentication, wire the API server up to your organization’s identity provider through OIDC, so logins go through the same SSO your team already uses. Kill static tokens and default service accounts for human users. Rotate service account tokens on a schedule, and never mount them into pods that don’t need to talk to the API.

For Kubernetes RBAC, the fixes are structural:

  • No ClusterRoles when a Role in a namespace will do
  • No wildcards in verbs or resources
  • No permanent admin access for developers
  • Quarterly audit of every RoleBinding

Portainer wraps this into predefined roles scoped per-cluster or per-namespace, which is the fastest way to get consistent access control across a fleet without writing YAML for every binding.

Step 2: Harden the Control Plane

Earlier, we discussed why the API server and etcd matter. Now let’s talk about the actual controls.

For the API server: bind it to a private network, put it behind a firewall or reverse proxy, and never expose it on a public IP. Enable audit logging at the RequestResponse level for anything sensitive (Secrets, RBAC changes, exec/attach) and ship the logs to a SIEM you actually monitor. Require TLS on every connection, and use certificate rotation.

For etcd: encrypt at rest. Configure an EncryptionConfiguration with a KMS provider (AWS KMS, GCP KMS, or HashiCorp Vault), and rotate the encryption key regularly. Restrict etcd network access to the control plane nodes only, and take encrypted backups on a schedule. If etcd is compromised, backups are the difference between an incident and a disaster.

Step 3: Set Workload Defaults

The policy engine work from the previous section enforces these rules at admission time. This step is about baking them into your workload manifests so they’re right the first time.

For every pod spec:

  • runAsNonRoot: true (never run containers as root)
  • readOnlyRootFilesystem: true (block writes to the container’s own filesystem)
  • Drop all Linux capabilities only add back the specific ones the container needs
  • Never set privileged: true without a documented, reviewed reason
  • Never mount hostPath volumes into application pods
  • Never share the host network or PID namespace

Also, add resource requests and limits on every container. A pod without limits is a pod that can starve every other workload on the node if something goes wrong. Plus, it’s a signal to attackers that the cluster isn’t being watched closely.

Step 4: Isolate the Network

Kubernetes gives every pod a routable IP and lets it talk to every other pod by default. That’s the opposite of what you want.

Install a CNI plugin that supports NetworkPolicies (Calico, Cilium, and Weave all do) and start with a default-deny policy in every namespace: no ingress, no egress, unless a policy explicitly allows it. Then add allow rules only for the specific communication paths your applications need: a frontend needs to reach the backend, the backend needs to reach the database, monitoring needs to scrape metrics. Everything else stays blocked.

For clusters that handle regulated workloads or east-west traffic between services, consider a service mesh (Istio, Linkerd) for mTLS between pods. It’s overkill for a lot of clusters, but where compliance requires encrypted service-to-service traffic, it’s the cleanest way to get there.

Step 5: Verify Every Image Before It Runs

The container image is the last chance to catch a problem before it hits the cluster. Treat every image as untrusted until you’ve verified it.

Build a pipeline that:

  • Pulls only from registries you control or explicitly trust
  • Scans every image for CVEs with Trivy, Grype, or an equivalent
  • Blocks deployment when critical vulnerabilities are found
  • Signs images with Cosign or Notary so the cluster can verify provenance at admission time
  • Uses your policy engine to reject any pod pulling from an unapproved registry

For the code inside the images, pin dependency versions, generate an SBOM for every build, and monitor those SBOMs for newly disclosed vulnerabilities. Supply chain attacks are cheaper than exploiting a running cluster, which is why they’ve become the entry point of choice.

For a wider look at hardening container workloads beyond Kubernetes, see our guide to Security Best Practices for Containerized Environments.

Step 6: Monitor, Audit, and Respond

Hardening is a snapshot, but runtime is where the actual attacks happen. If you aren’t watching, you won’t know until someone tells you.

For visibility:

  • Enable Kubernetes audit logging on every cluster
  • Send logs to a central SIEM
  • Run runtime threat detection (Falco or a commercial equivalent) to catch unauthorized process execution, unexpected network connections, and file writes to sensitive paths
  • Alert on RBAC changes, new privileged pod creations, and any use of kubectl exec into production namespaces

Then close the loop. Every alert needs a defined response path, and every incident should feed back into your hardening. If a policy failed, tighten it. If a control was missing, add it. Portainer’s audit logging captures every user action across every managed cluster, which is the piece most teams miss when rolling their own.

{{article-cta}}

Kubernetes Security Checklist

If you’re inheriting a cluster, running a security audit, or getting one ready for production, here’s the checklist to run through:

Access and Policy Enforcement

Control Plane and Data

Workloads and Network

Images and Runtime

Secure Your Kubernetes Clusters with Portainer

Hardening a cluster means locking down authentication and RBAC, protecting the API server and etcd, blocking privileged containers, isolating pod-to-pod traffic, and verifying every image before it runs. Doing this once is achievable, but doing it across every cluster you run is where security programs can fall apart.

Portainer sits in front of every cluster you manage and gives platform teams a single place to enforce policy, control access, and see what changed. Security Constraints wrap OPA Gatekeeper into toggles that apply across every connected cluster at once, predefined RBAC roles keep access control consistent whether you’re managing five clusters or five hundred, and audit logging streams every user action into your SIEM.

The result is that new clusters inherit your existing policies automatically, and the same rule you set in production applies everywhere else the moment it’s saved. You don’t reconfigure security for every cluster, you attach it.

Book a demo to see how Portainer keeps Kubernetes security consistent across every cluster you run.

FAQs

1. Is Kubernetes secure by default?

No. Kubernetes comes with permissive settings that most teams never adjust. Containers run as root, pod-to-pod network traffic is unrestricted, Secrets in etcd are only base64-encoded (not encrypted), and RBAC often grants more access than workloads need. Every one of these is a small oversight on its own, but attackers don’t need many. Securing Kubernetes means actively fixing the defaults.

2. What is the most important Kubernetes security control?

Least-privilege RBAC is one of the most important. The main reason is that every attack path in Kubernetes eventually runs through the API server, and RBAC decides what any authenticated user or workload can do once they reach it. When RBAC is well-scoped, most other controls have a smaller blast radius when they fail. When it’s overprovisioned, an attacker with a valid token can move through the cluster freely, and the network policies or admission rules downstream do very little to slow them down.

3. How do people handle security policy enforcement across Kubernetes clusters, like blocking privileged containers?

Teams use one of two mechanisms to make this work. First, Pod Security Admission is built into Kubernetes and enforces three preset levels (privileged, baseline, restricted) at admission time. For custom rules like blocking specific registries, requiring resource quotas, or enforcing ownership labels, teams add OPA Gatekeeper or Kyverno. Both engines run per cluster, so keeping the same policy consistent across a fleet requires GitOps or a central control plane. Portainer is a management layer that solves this directly. It wraps OPA Gatekeeper into toggles that apply across every connected cluster at once, so blocking privileged containers becomes a single change that propagates everywhere.

4. Does a managed Kubernetes service secure my workloads?

No. Managed services like EKS, GKE, and AKS handle the control plane for you, meaning the API server, etcd, and scheduler run on their infrastructure with baseline patching and hardening. Everything else, including your workloads, RBAC configuration, NetworkPolicies, admission policies, image supply chain, and runtime monitoring, is your responsibility. This is the shared responsibility model, and it’s where most Kubernetes breaches happen.

5. How often should I review Kubernetes security?

Quarterly at minimum, plus after any significant change. That includes every new cluster onboarding, every major Kubernetes version upgrade, every new team getting cluster access, and every incident. Between reviews, keep runtime monitoring on continuously and RBAC audits automated where possible. The gap between reviews is the window attackers exploit, so the more frequent the audit, the smaller the window.

Infrastructure Moves Fast. Stay Ahead.
Portainer Team
Portainer.io
Follow on LinkedIn

Stop Kubernetes Security Drift: Centralize Policy Enforcement and Hardening. See Portainer in Action

Tip  / Call out

Kubernetes