Verified by Garnet Grid

Container & Kubernetes Security

Secure container workloads. Covers image scanning, runtime protection, pod security standards, network policies, secrets in K8s, supply chain security, and admission controllers.

Containers expand the attack surface in ways traditional security tools don’t cover. A vulnerable base image means every pod running it is compromised. A misconfigured pod running as root can escape to the host. A missing network policy means any pod can talk to any other pod. Container security requires defense-in-depth across the build, deploy, and runtime phases.


Security Across the Container Lifecycle

BUILD                    DEPLOY                   RUNTIME
┌──────────────┐        ┌──────────────┐         ┌──────────────┐
│ Image scan   │───────▶│ Admission    │────────▶│ Runtime      │
│ SBOM creation│        │ controllers  │         │ monitoring   │
│ Base image   │        │ Pod security │         │ Network      │
│ hardening    │        │ standards    │         │ policies     │
│ Secret scan  │        │ Resource     │         │ Forensics    │
│              │        │ limits       │         │              │
└──────────────┘        └──────────────┘         └──────────────┘

Image Security

Minimal Base Images

Base ImageSizeCVE SurfaceUse Case
ubuntu:22.0477 MBHigh (200+ packages)Development only
debian:slim80 MBMediumGeneral purpose
alpine5 MBLowMinimal workloads
distroless2-20 MBMinimal (no shell!)Production recommended
scratch0 MBNoneStatic Go/Rust binaries
# Multi-stage build with distroless
FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o /server

FROM gcr.io/distroless/static:nonroot
COPY --from=builder /server /server
USER nonroot:nonroot
ENTRYPOINT ["/server"]

Image Scanning Pipeline

# CI/CD image scanning
image-security:
  steps:
    - name: Build image
      run: docker build -t app:${{ github.sha }} .
    
    - name: Scan for vulnerabilities
      run: |
        trivy image --severity HIGH,CRITICAL \
          --exit-code 1 \
          app:${{ github.sha }}
    
    - name: Generate SBOM
      run: |
        syft app:${{ github.sha }} -o spdx-json > sbom.json
    
    - name: Sign image
      run: |
        cosign sign --key cosign.key app:${{ github.sha }}

Pod Security Standards

# Restricted pod security (production)
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 65534
    fsGroup: 65534
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: app:latest
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]
      resources:
        limits:
          cpu: "500m"
          memory: "256Mi"
        requests:
          cpu: "100m"
          memory: "128Mi"

Network Policies

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

---
# Allow web → app traffic only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-web-to-app
spec:
  podSelector:
    matchLabels:
      tier: app
  ingress:
    - from:
        - podSelector:
            matchLabels:
              tier: web
      ports:
        - port: 8080

Anti-Patterns

Anti-PatternProblemFix
Running as rootContainer escape → host compromiserunAsNonRoot: true, use non-root user
No network policiesAll pods can communicate freelyDefault deny, explicit allow per service
Latest tagNo reproducibility, unknown vulnerabilitiesPin image digests, scan on every build
Secrets in env varsVisible in pod spec, logs, crash dumpsUse K8s Secrets mounted as files, or external vault
No resource limitsNoisy neighbor or resource exhaustion DoSSet CPU/memory limits on every container
Writable root filesystemAttacker can modify binariesreadOnlyRootFilesystem: true

Checklist

  • Base images: minimal (distroless/alpine), pinned by digest
  • Image scanning: every build, block on HIGH/CRITICAL CVEs
  • SBOM: generated and stored for every image
  • Pod security: non-root, read-only filesystem, drop all capabilities
  • Network policies: default deny, explicit allow per service
  • Resource limits: CPU and memory on every container
  • Admission controllers: enforce policies on deploy
  • Secrets: external vault (HashiCorp, AWS SM), not in env vars
  • Runtime monitoring: anomaly detection, process monitoring
  • Image signing: cosign/Notary for supply chain integrity

:::note[Source] This guide is derived from operational intelligence at Garnet Grid Consulting. For container security consulting, visit garnetgrid.com. :::

Jakub Dimitri Rezayev
Jakub Dimitri Rezayev
Founder & Chief Architect • Garnet Grid Consulting

Jakub holds an M.S. in Customer Intelligence & Analytics and a B.S. in Finance & Computer Science from Pace University. With deep expertise spanning D365 F&O, Azure, Power BI, and AI/ML systems, he architects enterprise solutions that bridge legacy systems and modern technology — and has led multi-million dollar ERP implementations for Fortune 500 supply chains.

View Full Profile →