Container & Kubernetes Security

Container Security Fundamentals

4 min read

Containers revolutionized deployment but introduced new security challenges. Understanding container isolation, image security, and runtime protection is essential for cloud-native security.

Container Threat Landscape

Common Attack Vectors

Attack VectorDescriptionImpact
Vulnerable base imagesOutdated packages with known CVEsContainer compromise
Secrets in imagesHardcoded credentials in layersCredential exposure
Privileged containersRunning as root with host accessHost escape
Insecure registriesPulling from untrusted sourcesSupply chain attack
Runtime exploitationMemory exploits, code injectionContainer breakout

Container Isolation Model

┌────────────────────────────────────────────────┐
│                  Host OS Kernel                 │
├────────────────────────────────────────────────┤
│  Container 1    │  Container 2    │  Container 3│
│  ┌──────────┐   │  ┌──────────┐   │  ┌────────┐│
│  │ App      │   │  │ App      │   │  │ App    ││
│  │ Libs     │   │  │ Libs     │   │  │ Libs   ││
│  └──────────┘   │  └──────────┘   │  └────────┘│
│  Namespace      │  Namespace      │  Namespace │
│  cgroups        │  cgroups        │  cgroups   │
└────────────────────────────────────────────────┘

Containers share the host kernel—isolation depends on:

  • Namespaces: Process, network, mount, user isolation
  • cgroups: Resource limits (CPU, memory)
  • seccomp: System call filtering
  • AppArmor/SELinux: Mandatory access control

Secure Docker Configuration

Dockerfile Best Practices

# Use minimal base image with specific version
FROM python:3.12-slim-bookworm AS builder

# Create non-root user
RUN groupadd -r appuser && useradd -r -g appuser appuser

# Set working directory
WORKDIR /app

# Copy requirements first (better caching)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Production stage
FROM python:3.12-slim-bookworm

# Copy only necessary files from builder
COPY --from=builder /usr/local /usr/local
COPY --chown=appuser:appuser . /app

# Never run as root
USER appuser

# Use ENTRYPOINT for immutable commands
ENTRYPOINT ["python", "app.py"]

Key principles:

  • Multi-stage builds to reduce image size
  • Specific version tags (never latest)
  • Non-root user execution
  • Minimal base images (alpine, distroless, slim)

Docker Daemon Security

# /etc/docker/daemon.json
{
  "userns-remap": "default",
  "no-new-privileges": true,
  "seccomp-profile": "/etc/docker/seccomp/default.json",
  "icc": false,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "live-restore": true
}
SettingPurpose
userns-remapMaps container root to unprivileged host user
no-new-privilegesPrevents privilege escalation
icc: falseDisables inter-container communication
seccomp-profileRestricts system calls

Image Security

Vulnerability Scanning

Trivy - Industry standard scanner:

# Scan local image
trivy image myapp:latest

# Scan with severity filter
trivy image --severity HIGH,CRITICAL myapp:latest

# Scan and fail CI pipeline if vulnerabilities found
trivy image --exit-code 1 --severity CRITICAL myapp:latest

# Scan filesystem (for IaC misconfigurations)
trivy fs --scanners vuln,misconfig .

Cloud-native scanning:

# AWS ECR scanning
aws ecr start-image-scan \
    --repository-name myapp \
    --image-id imageTag=latest

# GCP Artifact Registry
gcloud artifacts docker images scan \
    gcr.io/project/myapp:latest

# Azure Container Registry
az acr repository show-manifests \
    --name myregistry \
    --repository myapp \
    --query "[].{tag:tags[0],vulnerabilities:changeableAttributes.vulnerabilityAssessment}"

Image Signing and Verification

Cosign for signing container images:

# Generate key pair
cosign generate-key-pair

# Sign image
cosign sign --key cosign.key myregistry/myapp:latest

# Verify signature before deployment
cosign verify --key cosign.pub myregistry/myapp:latest

Runtime Security

Container Runtime Best Practices

# Run container with security options
docker run \
    --read-only \
    --no-new-privileges \
    --cap-drop ALL \
    --cap-add NET_BIND_SERVICE \
    --security-opt="no-new-privileges:true" \
    --pids-limit 100 \
    --memory="512m" \
    --cpus="0.5" \
    myapp:latest
FlagSecurity Benefit
--read-onlyPrevents filesystem writes
--cap-drop ALLRemoves all Linux capabilities
--cap-addAdds only required capabilities
--no-new-privilegesBlocks privilege escalation
--pids-limitPrevents fork bombs
--memory/--cpusResource limits

Secrets Management

Never embed secrets in images:

# Bad - secret in environment variable visible in image layers
ENV API_KEY=secret123

# Good - mount secrets at runtime
docker run -v /secrets/api_key:/run/secrets/api_key:ro myapp

# Better - use Docker secrets (Swarm) or external secret manager
docker secret create api_key ./api_key.txt
docker service create --secret api_key myapp

Container Security Checklist

CategoryControlImplementation
ImagesUse minimal base imagesdistroless, alpine, slim
ImagesScan for vulnerabilitiesTrivy, Snyk, cloud-native
ImagesSign and verifyCosign, Notary
RuntimeRun as non-rootUSER directive
RuntimeDrop capabilities--cap-drop ALL
RuntimeRead-only filesystem--read-only
SecretsExternal managementVault, cloud secrets
LoggingCentralized loggingFluentd, cloud logging

Next, we'll secure Kubernetes clusters with RBAC, network policies, and pod security. :::

Quick check: how does this lesson land for you?

Quiz

Module 5: Container & Kubernetes 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.