Cloud & Infrastructure Security

Container & Kubernetes Security

4 min read

Container security is a hot interview topic. This lesson covers Docker hardening, Kubernetes RBAC, and cluster security patterns.

Docker Security Fundamentals

Container Isolation Layers

┌────────────────────────────────────────────────────────────┐
│                      HOST KERNEL                            │
├────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│  │ Container A │  │ Container B │  │ Container C │        │
│  │             │  │             │  │             │        │
│  │ ├─ PID NS   │  │ ├─ PID NS   │  │ ├─ PID NS   │        │
│  │ ├─ NET NS   │  │ ├─ NET NS   │  │ ├─ NET NS   │        │
│  │ ├─ MNT NS   │  │ ├─ MNT NS   │  │ ├─ MNT NS   │        │
│  │ ├─ USER NS  │  │ ├─ USER NS  │  │ ├─ USER NS  │        │
│  │ └─ cgroups  │  │ └─ cgroups  │  │ └─ cgroups  │        │
│  └─────────────┘  └─────────────┘  └─────────────┘        │
└────────────────────────────────────────────────────────────┘

Secure Dockerfile Practices

# Multi-stage build to minimize attack surface
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --target=/app/deps -r requirements.txt

# Use distroless for minimal runtime
FROM gcr.io/distroless/python3-debian12

# Copy only what's needed
COPY --from=builder /app/deps /app/deps
COPY --chown=nonroot:nonroot app.py /app/

# Never run as root
USER nonroot

# Use specific entrypoint
ENTRYPOINT ["python", "/app/app.py"]

Docker Security Checklist

PracticeWhy It Matters
Non-root userLimits container escape impact
Read-only filesystemPrevents runtime modifications
No privileged modePrevents host access
Resource limitsPrevents DoS
Minimal base imageSmaller attack surface
No secrets in imagesPrevents credential exposure
Image signingEnsures image integrity

Interview Question

Q: "What is a container escape and how do you prevent it?"

Answer: A container escape is when an attacker breaks out of container isolation to access the host system.

Prevention:

  • Never run containers as root
  • Never use --privileged flag
  • Drop all capabilities: --cap-drop=ALL
  • Use read-only root filesystem
  • Enable seccomp and AppArmor profiles
  • Keep kernel and container runtime updated
  • Use gVisor or Kata containers for high-security workloads

Kubernetes Security

RBAC (Role-Based Access Control)

# Role: What actions are allowed
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["pods/log"]
  verbs: ["get"]

---
# RoleBinding: Who gets the role
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: production
subjects:
- kind: ServiceAccount
  name: monitoring-sa
  namespace: production
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Pod Security Standards

LevelDescriptionUse Case
PrivilegedNo restrictionsSystem workloads only
BaselineMinimal restrictions, prevents known escalationsMost workloads
RestrictedHeavily restricted, security best practicesSensitive workloads
# Enforce restricted security at namespace level
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

Secure Pod Specification

apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 10000
    fsGroup: 10000
    seccompProfile:
      type: RuntimeDefault

  containers:
  - name: app
    image: myapp:v1.0.0@sha256:abc123...  # Pin by digest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]

    resources:
      limits:
        cpu: "500m"
        memory: "256Mi"
      requests:
        cpu: "100m"
        memory: "128Mi"

    volumeMounts:
    - name: tmp
      mountPath: /tmp

  volumes:
  - name: tmp
    emptyDir: {}

  automountServiceAccountToken: false  # Disable if not needed

Network Policies

# Default deny all ingress traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress

---
# Allow specific traffic only
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

Secrets Management in Kubernetes

# BAD: Secret in plain YAML (base64 is not encryption!)
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  password: cGFzc3dvcmQxMjM=  # Just base64 encoded!

---
# GOOD: Use external secrets operator
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: db-credentials
spec:
  refreshInterval: 1h
  secretStoreRef:
    name: aws-secrets-manager
    kind: ClusterSecretStore
  target:
    name: db-credentials
  data:
  - secretKey: password
    remoteRef:
      key: production/database
      property: password

Interview Tip: When discussing Kubernetes security, always mention the 4C's of cloud-native security: Code, Container, Cluster, Cloud. Each layer adds defense in depth.

Next, we'll cover Zero Trust architecture. :::

Quick check: how does this lesson land for you?

Quiz

Module 4: Cloud & Infrastructure Security

Take Quiz
FREE WEEKLY NEWSLETTER

Stay on the Nerd Track

One email per week — courses, deep dives, tools, and AI experiments.

No spam. Unsubscribe anytime.