Cheat sheet · Docker and Kubernetes From Zero

Docker & Kubernetes cheat sheet

Docker and Kubernetes from the process in a box up to probes, rollouts and debugging, plus the answers interviewers ask for. A container is a process with limits, not a small VM.

Read the full series →

blogs · jp-blogs.vercel.app/cheatsheets/series/docker-kubernetes

What a container isLesson 0 →

  • A container is a normal process. Namespaces limit what it sees, cgroups limit what it can use.
  • It shares the host kernel (same uname -r), so it starts fast but is less isolated than a VM.
  • An image is read-only layers plus config. A container adds a thin writable layer and a process.
  • A tag can move, a digest (image@sha256:...) cannot. Avoid latest.
  • free inside a container shows host memory. The cgroup files show the real limit.
docker run -d -p 8088:8080 IMG
Start in the background, publish a port
docker ps -a
List containers, including stopped ones
docker logs NAME
What the process wrote to stdout and stderr
docker exec -it NAME sh
Start a second process in the same namespaces
docker stop NAME
SIGTERM, then SIGKILL after 10 seconds
docker rm NAME / docker rmi IMG
Delete a container / an image

Dockerfile instructionsLesson 1 →

InstructionWhat it does
FROMBase image. Pin a specific tag.
WORKDIRWorking folder (use it, not RUN cd)
COPY / ADDCopy files in. Prefer COPY; ADD also fetches URLs.
RUNRuns at build time and makes a layer
ARG / ENVBuild-time only / saved in the image
EXPOSEDocumentation only, publishes nothing
USERRun as non-root (node is UID 1000)
CMD / ENTRYPOINTDefault args / the fixed program

Watch out: ARG, ENV and copied-then-deleted files stay readable in docker history. Use RUN --mount=type=secret for tokens.

Fast, small, safe imagesLesson 1 →

FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:22-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
USER node
CMD ["node", "dist/server.js"]

Deps before source keeps the cache. Multi-stage gave 243 MB vs 1.69 GB.

  • Cache order: least-changing first. Rebuild took 1.6 s instead of 7.1 s.
  • Layers only add. Delete files in the same RUN that made them.
  • Exec form CMD ["node",...] lets SIGTERM reach the app. Shell form wraps it in sh -c.
  • .dockerignore: node_modules, .git, .env, logs. Lint with hadolint.

Volumes, networks, portsLesson 2 →

StorageUse for
Named volumeData that must outlive the container (databases)
Bind mountHost folder, good for development; add :ro
tmpfsMemory-only scratch space
  • Use a user-defined network: containers reach each other by name. The default bridge has no name lookup.
  • -p 8080:3000 binds all interfaces. Use -p 127.0.0.1:8080:3000 for private services.
  • A mounted folder must be writable by the container user (chown it in the image).

Run containers safelyLesson 2 →

docker run -d --name hard \
  --read-only --tmpfs /tmp \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  --memory 128m --pids-limit 100 \
  --user 1000:1000 IMG

Verified: the app still served traffic with all of this on.

Watch out: Never mount /var/run/docker.sock or use --privileged. The socket is root on the host. -e values show in docker inspect.

Docker ComposeLesson 3 →

docker compose up -d --build
Start the stack, rebuild images first
docker compose up -d --wait
Return when services are running or healthy
docker compose logs -f api
Follow one service
docker compose run --rm api CMD
One-off container (migrations)
docker compose down
Remove containers and networks, keep volumes
docker compose down -v
Also delete volumes. Data is gone.
docker compose config
Show the merged file, check syntax
  • Service names are DNS names on the project network.
  • Short depends_on only orders start. Use a healthcheck plus condition: service_healthy, and still retry in the app.
  • compose.override.yaml for development, profiles for optional services. Quote port strings.

Kubernetes architectureLesson 4 →

PartJob
API serverThe only door. Every part talks through it.
etcdStores all cluster state
SchedulerPicks a node for each new Pod
Controller managerRuns the reconcile loops
kubelet / kube-proxyOn each node: runs Pods / routes Service traffic
  • Reconcile loop: make status (current) equal spec (desired), forever.
  • A naked Pod is not replaced. Deployment owns a ReplicaSet owns Pods.
  • The Deployment selector must match template labels and is immutable.

Rollouts and declarative workLesson 4 →

kubectl apply -f FILE
Create or update from a file
kubectl diff -f FILE
Preview the change
kubectl apply --dry-run=server -f FILE
Validate on the server
kubectl set image deploy/N C=IMG:1.1
Start a rolling update
kubectl rollout status|history|undo
Watch / list / go back (deploy/NAME)
kubectl rollout restart deploy/N
Replace all Pods, rolling

Tip: Defaults are maxSurge: 25% and maxUnavailable: 25%. rollout undo makes a new revision. Check your context before you apply.

Services and IngressLesson 5 →

TypeReachable from
ClusterIP (default)Inside the cluster only
NodePortAny node IP, port 30000-32767
LoadBalancerCloud load balancer address
ExternalNameA DNS alias to an outside name
Headless (clusterIP: None)DNS returns the pod IPs
Port fieldMeaning
containerPortWhat the app listens on (documentation)
targetPortPod port the Service sends to (defaults to port)
portPort clients use on the Service
nodePortPort opened on every node
  • DNS: svc, svc.ns, svc.ns.svc.cluster.local. Only ready pods are in the EndpointSlice.
  • Ingress is rules only and needs a controller. pathType (Exact, Prefix) is required. Gateway API is the future.
  • NetworkPolicy needs a CNI that enforces it. By default all pods can talk.

Config, Secrets, storageLesson 6 →

  • ConfigMap and Secret values are strings. Quote numbers and booleans.
  • Env vars are fixed at start. Mounted files update later (not with subPath). Use rollout restart.
  • PVC asks, PV is the disk, StorageClass makes it on demand. An unbound PVC leaves the Pod Pending.
  • StatefulSet: stable names, DNS and a disk per pod. No replication for you.
Access modeMeaning
ReadWriteOnceOne node at a time
ReadWriteOncePodExactly one pod
ReadOnlyManyMany nodes, read-only
ReadWriteManyMany nodes, needs NFS or similar

Watch out: base64 is not encryption. Secrets sit plain in etcd by default. kubectl apply can copy one into an annotation. Use RBAC, encryption at rest, kubeconform -strict.

Probes, resources, scalingLesson 7 →

ProbeFailure means
readinessProbeStop sending traffic
livenessProbeRestart (never check the database)
startupProbeSlow start; holds off the other two
FieldDefault
periodSeconds10
timeoutSeconds1
failureThreshold3
initialDelaySeconds0
QoS classRule
GuaranteedRequests equal limits for CPU and memory
BurstableSome requests or limits
BestEffortNone. Evicted first.
desired = ceil(current
  x metric / target)
4 pods, 90% vs 70%: ceil(5.14) = 6

Needs CPU requests and metrics-server. Tolerance 10%.

Zero downtime and disruptionLesson 7 →

  1. Readiness probe on every pod, so new pods only get traffic when ready.
  2. maxUnavailable: 0 and maxSurge: 1 (or more).
  3. Handle SIGTERM and add a preStop sleep. Grace period is 30 s.
  4. At least 2 replicas and a PodDisruptionBudget.
  • Requests schedule. Limits enforce: CPU throttles, memory OOM-kills (137).
  • A stuck rollout shows ProgressDeadlineExceeded. It does not roll back by itself.
  • A PDB covers voluntary disruption only. Too strict, it blocks node drains.

DebuggingLesson 8 →

Exit codeMeaning
125 / 126 / 127Docker failed / not runnable / not found
137SIGKILL (128+9): OOM, docker kill, stop timeout
143SIGTERM (128+15)
StatusLook at
Pendingdescribe events: FailedScheduling
ImagePullBackOffdescribe: name, tag, credentials
CrashLoopBackOfflogs --previous, exit code
Running but 0/1Readiness probe; empty endpoints
kubectl describe pod NAME
Events at the bottom
kubectl logs NAME --previous
Output of the crashed container
kubectl debug -it POD --image=busybox
Ephemeral container, no shell needed
kubectl get events --sort-by=...
Recent events (sort by .lastTimestamp)

Interview one-linersLesson 9 →

QuestionShort answer
Container vs VM?A process on the shared kernel, not a guest OS.
CMD vs ENTRYPOINT?CMD is default args, ENTRYPOINT is the program.
ARG vs ENV?Build-time vs saved in the image. Neither is secret.
Does depends_on wait?No. Only with service_healthy.
Is Secret encrypted?No, only base64, until you enable encryption.
ConfigMap changed?Env vars stay old. Restart the pods.
Namespace a boundary?Naming scope, not a security boundary.
Pending pod?describe: resources, selector, taint, PVC.
Unready, Service errors?Check endpoints: selector typo or unready pods.

A cheat sheet is a reminder, not a teacher. Each card links to the lesson that explains it step by step.