Container security is critical in modern cloud-native applications. Here’s a comprehensive guide to securing your containerized workloads.
Container Images
Use Minimal Base Images
# Bad: Large base image with many dependencies
FROM ubuntu:22.04
# Good: Minimal image with just what's needed
FROM gcr.io/distroless/static-debian12
Distroless images contain only the application and its runtime dependencies, reducing the attack surface.
Multi-Stage Builds
# Build stage
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o main
# Production stage
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/main /main
ENTRYPOINT ["/main"]
This keeps build tools and source code out of production images.
Kubernetes Security
Pod Security Standards
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10000
fsGroup: 10000
containers:
- name: app
image: nginx:1.25
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Network Policies
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-network-policy
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 8080
Runtime Security
Falco Rules
- rule: Terminal shell in container
desc: A terminal shell in a container
condition: >
spawned_process = container
and shell_procs = proc
and terminal_procs = shell
and container.entrypoint.exists = false
output: >
Terminal shell spawned in container (user=%user.name
command=%proc.cmdline container=%container.name)
priority: WARNING
Scanning Pipeline
# GitHub Actions example
- name: Scan container image
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
severity: 'CRITICAL,HIGH'
exit-code: '1'
Security should be embedded throughout the CI/CD pipeline, not added as an afterthought.
Image Signing
Use Cosign to sign and verify container images:
# Sign an image
cosign sign --yes ghcr.io/ankitmaurya/app:latest
# Verify before deployment
cosign verify --certificate-identity=xxx ghcr.io/ankitmaurya/app:latest
This ensures only trusted images are deployed to your cluster.
Secret Management
Never store secrets in images or Git. Use:
- Kubernetes Secrets (with encryption at rest)
- HashiCorp Vault
- AWS Secrets Manager
- External Secrets Operator
Container security is a continuous process. Regular audits and updates are essential.