Docker Containers & Kubernetes Architecture
Master production multi-stage container optimization, Docker Compose multi-service topology networking, Kubernetes control plane architecture, and Helm & ArgoCD GitOps continuous deployment.
Multi-Stage Dockerfile Builder & Optimization Inspector
Docker Compose Service Stack Generator & Topology Engine
Kubernetes Control Plane vs Worker Node Architecture
Control Plane (Master Node)
Global cluster state, scheduling & API management
Worker Nodes (Node 01..03)
Runs application pods, container runtime & networking
Central API gateway and orchestration engine. Validates and processes all REST requests from kubectl, controllers, and kubelets.
Ingress ➔ Kubernetes Service ➔ Pod Endpoints Traffic Flow
Simulate live HTTP ingress packet decapsulation and load balancing
Helm Charts Packaging & ArgoCD GitOps Sync Visualizer
Trivy Scanner Simulator — CVE Hunt Inside Your Image
Pick an image, run a simulated trivy image scan, and watch the vulnerability report build up: severity counts, per-package fixes, an SBOM (CycloneDX) preview, and an exportable JSON report.
Select an Image Target & Scan
Kubernetes Resource Quotas & Limits
Master CPU & memory request/limit math, namespace-wide ResourceQuota enforcement, LimitRange defaults, QoS class mechanics (Guaranteed · Burstable · BestEffort), and efficiency metrics that keep costs and evictions in check.
CPU & Memory Requests/Limits Calculator
Guaranteed minimum for scheduling
Burst ceiling before CPU throttling
Reserved on nodes at placement
OOM-kill threshold
Spare node headroom: 7.75 cores
Spare node headroom: 31.5Gi
ResourceQuota Builder
Scope restricts the quota to pods matching that QoS class (BestEffort / NotBestEffort) or the whole namespace (Default).
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: default
spec:
hard:
pods: 20
requests.cpu: "2"
limits.cpu: "4"
requests.memory: "4Gi"
limits.memory: "8Gi"• Admission is rejected when the pod's declared request/limit would exceed the remaining quota for that resource.
• Resources counted: requests.* and limits.* are summed across all containers in the pod.
• If a namespace has a quota for requests.cpu, every pod must declare it (ingress) or be rejected.
LimitRange Configurator
Lowest allowed request/limit
Injected when request omitted
Injected when limit omitted
Hard ceiling per container
Lowest allowed request/limit
Injected when request omitted
Injected when limit omitted
Hard ceiling per container
apiVersion: v1
kind: LimitRange
metadata:
name: container-limits
namespace: default
spec:
limits:
- max:
cpu: "4000m"
memory: "8192Mi"
min:
cpu: "50m"
memory: "64Mi"
default:
cpu: "250m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
maxLimitRequestRatio:
cpu: "4"
memory: "2"
type: Container• When a container omits a limit, the namespace default is injected; when it omits a request, defaultRequest is injected.
• Containers declaring values outside [min, max] are rejected at admission.
• maxLimitRequestRatio caps how far a container's limit may exceed its request for the same resource.
QoS Class Calculator
At least one container declares a request or limit, but the Guaranteed criteria are not fully met. Middle tier: can burst, may be evicted when pressure hits.
1. No requests or limits anywhere → BestEffort.
2. Every container sets CPU request = CPU limit AND memory request = memory limit → Guaranteed.
3. Anything else with at least one request/limit → Burstable.
apiVersion: v1
kind: Pod
metadata:
name: qos-demo
namespace: default
spec:
containers:
- name: api-server
resources:
requests:
cpu: "250m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
- name: cache
# no requests/limits — contributes to BestEffort
restartPolicy: Always
# Pod QoS class: BurstableResource Efficiency Metrics
From metrics: sum(rate(container_cpu_usage_seconds_total))/requests
From metrics: container_memory_working_set_bytes vs requests
Spare node headroom: 6 cores
Spare node headroom: 30Gi
Kubernetes Network Policy Visual Builder 🛡️
Build ingress/egress allowlists with pod, namespace and CIDR selectors — then preview the traffic flow, generated YAML, and a live allow/deny simulator.
🛡️ Ingress / Egress Rule Builder
4 active🧪 Policy Effect Simulator
📡 Visual Traffic Flow
📄 Generated YAML
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-api-allowlist
namespace: prod
spec:
podSelector:
matchLabels:
app: web
tier: frontend
policyTypes: [Ingress, Egress]
ingress:
# rule: allow-frontend-web
- from:
- podSelector:
matchLabels:
app: frontend
- namespaceSelector:
matchLabels:
app: payments
ports:
- port: 80
protocol: TCP
# rule: allow-monitoring
- from:
- namespaceSelector:
matchLabels:
role: monitoring
ports:
- port: 9090
protocol: TCP
egress:
# rule: allow-db-out
- to:
- namespaceSelector:
matchLabels:
app: db
ports:
- port: 3306
protocol: TCP
# rule: allow-payments-lb
- to:
- ipBlock:
cidr: 203.0.113.0/24
ports:
- port: 443
protocol: TCP🔒 Namespace Isolation Mode
Kubernetes Ingress & Service Mesh
Route external traffic into the cluster with NGINX Ingress, then go deeper: path-based routing builders, TLS termination, mutual-TLS mesh identity, canary weight splitting and traffic mirroring with Istio. Compare the two control planes side by side.
NGINX Ingress Controller vs Istio Service Mesh
Ingress Resource — Path-Based Routing Builder
TLS Termination Configuration
mTLS Service Mesh Visualization
1. Traffic is encrypted pod-to-pod — the cluster network is no longer trusted.
2. Replay/middlebox attacks fail: a client must present a cert bound to its identity.
3. STRICT rejects legacy clients until they adopt mTLS — migrate with PERMISSIVE first.
Canary Deployment Weights
Traffic Mirroring (Shadowing)
Persistent Volumes & State on EKS
Interactive lab for the PV/PVC contract: watch volumes travel from Pending to Bound (and beyond), compare EBS and EFS StorageClasses, check which access mode fits your workload, choose a reclaim strategy, right-size capacity — then snapshot and restore.
Pending → Bound → Deleted → (what happened to my data?)
- • PVC = a claim; PV = the actual volume (EBS volume or EFS file system).
- • The StorageClass provisioner (ebs.csi.aws.com) creates PVs on demand — dynamic provisioning.
- • With WaitForFirstConsumer (gp3 / io2), the PV is only created after a Pod is scheduled — so the EBS volume lands in the node's AZ.
- • Deleting the PVC detaches the PV: phase → Released. The reclaim policy picks what happens to the bytes.
- • EBS PVs attach to exactly one node; EFS PVs are mounted over NFS from any node.
Delete.EBS vs EFS — choose your provisioner
Baseline performance is size-independent — a 1 GiB gp3 already has 3 000 IOPS; only pay extra IOPS above the baseline.
reclaimPolicy follows Module 4's selector — a class is created once; edit means recreate.
RWO / ROX / RWX — how many pods can touch it?
| Mode | Full name | Nodes | Writers | EBS | EFS |
|---|---|---|---|---|---|
| RWO | ReadWriteOnce | 1 node | 1 writer (single pod) | ✓ | ✓ (as container root volume) |
| ROX | ReadOnlyMany | Many nodes | 0 writers — all readers | ✓ | ✓ |
| RWX | ReadWriteMany | Many nodes | Many writers | ✗ | ✓ |
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: apps-rwo
namespace: app-prod
spec:
accessModes:
- RWO
storageClassName: ebs-gp3
resources:
requests:
storage: 100Gi
---
ReadWriteOnce (RWO) — PostgreSQL, MySQL, Redis — classic single-writer databases.The fate of your bytes when the PVC is deleted
PVC deleted → PV phase becomes Released → the EBS volume / EFS file system is untouched. PV is NOT automatically rebound — an admin must delete the PV (and optionally re-market the volume). Data is safe but orphaned without manual cleanup; the cloud storage keeps billing you.
Tip: reclaimPolicy is fixed at StorageClass creation — choose Delete for auto-cleanup or Retain for insurance policies, and pair either with scheduled snapshots (Module 6).
Right-size the cluster storage budget
| Class | $/GiB | Cost for 300 GiB | IOPS est. | Throughput | Zones |
|---|---|---|---|---|---|
| EBS gp2 | $0.1 | $30.00 | 300 IOPS | ≤ 250 MiB/s | Single-AZ |
| EBS gp3 | $0.08 | $24.00 | 3,050 IOPS | 125 MiB/s | Single-AZ |
| EBS io2 | $0.125 | $37.50 | 50,000 IOPS | up to 4 GiB/s | Single-AZ |
| Amazon EFS | $0.3 | $90.00 | 10+ GiB/s burst | elastic | Multi-AZ |
IOPS estimates are per volume of the selected size (gp2: 3×GiB · gp3: 3 000 + 0.5×GiB · io2: 500×GiB) — EFS scales elastically regardless of reported capacity.
Point-in-time recovery in three clicks
# No snapshots yet — press "Take Snapshot" to simulate an AWS EBS snapshot # (EFS snapshots behave the same via efs-backup).
dataSource points at the VolumeSnapshot — the original volume is never touched.Container Platform / Image Supply Chain
Docker Image Registry & Tag Strategies
Tag immutability, retention economics, multi-arch distribution, and layer anatomy — everything that decides whether an image is safe, findable, and cheap to store.
Image Tag Strategy Selector
Each strategy is a promise about repo:tag → digest stability. Pick one and inspect its failure modes.
Example references
Image Lifecycle Visualizer
Every image travels build → registry → cluster → garbage. Drag the stage slider.
Build
docker build
docker build composes immutable layers (filesystem diffs). Each instruction (FROM, RUN, COPY) adds one layer; a rebuild reuses unchanged layers unless COPY'd files changed.
Retention Policy Builder
Policies fight registry sprawl. Tune rules below and watch the prune preview.
per repository
orphaned manifests
beyond newest 2
comma-separated; never expires
Prune preview — 14 images
Generated policy
Mutable tags (branch deployments, re-tagged versions) escape age rules — pin policies to digest when traceability matters
Multi-Arch Manifest Viewer
One tag, many architectures: the manifest list (index) points to per-arch manifests.
registry.example.com/team/payment-api:latest (index)
Selected manifest
Registry Cost Calculator — ECR / ACR / GCR
Storage is billed per unique byte; egress per pull crossing the cloud boundary.
Basic = $0, Standard/$25, Premium/$100
Amazon ECR
AWS$12.87/mo
Flat $0.10/GB-mo storage; egress billed at standard AWS data-transfer rates. Free tier: 500 MB/mo private for new accounts (12 months).
Google Artifact Registry (GCR)
GCP$13.41/mo
GCR is deprecated in favor of Artifact Registry. Storage $0.10/GB-mo; egress to internet at GCP network pricing (higher first-TB tier). Free tier 0.5 GiB/mo.
Azure Container Registry
Azure$12.82/mo
ACR storage ~$0.10/GB-mo beyond SKU-included quota; egress Zone-1 pricing applies additionally. SKUs (Basic/Standard/Premium) add their own monthly fee — add yours below.
Storage = unique layers after reuse deduction (80%); actual bills depend on image variance and retention. ACR also carries SKU monthly fees — the SKU input above is your own plan price.
Image Layer Analyzer
Peel an image: each layer is a filesystem diff. Same layers between images = stored once.
registry.example.com/team/payment-api:v2.4.1
Multi-stage build: node runtime only in final image. Even a tiny app ships the full base — check apk/apt layers & multi-stage=1.
RBAC & Cluster Hardening Simulator
Design least-privilege Roles and Bindings, trace real authorization decisions through the RBAC chain, attach ServiceAccounts to Pods, apply Pod Security Standards, and harden security contexts — live in the browser.
Role & ClusterRole Builder
Namespaced Roles only affect resources in their own namespace.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deployment-manager
namespace: ci-system
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch"]💡 get/list/watch is read-only, create/update/patch mutates, delete destroys. Grant the least set the workload actually needs.
RoleBinding / ClusterRoleBinding Configurator
Lets the CI pipeline manage its own workload objects inside ci-system.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ci-builder-workloads
namespace: ci-system
subjects:
- kind: ServiceAccount
name: ci-builder
namespace: ci-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ci-workloadPermission Evaluator
Decision path: ci-builder-workloads
| API Group | Resource | Verbs |
|---|---|---|
| core/v1 | configmaps | creategetlistupdatewatch |
| core/v1 | nodes+pods+services+endpoints | getlistwatch |
| core/v1 | pods+pods/log | createdeletegetlistupdatewatch |
| core/v1 | services | creategetlistwatch |
| apps | deployments+replicasets | creategetlistpatchupdatewatch |
| apps | deployments+statefulsets+daemonsets | getlistwatch |
ServiceAccount & Pod Association
The API server authenticates in-cluster calls with this token — which ServiceAccount you bind decides what that Pod may do (Module 3).
apiVersion: v1 kind: ServiceAccount metadata: name: ci-builder namespace: ci-system automountServiceAccountToken: true imagePullSecrets: - name: registry-creds
apiVersion: v1
kind: Pod
metadata:
name: ci-builder-pod
namespace: ci-system
spec:
serviceAccountName: ci-builder
automountServiceAccountToken: true
imagePullSecrets:
- name: registry-creds
containers:
- name: ci-builder-pod
image: registry.company.io/ci-agent:v2.3Pod Security Standards
Enforce rejects non-compliant Pods at admission.
- • Privileged containers are prohibited
- • allowPrivilegeEscalation must be false
- • hostNetwork is prohibited
- • HostPath volumes are prohibited
- • runAsNonRoot: true and a non-zero runAsUser are required
- • seccompProfile: RuntimeDefault or Localhost is required
- • capabilities must drop CAP_ALL (NET_BIND_SERVICE may be added)
| Control | Privileged | Baseline | Restricted |
|---|---|---|---|
Privileged Containers privileged: true | ✓ | ✗ | ✗ |
Host Namespaces hostPID / hostIPC: true | ✓ | ✗ | ✗ |
Host Network & Ports hostNetwork: true | ✓ | ✗ | ✗ |
HostPath Volumes mount path from host filesystem | ✓ | ✗ | ✗ |
Privilege Escalation allowPrivilegeEscalation: false | ✓ | ✗ | ✗ |
Linux Capabilities Drop ALL, may add NET_BIND_SERVICE only | ✓ | ◐ | ◐ |
Seccomp RuntimeDefault / Localhost | ✓ | ✓ | ✗ |
runAsNonRoot runAsNonRoot: true | ✓ | ✓ | ✗ |
runAsUser ≠ 0 non-zero UID at runtime | ✓ | ✓ | ✗ |
SELinux type container_t only | ✓ | ◐ | ◐ |
apiVersion: v1
kind: Namespace
metadata:
name: payments
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.30Security Context Configurator
✓ No hardening issues detected — this Pod matches restricted-level best practice.
apiVersion: v1
kind: Pod
metadata:
name: hardened-api
spec:
securityContext:
fsGroup: 2000
containers:
- name: app
image: registry:9090/hardened-api:latest
securityContext:
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
seccompProfile:
type: RuntimeDefaultHPA & VPA Autoscaling Control Room
Configure metrics, tune scale behaviors, then watch replica decisions play out live
HPA Metric Configurator
Pick the signal the controller watches
NAME REFERENCE TARGETS MIN MAX REPLICAS
web-api Deployment/web-api 70% 2 10 2
Scale-Up / Scale-Down Behavior Editor
Stabilization windows + per-event rate policies
Target Utilization → Required Replicas Calculator
ceil( replicas × observed ÷ target ) — the math HPA runs every reconcile loop
Vertical Pod Autoscaler — Recommendation Viewer
VPA mines history (histograms) and emits request bounds, not just a target
| Metric | Current | Observed | Lower | Recommended | Uncapped | Upper | Δ vs current |
|---|---|---|---|---|---|---|---|
| cpu | 500m | 318m | 268m | 343m | 366m | 532m | −31% |
| memory | 512Mi | 542Mi | 484Mi | 569Mi | 607Mi | 910Mi | +11% |
Status: Running · target: web-api
Recommendation: cpu 343m (268m–532m) · memory 569Mi (484Mi–910Mi)
Autoscaling Simulator — Live Replica Decisions
Drives the configured metric through HPA math: formula → stabilization → policy → min/max bounds
Press ▶ Simulate to watch the HPA compute replicas against the traffic spike scenario
No samples yet — start the simulation.
— waiting for the first scale event —
✅ Autoscaling Best Practices
- ▸ Start with CPU utilization (~70–80%), add custom metrics (QPS, queue depth) only once they stabilize.
- ▸ Set minReplicas ≥ 2 for HA — the floor keeps serving even at zero load.
- ▸ Scale down gently: stabilizationWindowSeconds ≥ 300s prevents flapping on dips.
- ▸ HPA scales on per-pod averages; per-pod skew is handled by VPA instead.
- ▸ VPA on memory + HPA on CPU is battle-tested; avoid both on the same metric in Auto mode.
- ▸ After VPA changes requests, HPA's utilization denominator changes — re-check targets.
Diagnose Pods Like a Cluster SRE
Walk the Pod lifecycle state machine, decode the four failure archetypes (CrashLoopBackOff, ImagePullBackOff, Pending, OOMKilled), generate exact kubectl fire commands, replay cluster events, and tune liveness/readiness probes until the pod stays green.
Pod Lifecycle State Machine Simulator
Scheduler picks a node, kubelet pulls the image, probes pass, pod goes Ready.
STATUS: Running READY: 1/1 RESTARTS: 0 AGE: 2m
This scenario passes through Pending → ContainerCreating → Running. Click any phase to inspect its meaning, output signals, and the exact kubectl probe.
Common Pod Failure Pattern Library
The kubelet detects the container exiting with a non-zero code shortly after start and backs off with exponential delay (10s, 20s, 40s … up to 5m) before each retry. Almost always an app-level bug for freshly written code — rarely an infrastructure problem.
- ▸Application panic / unhandled exception during startup
- ▸Missing env var, config file, or secret the app hard-crashes on
- ▸Port already in use inside the container or namespace
- ▸Wrong architecture: amd64 image scheduled onto an arm64 node
- ▸Probe fails from t=0 with failureThreshold=1 — the probe kills it before readiness ever passes
- 1Read the last run: kubectl logs <pod> --previous -c app
- 2Verify mounts and secrets: kubectl exec <pod> -- env && cat /app/config/*
- 3Run the image locally with the same args and observe the exit code
- 4Temporarily override the entrypoint to a sleep to debug interactively
- 5Give the app room to boot: raise liveness initialDelaySeconds before blaming it
- ✓kubectl get pods → STATUS: CrashLoopBackOff, RESTARTS climbing
- ✓kubectl logs <pod> --previous → application stack trace at startup
- ✓kubectl describe pod <pod> → Events: Back-off restarting failed container
kubectl Debug Command Generator
kubectl logs web-7b6f9d-4x7k2 -c app -n default --tail=50
kubectl get events — Live Viewer Simulator
Liveness / Readiness / Startup Probe Debugger
Observability Stack Lab
Prometheus metric collection, Grafana dashboard composition, Tempo/Jaeger distributed tracing, structured log streams, alert rule authoring, and SLI/SLO budgeting — the full observability loop for containerized workloads.
Live Metric Simulator
Gauges sampled every 1300ms — counters stay monotonic, rate() converts them to usable rates.
Dashboard Builder
Compose panels from the widget palette, size them on the canvas, export provisioning JSON.
empty canvas — add widgets from the palette
or pick a preset template above
Trace Waterfall — Jaeger / Tempo
One user request fans out across services; every span carries start time, duration, status, and its parent link.
This span took 1140ms — 92% of the 1240ms trace.
Log Stream Explorer
JSON-structured entries with levels, services, and key=value fields — filter, search, live-tail.
Prometheus Alert Configurator
Author a rule against live simulated values, evaluate it repeatedly, and export the YAML for your cluster.
groups:
- name: container-observability.alerts
rules:
- alert: HTTP_5XX_ERROR_RATE
expr: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100 > 2
for: 5m
labels:
severity: critical
team: "platform"
env: "prod"
annotations:
summary: "5xx rate is at {{ $value }}% of traffic"
description: "Value 1.7% is > 2 for 5m."Error Budget Calculator
Turn SLIs (good / total) into an SLO, then track how much of the error budget has been consumed.
SLI = successful requests / total requests — counts "good" events over the window.
Observability Loop Cheat Sheet
Expose /metrics via client libraries; watch label cardinality; scrape on a fixed interval; store with a retention policy.
Grafana panels over PromQL; variables + provisioning keep dashboards reproducible; alert from inside the same panels.
Correlate one request across services with traceparent. Waterfalls expose latency ownership; sample 1–10% head/tail.
JSON lines with level, service, and fields. Filter by level and search by field; wire ERROR streams into alert paths.
expr boolean + for duration → labels → receivers. Put threshold with slack; PENDING vs FIRING is hysteresis.
SLI = good/total. Error budget = 100% − target. Multi-window burn alerts page before the budget is gone.