# Advanced Security Considerations for Hardening Container Runtimes and Kubernetes Network Policies in Production

> Secure your production Kubernetes by hardening container runtimes and network policies. Learn to implement advanced security like OCI compliance, user namespaces, seccomp, and default-deny network policies.

- Repository: [Arie Bregman/devops-exercises](https://github.com/bregman-arie/devops-exercises)
- Tags: deep-dive
- Published: 2026-02-28

---

**Hardening container runtimes and Kubernetes network policies in production requires migrating to OCI-compliant runtimes like containerd, enforcing user namespaces and seccomp profiles, implementing strict security contexts with non-root users, and deploying default-deny network policies with explicit pod-to-pod whitelisting to eliminate lateral movement vectors.**

Hardening container runtimes and Kubernetes network policies represents a critical defense-in-depth strategy for production workloads. According to the `bregman-arie/devops-exercises` repository, implementing advanced security controls at both the runtime and network layers significantly reduces the attack surface for containerized applications. This guide examines production-grade hardening techniques derived from the repository's comprehensive Kubernetes and container security documentation.

## Hardening Container Runtimes in Production

### Selecting a Production-Grade Runtime

The foundation of runtime security begins with selecting an OCI-compliant runtime actively maintained for production use. In [`topics/kubernetes/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/kubernetes/README.md) at line 265, the repository emphasizes preferring **containerd** or **CRI-O** over the deprecated Docker Engine for production clusters. These high-level runtimes provide better isolation controls and reduced attack surfaces compared to legacy alternatives.

### Securing Low-Level Runtimes with runc

At the low-level, `runc` implements the OCI runtime spec and directly launches containers. According to [`topics/containers/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/containers/README.md) at line 904, hardening `runc` requires enabling **user namespaces** to isolate container users from host users, applying **seccomp** profiles to filter syscalls, and strictly disabling privileged mode. These controls protect kernel namespace and cgroup isolation mechanisms from breakout attempts.

### Leveraging High-Level Runtime Features

`containerd` manages `runc` instances while providing additional security controls for image management and snapshotting. As documented in [`topics/containers/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/containers/README.md) at line 914, production deployments should enable **containerd's built-in security features** including image verification via cosign or Notary, runtime sandboxing capabilities, and limiting concurrent workloads per node to prevent resource exhaustion attacks.

### Implementing Security Contexts

The `securityContext` field defines pod-level privilege boundaries. According to [`topics/kubernetes/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/kubernetes/README.md) at line 2356, improper defaults can allow containers to run as root or mount host filesystems. Production pods must set `runAsNonRoot: true`, `readOnlyRootFilesystem: true`, drop all Linux capabilities, and use `fsGroup` only when necessary.

The following YAML demonstrates a hardened pod specification implementing these controls:

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
  labels:
    app: secure-app
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 1000
    runAsNonRoot: true
    readOnlyRootFilesystem: true
    capabilities:
      drop:
        - ALL
  containers:
  - name: app
    image: myregistry/secure-app:1.2.3
    ports:
    - containerPort: 8080
    resources:
      limits:
        cpu: "500m"
        memory: "256Mi"
    securityContext:
      allowPrivilegeEscalation: false
      seccompProfile:
        type: RuntimeDefault

```

*Key points*: non-root user, read-only filesystem, dropped capabilities, and default seccomp profile prevent privilege escalation and filesystem tampering.

## Production-Grade Kubernetes Network Policies

### Implementing Default-Deny Posture

By default, Kubernetes allows unrestricted pod-to-pod communication within namespaces. As noted in [`topics/kubernetes/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/kubernetes/README.md) at line 1689, production clusters require a **default-deny** `NetworkPolicy` that blocks all ingress and egress traffic, forcing explicit allow rules for required communication.

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

```

### Namespace Isolation and Pod-to-Pod Whitelisting

Multi-tenant clusters require clear traffic boundaries between namespaces. Apply **namespace-level policies** that only permit traffic from the same namespace or from trusted gateway namespaces. For fine-grained control, use **selector-based** `NetworkPolicy` rules that restrict traffic to specific labels.

The following policy explicitly permits only frontend pods to communicate with backend pods on port 8080:

```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

```

### Egress Controls and External Traffic Restrictions

Prevent compromised pods from exfiltrating data or reaching external command-and-control servers. Define egress policies that restrict outbound traffic to known services such as internal DNS, monitoring endpoints, or specific external APIs. This limits lateral movement and data exfiltration capabilities.

### Policy Enforcement and Verification

Not all CNI plugins enforce policies equally. Deploy a **CNI that supports policies** such as Calico, Cilium, or Kong Mesh. Verify that policy enforcement mode is set to **"enabled"** in the CNI configuration.

Integrate **policy linting** tools such as Datree or kube-score into CI/CD pipelines to catch misconfigurations before deployment. Enable **CNI-level logs** and forward them to a SIEM; use `kubectl logs` on the CNI daemonset for debugging policy violations.

## Summary

- **Runtime Selection**: Prefer containerd or CRI-O over deprecated Docker Engine, as documented in [`topics/kubernetes/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/kubernetes/README.md) line 265.
- **Low-Level Hardening**: Enable user namespaces, seccomp profiles, and disable privileged mode in runc configurations ([`topics/containers/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/containers/README.md) line 904).
- **High-Level Features**: Leverage containerd's image verification and sandboxing capabilities ([`topics/containers/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/containers/README.md) line 914).
- **Security Contexts**: Implement `runAsNonRoot`, `readOnlyRootFilesystem`, and drop all capabilities in pod specs ([`topics/kubernetes/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/kubernetes/README.md) line 2356).
- **Default-Deny Networking**: Establish default-deny network policies to block all traffic by default, then explicitly whitelist required communication ([`topics/kubernetes/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/kubernetes/README.md) line 1689).
- **Policy Enforcement**: Use CNI plugins like Calico or Cilium that support network policies and enable policy linting in CI/CD pipelines.

## Frequently Asked Questions

### What is the difference between containerd and runc in container runtime security?

containerd serves as the high-level runtime that manages image pulling, storage, and container lifecycle, while runc is the low-level OCI runtime that actually creates and runs containers. For security, containerd provides image verification and sandboxing features ([`topics/containers/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/containers/README.md) line 914), whereas runc requires hardening through user namespaces and seccomp profiles to protect kernel isolation mechanisms ([`topics/containers/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/containers/README.md) line 904).

### Why should I use default-deny network policies in Kubernetes?

Default-deny policies block all ingress and egress traffic by default, forcing explicit allow rules for any communication. This approach prevents unauthorized lateral movement between pods and reduces the blast radius of compromised containers. As documented in [`topics/kubernetes/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/kubernetes/README.md) line 1689, implementing default-deny is the first step toward production-grade network segmentation.

### How do I prevent containers from running as root in Kubernetes?

Set `runAsNonRoot: true` in the pod's `securityContext` and specify a non-zero `runAsUser` value. Additionally, configure `readOnlyRootFilesystem: true` and drop all Linux capabilities. According to [`topics/kubernetes/README.md`](https://github.com/bregman-arie/devops-exercises/blob/main/topics/kubernetes/README.md) line 2356, these settings ensure containers cannot escalate privileges or modify the root filesystem, significantly reducing attack vectors.

### Which CNI plugins support Kubernetes network policy enforcement?

Calico, Cilium, and Kong Mesh provide robust network policy enforcement capabilities. These CNIs translate Kubernetes NetworkPolicy resources into underlying firewall rules or eBPF programs. When deploying these plugins, verify that policy enforcement mode is explicitly enabled to ensure rules are actively blocking or allowing traffic as configured.