top of page

Kubernetes Security Deep Dive: The Hands-On Guide for Real-World Engineers

  • Aug 23
  • 4 min read

Securing Your Cluster from the Ground Up

"Default-permit is not a policy - it's a disaster waiting to happen."— Every engineer who's debugged an exposed pod

Kubernetes is powerful—but with great flexibility comes great responsibility. You wouldn't deploy a web server with root password as 1234, so why launch a container that runs as root, talks to every other pod, and can read all secrets?


In this detailed blog post, we’ll go way beyond checklists and dive deep into how you, as a hands-on engineer, can secure your Kubernetes workloads using:


  • Network Policies

  • Pod Security Standards (PSS)

  • Secrets Management

  • Role-Based Access Control (RBAC)


With working examples, diagrams, and tips from the trenches, you’ll walk away with a blueprint you can apply today—not just in theory.

1 - Network Policies: Prevent Pod Chaos with Firewall Rules

By default, Kubernetes let's all pods talk to all other pods. That’s like giving every container a walkie-talkie—and zero supervision.

Real-World Risk

Say a dev pod running an old dependency gets popped by an attacker. Without a network policy, they can now scan and exploit internal services like databases, Redis, or even kubelet.

Solution: Define Network Policies

A NetworkPolicy is a Kubernetes object that restricts traffic at the pod level, based on:

  • Pod labels (source/destination)

  • Namespace labels

  • IP blocks

  • Ports and protocols


Your CNI plugin must support them! (Calico, Cilium, etc.)

Example 1: Block All Traffic to a Namespace

Create a default deny-all ingress:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: finance
spec:
  podSelector: {}
  policyTypes:
    - Ingress

Now, nothing can talk to pods in finance namespace—unless explicitly allowed.

Example 2: Allow Only Frontend → Backend

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend
  namespace: app
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
  policyTypes:
  - Ingress

Pro Tips

  • Start with default deny, then open up incrementally.

  • Tag pods and namespaces consistently to simplify policies.

  • Use tools like Cilium Hubble for visualizing pod-to-pod traffic.

2 - Pod Security Standards (PSS): Protect the Node, Protect Everything

“Running containers as root is like giving strangers root access to your laptop. You wouldn't do that—so don't do it in prod.”

Kubernetes gives you the power to define what workloads are allowed to run based on their security profile. That’s where Pod Security Standards come in.


The Three Pod Security Levels:

Level

Description

Typical Use

privileged

Full access to host features

Admin-only, rarely used

baseline

Prevents known bad practices (e.g., hostPath)

Dev environments

restricted

Enforces strict security (non-root, no host networking, etc.)

Production workloads

Enable PSS in Namespaces

Kubernetes (v1.25+) uses Pod Security Admission based on namespace labels.

kubectl label namespace prod \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=latest

Now all pods in prod must comply with the restricted policy. Non-compliant pods won’t even schedule.

What Does Restricted Block?

  • runAsUser: 0 → ❌

  • hostPath, hostNetwork, hostIPC → ❌

  • Privileged mode or capabilities like NET_ADMIN → ❌

Tip: Test Before You Enforce

Use audit or warn modes to preview issues:

kubectl label namespace staging \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/audit-version=latest

3 - Secrets Management: No More Base64 Band-Aids

Kubernetes Secrets are not secure by default. They’re just Base64-encoded and stored in etcd.

Let’s break that down.

The Problem

kubectl get secret my-db-pass -o yaml

This gives you... your production DB password in plaintext with a single command. Yikes.

Secure Your Secrets

1 - Enable Encryption at Rest

Edit the kube-apiserver config to use an encryption provider:

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-key>
      - identity: {}

Apply and restart the API server.

2 - Use External Secret Managers

Kubernetes + Cloud Provider = Secure Secrets

Examples:

  • AWS Secrets Manager

  • Azure Key Vault

  • Google Secret Manager

  • HashiCorp Vault


Use External Secrets Operator:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-secret
spec:
  secretStoreRef:
    name: aws-secrets-store
    kind: ClusterSecretStore
  target:
    name: db-creds
  data:
    - secretKey: password
      remoteRef:
        key: prod/db/password

Boom—automatic sync of secrets from cloud vaults to Kubernetes.

4 - RBAC: Define Who Can Do What

Without RBAC, any pod with access to the API could delete everything.

Kubernetes RBAC is like IAM for your cluster. It lets you grant precise permissions to users, service accounts, and groups.

RBAC Concepts Recap:

  • Role – Permissions within a namespace

  • ClusterRole – Permissions cluster-wide

  • RoleBinding / ClusterRoleBinding – Binds a role to a user or service account

Example: Read-Only Access to Pods

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev
  name: pod-reader
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: bind-pod-reader
  namespace: dev
subjects:
  - kind: ServiceAccount
    name: dev-sa
    namespace: dev
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RBAC Anti-Patterns to Avoid

🚫 verbs: ["*"]

🚫 resources: ["*"]

🚫 Giving system:masters to devs


Instead:

  • Break roles into least-privileged components.

  • Use audit tools like rakkess or kubectl-who-can.

  • Rotate service account tokens with short TTLs.

Bonus Section: Policy Automation & Auditing Tools

Kubernetes lets you secure workloads manually—but let’s be real: automation wins.

Must-Know Tools

Tool

Use Case

Kyverno

Kubernetes-native policy engine (validate, mutate, generate)

OPA Gatekeeper

Policy-as-code (custom rules, compliance checks)

Kube-bench

CIS Kubernetes benchmark scanning

Kubeaudit

Audit workloads for common misconfigs

Trivy

Scan images, clusters, configs for vulnerabilities

Kyverno Example: Block Untrusted Image Registries

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: restrict-image-registries
spec:
  validationFailureAction: enforce
  rules:
  - name: block-untrusted-registries
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Only images from ghcr.io or ECR are allowed."
      pattern:
        spec:
          containers:
          - image: "?(ghcr.io|*.amazonaws.com)/*"

Final Thoughts: Secure by Default, Harden Over Time

Kubernetes is not secure out of the box—but it gives you all the tools to make it airtight.

Start small. Enforce gradually. Automate ruthlessly.

Action Checklist

  •  Apply default deny NetworkPolicy

  •  Label namespaces with PSS (start with baseline)

  •  Encrypt secrets at rest or use External Secrets

  •  Audit RBAC and apply least privilege

  •  Integrate Kyverno or Gatekeeper for policy enforcement


Want Help Securing Your Kubernetes Clusters?

At Ananta Cloud, we specialize in:

  • Zero-trust Kubernetes architectures

  • GitOps + Policy-as-code setups

  • Cloud-native security reviews and remediation





Comments

Rated 0 out of 5 stars.
No ratings yet

Add a rating
average rating is 4 out of 5, based on 150 votes, Recommend it

Stay ahead with the latest insights delivered right to you.

  • Straightforward DevOps insights

  • Professional advice you can trust

  • Cutting-edge trends in IaC, automation, and DevOps

  • Proven best practices from the field

bottom of page