# Why Securing Kubernetes Is Challenging but Critical
| Focus Area |
Risk or Concern |
Recommended Action |
| Cluster Infrastructure |
Core components like the API Server, etcd, and Nodes are central control points. If compromised, the whole cluster is at risk. |
Enforce strong authentication & authorization, encrypt communication and data at rest, and tightly control access to Nodes. |
| Application Security |
Business apps may have coding flaws or exposed APIs that attackers can exploit. |
Regularly audit apps for security gaps. Use runtime protection tools like Falco to detect suspicious behavior. |
| Container & Host Runtime |
Exploiting container runtimes or host OS can lead to container escape (ability of applications or processes running inside a container to access resources outside of the container that are not supposed to be available to them) — compromising the node or adjacent apps. |
Use minimal, hardened base images. Keep host OS patched. Apply host-level protections like AppArmor or SELinux. |
| Pod & Workload Isolation |
Pods may have excessive privileges or misconfigured access. |
Use Pod Security Admission, assign roles with RBAC, and block privilege escalation. Avoid risky features like hostPath. |
| Network Access Control |
By default, all Pods can talk to each other. |
Define Network Policies to explicitly allow necessary connections only. Use mTLS for encrypted, verified service-to-service communication. |
| Secrets & Configuration |
Secrets (e.g., passwords, API keys) can be exposed via logs, misconfiguration, or unauthorized access. |
Store secrets securely using Kubernetes Secrets or tools like Vault. Encrypt everything at rest and restrict access. |
| Image Supply Chain |
Vulnerabilities can be introduced via third-party or outdated container images. |
Scan images before deployment using tools like Trivy or Clair. Sign and verify images before they’re run in production. |
| Visibility & Threat Detection |
Without monitoring, breaches or misconfigurations may go unnoticed. |
Enable audit logging. Monitor workloads with runtime tools. Use centralized dashboards and alerting for early response. |
# What is the need for Kubernetes Service Accounts?
- Provide Identity for Pods (Authentication): Service accounts assign a secure identity to applications running inside Pods so they can interact with the Kubernetes API and external resources
- Enable Secure API Access from Pods: Kubernetes automatically injects a token into each Pod, allowing it to make authenticated API calls using its service account
- Limit Access to a Specific Namespace: Each service account belongs to one namespace, helping isolate permissions and control access locally
- Control Permissions with RBAC: Use Role-Based Access Control to define what actions a service account can perform — such as reading secrets or listing pods
- Avoid Using Default Service Account: For security, define custom service accounts with only the permissions your application truly needs
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: dev
# Practical Example: RBAC with Service Account
- ServiceAccount Provides Pod Identity: A
ServiceAccount represents an identity for Pods to authenticate with the Kubernetes API
- Role Defines Allowed Actions: A
Role lists what actions (like get, list, create) are allowed on which Kubernetes resources within a specific namespace
- RoleBinding Connects Identity to Permissions: A
RoleBinding links a Role to a ServiceAccount, granting that identity the defined permissions
- Used for Least-Privilege Access: This trio enables giving Pods only the exact access they need—no more, no less
- Supports Multiple Bindings: One
ServiceAccount can be bound to multiple Roles, and a Role can be bound to multiple ServiceAccounts
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader-sa
namespace: my-namespace
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: my-namespace
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: bind-pod-reader
namespace: my-namespace
subjects:
- kind: ServiceAccount
name: pod-reader-sa
namespace: my-namespace
roleRef:
kind: Role
name: pod-reader
namespace: my-namespace
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-reader-deploy
namespace: my-namespace
spec:
replicas: 1
selector:
matchLabels:
app: pod-reader
template:
metadata:
labels:
app: pod-reader
spec:
serviceAccountName: pod-reader-sa
containers:
- name: curl
image: curlimages/curl:latest
command:
- /bin/sh
- -c
- |
while true; do
# Token is automatically mounted at this path by Kubernetes
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -s --header "Authorization: Bearer $TOKEN" \
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
https://kubernetes.default.svc/api/v1/namespaces/my-namespace/pods;
echo "-----";
sleep 10;
done
# What is the need for ClusterRole and ClusterRoleBinding?
- Access Across All Namespaces: Use
ClusterRole when a Pod or user needs to list, get, or modify resources (like Pods or Nodes) across multiple namespaces or the whole cluster
- Grant Permissions to Non-Namespaced Resources: Cluster-wide resources like
nodes, persistentvolumes, clusterroles, and namespaces can only be managed using a ClusterRole
- Avoid Over-Provisioning Roles in Each Namespace: Instead of duplicating the same
Role in every namespace, a single ClusterRole simplifies management and ensures consistency
- Secure But Flexible Access Control:
ClusterRole with ClusterRoleBinding can grant access to specific users, groups, or service accounts across the cluster without modifying every namespace
- Enable Admin or Read-Only Cluster-Wide Views: Required for dashboards, monitoring tools (e.g., Prometheus, Lens) that need visibility across namespaces
apiVersion: v1
kind: ServiceAccount
metadata:
name: cluster-pod-reader-sa
namespace: my-namespace
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: bind-cluster-pod-reader
subjects:
- kind: ServiceAccount
name: cluster-pod-reader-sa
namespace: my-namespace
roleRef:
kind: ClusterRole
name: cluster-pod-reader
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: read-pods-deploy
namespace: my-namespace
spec:
replicas: 1
selector:
matchLabels:
app: pod-reader
template:
metadata:
labels:
app: pod-reader
spec:
serviceAccountName: cluster-pod-reader-sa
containers:
- name: reader
image: curlimages/curl:latest
command:
- /bin/sh
- -c
- >
while true; do
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token);
curl -s --header "Authorization: Bearer $TOKEN"
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
https://kubernetes.default.svc/api/v1/pods;
echo "---";
sleep 10;
done
# What is the need for a Network Policy?
- Enforce Zero Trust Networking: By default, Kubernetes allows all Pod-to-Pod communication. Network policies help enforce least privilege—only explicitly allowed traffic is permitted
- Restrict Unwanted Communication Between Services: In a microservices setup, not all services should talk to each other. For example, a frontend service may access the backend, but it shouldn't talk directly to the database
- Protect Sensitive Data in Transit: Limit traffic to only expected sources and destinations—e.g., only allow traffic to the database from backend services, not from all Pods
- Control Egress and Ingress Traffic: Ensure that only specific Pods can access external services (egress) or be reached by them (ingress)—important for compliance and audit
- Limit Blast Radius of Compromised Pods: If one Pod is compromised, network policies can prevent it from reaching other sensitive services like payment or admin microservices
- Create Logical Security Boundaries: Apply isolation by namespace, label, or app role (e.g., only
role: backend can access role: db)
# Give a Practical Example of Network Policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: my-microservices
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-from-frontend
namespace: my-microservices
spec:
podSelector:
matchLabels:
role: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-database-from-backend
namespace: my-microservices
spec:
podSelector:
matchLabels:
role: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: backend
# When do you use Pod Security Admission?
- Pod Security Admission: Enforces Kubernetes' built-in security standards (
restricted, baseline, privileged) at the namespace level to control which Pods can be admitted based on their security context
Privileged: No restrictions (for legacy workloads)
Baseline: Moderate restrictions; avoids known privilege escalations
Restricted: Strongest controls; disallows host access, privilege escalation, most volume types
- Fail Early with Clear Errors: Admission controller rejects non-compliant pods at creation time, giving immediate feedback instead of allowing unsafe pods to run
- Enforce Secure Defaults for All Teams: Helps platform teams ensure every developer follows security best practices (e.g., disallow hostPath usage)
- Apply Policies Based on Namespace: Apply different levels of security (
restricted, baseline, privileged) to different environments (e.g., prod vs dev)
- Prevent Dangerous Pod Configurations: Blocks pods that attempt to run as root or use privileged containers, reducing the risk of accidental or malicious escalations
- Avoid Misuse of Host Resources: Prevents containers from mounting sensitive host directories or using host networking, which could expose the host node
# How does Pod Security Admission work? What is the role of Pod Security Standards (PSS)?
- Pod Security Admission: Pod Security Admission (PSA) is a built-in admission controller that checks Pod specifications before they are created in the cluster
- Enforce Security Rules at Namespace Level: PSA works by evaluating Pods against predefined rules configured per namespace
- Leverage Pod Security Standards (PSS): Kubernetes defines three built-in security profiles —
privileged, baseline, and restricted — to describe increasing levels of security
Privileged: No restrictions (for legacy workloads)
Baseline: Moderate restrictions; avoids known privilege escalations
Restricted: Strongest controls; disallows host access, privilege escalation, most volume types
- Use Labels to Set Enforcement Mode: Admins apply labels like
pod-security.kubernetes.io/enforce: restricted to a namespace to apply a PSS level
- Offer Flexible Modes of Operation: PSA supports three modes:
enforce: Blocks Pods that do not meet the configured Pod Security Standard—used to strictly enforce security policies in production
audit: Logs violations of the security standard without blocking Pod creation—ideal for monitoring policy compliance
warn: Displays warnings to users at creation time if a Pod would violate policy—useful for developer awareness during testing or onboarding
- Apply Different Modes for Dev and Prod: You can use
warn in dev namespaces to educate developers, and enforce in prod to block insecure Pods
- Avoid Complex Custom Policies: PSS gives you a standardized, Kubernetes-native way to enforce common security best practices without writing your own policies
apiVersion: v1
kind: Namespace
metadata:
name: secure-apps
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
# What is the need for SecurityContext?
- SecurityContext: Defines privilege and access settings for a Pod or container, helping enforce safe defaults
- Avoid Running as Root: By default, containers may run as the root user, which can be dangerous if compromised
- Enforce Non-Root Execution: Use
runAsNonRoot and runAsUser to force applications to run with limited privileges
- Restrict Privilege Escalation: Set
allowPrivilegeEscalation: false to prevent processes from gaining more permissions than they start with
- Drop Unnecessary Capabilities: Use
capabilities.drop to remove Linux kernel capabilities like NET_ADMIN (Network Administration) or SYS_TIME (Change System Time) for tighter security
- Apply Consistent Security Defaults: Define
securityContext at the Pod level to apply secure settings to all containers inside a Pod
- Improve Isolation and Defense-in-Depth: Helps reduce impact if a container is compromised, protecting host and other workloads
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
# List a few tools to enhance security posture of workloads running in Kubernetes
| Tool |
Category |
Explanation |
| Trivy |
Vulnerability Scanning |
Scans container images, code, and Kubernetes configs to detect known vulnerabilities and misconfigurations before deployment. Helps ensure only secure workloads are promoted. |
| Snyk |
Vulnerability Scanning |
Identifies security issues in application dependencies, Dockerfiles, and infrastructure-as-code. Offers fix suggestions, making it ideal for development teams and CI/CD pipelines. |
| Clair |
Vulnerability Scanning |
Automatically scans container images in registries for CVEs (Common Vulnerabilities and Exposures). Often integrated into image repositories to prevent insecure images from being deployed. |
| Falco |
Runtime Threat Detection |
Monitors running workloads for suspicious activity like shell access, file changes, or network connections. Helps detect security breaches in real time. |
| Seccomp |
Runtime Hardening |
Restricts system calls a container can make, reducing the potential damage from compromised workloads. Enforces minimal permissions at the Linux kernel level. |
| AppArmor |
Runtime Hardening |
Defines security profiles that limit container behavior (e.g., file and network access). |
| SELinux |
Host & Container Isolation |
Applies strict access control rules to prevent containers from accessing host or other container resources. Often required in high-security or government environments. |