This article is based on reporting originally published on darkreading.com.
Why Traditional Security Falls Short in Kubernetes Environments
As more organizations shift to microservices-based architectures and orchestrate containerized workloads with Kubernetes, the perimeter-based security model that relied on firewalls and network segmentation begins to break down. Cloud infrastructure is elastic and highly dynamic — the static boundaries that firewalls enforce simply do not map cleanly onto ephemeral pods, virtual private cloud (VPC) networks, and cloud-native applications maintained by many different teams.
In a Kubernetes cluster, the threat model must account for risks that originate inside the running environment. Common examples include a malicious or compromised third-party library pulled in as a dependency, or a container image sourced from an untrusted registry. Because the attack surface is internal as well as external, distributed security controls are essential.
What Kubernetes Provides Natively
Compared to many open or VM-based platforms, Kubernetes ships with a reasonably strong set of built-in security primitives:
- Flexible authentication — Kubernetes supports multiple authentication strategies including X.509 certificates, bearer tokens, and OIDC identity providers.
- Role-Based Access Control (RBAC) — A mature RBAC system lets administrators define fine-grained permissions for users and service accounts across namespaces and resources.
- Admission controllers — Resources are validated (and optionally mutated) before being admitted into the cluster, enabling policy enforcement at creation time.
- Pod security controls — Configuration options allow operators to constrain how processes run inside containers (e.g., preventing privilege escalation, enforcing read-only root filesystems).
- Network Policies — Kubernetes NetworkPolicy resources enable east-west (intra-cluster) microsegmentation between pods.
Fine-grained microsegmentation, in particular, significantly reduces the attack surface by limiting lateral movement — making it harder for a compromised component to pivot to other services, exfiltrate data, or spread within the cluster.
Understanding Kubernetes Network Policies
Kubernetes NetworkPolicy is the primary API for controlling pod-to-pod and pod-to-endpoint traffic. Before configuring policies, it is important to understand the default behaviour and the key semantics:
- Open by default: Without any NetworkPolicy applied, all pods can send and receive traffic freely — to and from any source or destination inside or outside the cluster.
- East-west scope: Native NetworkPolicy semantics are limited to intra-cluster segmentation and CIDR block specification. Domain names and domain wildcards are not supported in policy rules.
- Label-based selection: Policies select pods using labels and define rules specifying which ingress or egress traffic is permitted for those pods.
- Additive and whitelisting: Policies are additive — there is no native concept of an explicit drop action. Once any NetworkPolicy selects a pod, all traffic not explicitly permitted is denied for that pod.
- CNI plugin requirement: NetworkPolicy enforcement requires a Container Network Interface (CNI) plugin that supports the NetworkPolicy API. Popular choices include Calico and Flannel, as well as cloud-provider CNI plugins that integrate with VPC networking.
Start with a Default Deny-All Policy
The most impactful first step is to flip the open-by-default posture by applying a default deny-all policy to each namespace. This single change means that no pod can send or receive traffic unless an explicit allow rule is defined. The recommended workflow is:
- Apply a default deny-all NetworkPolicy to every namespace.
- Incrementally add explicit allow policies for each known, legitimate communication path between services.
This approach — sometimes described as default deny, explicit allow — minimises the blast radius of any compromised component.
Below is a minimal example of a default deny-all NetworkPolicy for a namespace:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Code language: PHP (php)
With podSelector: {}, the policy selects all pods in the namespace. Specifying both Ingress and Egress policy types with no rules blocks all inbound and outbound traffic by default.
Ingress Traffic Controls: Load Balancers and Layer-7 Proxies
Beyond pod-to-pod policies, Kubernetes offers additional network security controls for traffic entering the cluster from external sources. Using special resource annotations on Service and Ingress objects, operators can instruct the Kubernetes cloud controller to configure underlying VPC security groups and load balancers — for example, restricting which source IP ranges are permitted to reach a load balancer. These annotations are consumed by the cloud controller, which acts as a translation layer between Kubernetes resources and the underlying cloud platform.
Where Native Kubernetes Security Falls Short
Despite these capabilities, Kubernetes native security controls have well-documented gaps that require additional tooling or architectural decisions to address:
- Host-network pods: Pods configured to run on the host network namespace are not subject to NetworkPolicy rules. These pods require separate controls at the host or infrastructure level.
- No explicit drop actions: Native NetworkPolicy has no way to express an explicit deny rule. Third-party tools such as Calico’s
GlobalNetworkPolicyextend the API to support deny semantics. - External domain endpoints: Workloads that need to reach external services (databases, SaaS APIs) identified by DNS hostnames cannot be segmented on their egress paths using native NetworkPolicy, since domain names are not supported.
- Identity-based access: Native controls do not provide workload identity or service-to-service authentication at the application layer. Service mesh solutions (such as Istio or Linkerd using mutual TLS via sidecar proxies) are typically required for this level of control.
- No policy violation logging: Kubernetes does not natively expose logs or statistics for network policy violations, making it difficult to feed data into intrusion detection and prevention systems (IDPS).
- DNS is open by default: The Kubernetes DNS service (used for service discovery) is accessible to every pod in the cluster by default. This creates a potential channel for exfiltration techniques such as DNS tunneling, which require specialised network security analysis to detect.
Complementary Tools and Practices
Given these limitations, a mature Kubernetes security posture typically combines native controls with additional layers:
- Extended CNI policies (e.g., Calico GlobalNetworkPolicy): Adds drop-action semantics and cluster-wide policy enforcement beyond namespace scope.
- Service mesh (e.g., Istio, Linkerd): Provides mutual TLS between services, workload identity, fine-grained traffic management, and observability through sidecar proxies without requiring application code changes.
- Admission controllers and policy engines (e.g., OPA/Gatekeeper, Kyverno): Enforce security policies at resource admission time — for example, blocking privileged containers or images from untrusted registries.
- Runtime security (e.g., Falco): Detects anomalous behaviour at runtime by monitoring system calls, providing the intrusion detection layer that native Kubernetes lacks.
- Image scanning: Integrate container image scanning into your CI/CD pipeline to catch known vulnerabilities before images reach production.
- Audit logging: Enable the Kubernetes API server audit log and ship logs to a centralised SIEM to capture all API activity for compliance and incident response.
Key Takeaways
Securing Kubernetes is not a single-step configuration task — it is an ongoing practice that spans the entire workload lifecycle. The most important principle is to understand and deliberately change the open by default posture of Kubernetes:
- Enable RBAC and apply the principle of least privilege to all users and service accounts.
- Apply default deny-all NetworkPolicies to every namespace and add explicit allow rules as needed.
- Use a CNI plugin that fully supports the NetworkPolicy API.
- Supplement native controls with a service mesh, extended CNI policies, and runtime security tooling to close the gaps that Kubernetes alone cannot address.
- Ensure policy violations, API audit events, and runtime anomalies are logged and monitored.
Kubernetes provides a strong foundation, but production-grade security requires deliberate configuration and complementary tooling layered on top of it.