000
Provisioning the stack…
CrackOps/ the stack

The world's most over-engineered way to learn what happens after git push.

*no containers were harmed

Isn't just
a container.

It's 146 MB of decisions — base image, layer order, user, entrypoint — and an interviewer will ask you to defend every one of them.*

*we checked

84 tools.
One container.

The real logos of the tools you'll be asked about — source control, CI, registries, IaC, Kubernetes, mesh, observability, security, cost.

Every tile here shows up in a real job description.
01 · Package

Five layers.
Zero guesswork.

Order them by how often they change, cache the slow ones, and never run as root. That's the Dockerfile question, answered.

FROM gcr.io/distroless/java21FROM52 MB · cached
COPY build/libs/deps/ /app/lib/COPY88 MB · cached
COPY build/libs/checkout.jar /app/COPY6 MB
USER 65532:65532USER0 B
ENTRYPOINT ["java","-jar","/app/checkout.jar"]ENTRYPOINT0 B
41sbuild · 287 of 312 tasks from cache
02 · Deliver

Every push.
Same road.

Checkout, build, test, scan, push, sync. CI proves it works; GitOps makes the cluster match the repo.

01 · CheckoutGitHub
02 · BuildGradle
03 · TestJenkins
04 · ScanTrivy · Snyk
05 · ImageDocker → Harbor
06 · SyncArgo CD
Lead time for changes · DORAtlead = tprod − tmerge
02b · Release — the full CI/CD path

From git commit
to the user's screen.

01 / 159f2c1e7 feat(payments): 3DS challenge · payments 2.8.1 → 2.9.0
Stage 1 · Laptop

A developer writes the change

  • Branch from main: feature/3ds-payments
  • Code + unit tests, run locally
  • pre-commit hooks: lint, format, secret scan
  • Small commits with clear messages

Interviewers ask“Trunk-based development or GitFlow — and why?”

zsh · ~/payments
02c · Live — a real rolling update

Deploying while
users keep clicking.

CONTROL PLANE · behind the scenesArgo CDgit → desired statekube-apiserverthe front dooretcdstores the specDeployment controllercreates ReplicaSetsSchedulerpicks a nodeEndpoints controllerwho gets trafficDATA PLANE · serving usersUsers~16 req/sCDNedge cacheLoad balancerL7 · TLSIngressNGINXServiceClusterIPnode-a · kubelet · containerdnode-b · kubelet · containerdnode-c · kubelet · containerdpayments-6c8d9-a2.8.1 · Running 1/1payments-6c8d9-b2.8.1 · Running 1/1payments-6c8d9-c2.8.1 · Running 1/1
Requests served00 from CDN cache
Failed (502)0zero downtime
Success rate100.00%SLO 99.9%
Traffic on 2.9.00%
$ kubectl get endpoints payments -w
10.0.1.14 · 2.8.1
10.0.2.14 · 2.8.1
10.0.3.14 · 2.8.1
$ kubectl get events -w
Waiting for a deploy… press “Deploy 2.9.0”.
03 · Run

Pods, probes
and 2 AM.

Your container is now one pod of many. Know how the control plane schedules it — then prove you can debug it.

checkout-6f4byour container, now a pod
control planeapi-server · etcd · scheduler
node-akubelet · containerd
node-bkubelet · containerd
node-ckubelet · containerd
payments-7d9fCrashLoopBackOff · 6 restarts
payments-8c2eRunning · limits 1Gi
kubectl · payments
$ kubectl get pods -n payments
payments-7d9f  0/1  CrashLoopBackOff  6
$ kubectl describe pod payments-7d9f | grep -A2 Last
Last State: Terminated · Reason: OOMKilled · Exit 137
$ kubectl set resources deploy/payments --limits=memory=1Gi
deployment.apps/payments resource requirements updated
03b · Declare

Six files.
One service.

01 / 06 · Deployment

Requests decide where a pod is scheduled; limits decide when it's killed. Probes decide when it gets traffic.

02 / 06 · Service

A stable name and virtual IP in front of pods that come and go. Only ready pods become endpoints.

03 / 06 · Ingress

One door for HTTP: host and path routing to Services, TLS certificates from cert-manager.

04 / 06 · ConfigMap

Configuration outside the image. Changing it does not restart pods — roll the Deployment to pick it up.

05 / 06 · Secret

base64 is encoding, not encryption. Encrypt etcd at rest, lock down RBAC, or sync from Vault.

06 / 06 · HorizontalPodAutoscaler

Scales replicas between min and max on CPU, memory or custom metrics. Needs requests to be set.

03c · Debug

What breaks
at 2 AM.

CrashLoopBackOffrestarting · exit 1
ImagePullBackOfftag 2.9.0 not found
OOMKilledexit 137 · limit 512Mi
PendingInsufficient memory
Evictednode DiskPressure
CreateContainerConfigErrorconfigmap not found
Readiness probe failedHTTP 503 · no traffic
node-c NotReadykubelet stopped posting status
kubectl get events -A -w
TYPEREASONOBJECT · MESSAGE
WarningBackOffpod/payments-7d9f Back-off restarting failed container api
WarningFailedpod/checkout-5c1a Failed to pull image "registry.acme.io/checkout:2.9.0": not found
WarningOOMKillingnode/node-b Memory cgroup out of memory: Killed process 4113 (java)
WarningFailedSchedulingpod/search-9x2k 0/3 nodes are available: 3 Insufficient memory
WarningEvictedpod/cart-77fd The node had condition: [DiskPressure]
WarningFailedpod/payments-v2-0a Error: configmap "payments-config-v2" not found
WarningUnhealthypod/auth-41ae Readiness probe failed: HTTP probe failed with statuscode: 503
WarningNodeNotReadynode/node-c Node node-c status is now: NodeNotReady
pod logs · payments-7d9f
Handles load with ease

Traffic triples at 9 AM. The HorizontalPodAutoscaler reads CPU every 15 seconds and adds pods before users notice. Your cluster stays perfectly calm.*

Capacity
under pressure
CPU 100%50%0%
HorizontalPodAutoscaler · the real formuladesired = ceil(current × util ⁄ target)
*a visualisation, not an SLA
payments · productionLast 15 minutesRefresh 5s● live
CPU usage by pod—
Memory working set vs limit—
Requests / s—
5xx error rate—
p99 latency · SLO 600 ms—
Container restarts—
Network RX / TX—
Node CPU heatmap—
Error budget · 30 days—
07 · Observe

Every graph is a question. Memory climbs to the limit — then the kernel answers with an OOM kill.

04 · Provision

Declared,
not clicked.

Every node, subnet and role above is a line of Terraform. Plan it, review it in a pull request, apply it — and keep the state somewhere safe.

module "eks" {
  source          = "terraform-aws-modules/eks/aws"
  cluster_version = "1.33"
  eks_managed_node_groups = {
    default = { min_size = 3, max_size = 9 }
  }
}
terraform plan · 47 to add, 0 to change, 0 to destroyΔ = desired − actual
Zoom in10,000×
One request7 spans · 1,204 log lines
Metrics · Logs · Traces
observability

If it isn't measured, it didn't happen.
If it isn't alerted on, it happened at 2 AM.

100% instrumented
observability

Golden signals on every service. Burn-rate alerts instead of noise. One trace from the load balancer to the database.

p99 latency406 msSLO 600 ms · 30-day
Error budget71% left99.9% availability · 21.6 min/month
Trace 4bf92f35 · 312 mspayments.authorize → SELECT orders
05 · Respond

2:13 AM.

Mitigate first. Communicate always. Root-cause later — and write it down without blame.

PagerDutyCheckoutErrorBudgetBurn — 14× burn rate over 5m
OpsgeniePaged Priya (primary). Escalates to Sam in 10m.
#inc-2291Priya: ack'd, I'm IC. 502s from payments.
#inc-2291Sam: payments 2.8.0 went out at 02:09. Rolling back.
Rundeckhelm rollback payments 41 — succeeded
SquadcastResolved. 18 minutes, ~2.1% of checkouts affected.
Choose your own

DevOps

The original. Pipelines, containers, IaC and the cloud — the loop every team runs, explained until it feels obvious.

Start the DevOps track
  • CI/CD and GitOps
  • Docker, registries, Helm
  • Terraform across AWS · GCP · Azure
Our state-of-the-art open-weight interviewer

CrackOps-1

Abstract

We present CrackOps-1, an interview simulator for DevOps, SRE and platform engineers. It faithfully reproduces key interviewer behaviours — follow-up questions, “and what if that fails?”, and asking about etcd at the worst possible moment. Evaluated on a single laptop at 2 AM. Limitations include a heavy dependency on coffee and a real Kubernetes cluster.

Acknowledgements

Every on-call engineer who ever wrote a postmortem without blaming anyone.

Peer review

“It asked me about CrashLoopBackOff and then about my feelings. 10/10.”
— anonymous SRE, r/devops