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 Vector | Description | Impact |
|---|---|---|
| Vulnerable base images | Outdated packages with known CVEs | Container compromise |
| Secrets in images | Hardcoded credentials in layers | Credential exposure |
| Privileged containers | Running as root with host access | Host escape |
| Insecure registries | Pulling from untrusted sources | Supply chain attack |
| Runtime exploitation | Memory exploits, code injection | Container 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 /usr/local /usr/local
COPY . /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
}
| Setting | Purpose |
|---|---|
| userns-remap | Maps container root to unprivileged host user |
| no-new-privileges | Prevents privilege escalation |
| icc: false | Disables inter-container communication |
| seccomp-profile | Restricts 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 --security-checks vuln,config .
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
| Flag | Security Benefit |
|---|---|
| --read-only | Prevents filesystem writes |
| --cap-drop ALL | Removes all Linux capabilities |
| --cap-add | Adds only required capabilities |
| --no-new-privileges | Blocks privilege escalation |
| --pids-limit | Prevents fork bombs |
| --memory/--cpus | Resource 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
| Category | Control | Implementation |
|---|---|---|
| Images | Use minimal base images | distroless, alpine, slim |
| Images | Scan for vulnerabilities | Trivy, Snyk, cloud-native |
| Images | Sign and verify | Cosign, Notary |
| Runtime | Run as non-root | USER directive |
| Runtime | Drop capabilities | --cap-drop ALL |
| Runtime | Read-only filesystem | --read-only |
| Secrets | External management | Vault, cloud secrets |
| Logging | Centralized logging | Fluentd, cloud logging |
Next, we'll secure Kubernetes clusters with RBAC, network policies, and pod security. :::