DevOps and cloud interview questions
Operations questions for full-stack and platform roles: containers versus VMs, Dockerfiles, Kubernetes Deployments, Services, probes and resources, CI/CD and release strategies, Terraform state and drift, observability and SLOs, DNS and TLS, autoscaling, incidents, and cost.
Answer out loud or on paper before revealing. If your answer misses a key point, revisit the linked guide or explainer.
Nothing is due right now. Every question in this set is scheduled for a later review.
What is the difference between a container and a virtual machine?
Reveal model answer
A VM virtualises hardware: a hypervisor runs complete guest operating systems, each with its own kernel, so VMs are heavier and slower to boot but strongly isolated. A container is an isolated process on the host's kernel, using Linux namespaces for isolation and cgroups for resource limits, packaged with its filesystem from an image, so it starts in milliseconds to seconds and packs densely. Because containers share the kernel, isolation is weaker: a kernel exploit or a privileged container can reach the host, which is why multi-tenant platforms add sandboxes such as gVisor or micro-VMs like Firecracker. In practice they combine: containers usually run inside cloud VMs.
WHAT A STRONG ANSWER COVERS
- Own kernel per VM versus shared host kernel for containers.
- Namespaces for isolation and cgroups for resource limits.
- Trade-off: density and startup speed versus isolation strength.
- Containers typically run on VMs in the cloud.
RED FLAGS
- 'A container is a lightweight VM.'
- Claiming containers are as isolated as VMs.
LIKELY FOLLOW-UPS
- Why can't you run a Windows container on a Linux kernel natively?
- What does `--privileged` give a container?
How did your answer compare?
SOURCES
Review this Dockerfile for a Node app: `FROM node:latest`, `COPY . .`, `RUN npm install`, `ARG NPM_TOKEN`, `CMD npm start`.
Reveal model answer
`node:latest` is unpinned and huge: pin a slim or distroless tag, ideally by digest, and let a bot such as Dependabot bump it. `COPY . .` before installing busts the dependency layer cache on every source change and can copy `.env` and `node_modules` without a `.dockerignore`; copy `package.json` and the lockfile first, run `npm ci`, then copy the source. Use a multi-stage build so compilers, dev dependencies, and build output stay out of the runtime image, and switch to a non-root `USER`. The `ARG NPM_TOKEN` persists in image metadata and history; use a build secret (`RUN --mount=type=secret,id=npmrc`) instead. Finally, use exec form `CMD ["node", "server.js"]` so the app is PID 1 and receives SIGTERM directly rather than through a shell or npm wrapper that may not forward it; as PID 1, Node ignores SIGTERM unless the app registers a handler, so handle it for graceful shutdown or run with an init such as `docker run --init` or tini.
WHAT A STRONG ANSWER COVERS
- Pin base images (tag or digest) and keep them small.
- Order layers for caching: manifests and install before source.
- `.dockerignore` and multi-stage builds.
- Non-root user.
- Build secrets instead of ARG or ENV.
- Exec-form CMD and signal handling.
RED FLAGS
- Suggesting `--no-cache` as the fix for slow builds.
- Deleting the secret in a later layer and assuming it is gone.
LIKELY FOLLOW-UPS
- How would you make this image reproducible?
- What happens to in-flight requests when Kubernetes sends SIGTERM?
How did your answer compare?
SOURCES
In Kubernetes, what do a Deployment and a Service do, and how does a rolling update work?
Reveal model answer
A Deployment declares the desired Pod template and replica count and manages ReplicaSets to reach it; a Service gives a stable virtual IP and DNS name that load-balances to whichever ready Pods match its label selector, so clients never track Pod IPs. On a template change the default RollingUpdate strategy creates a new ReplicaSet and shifts Pods over, bounded by `maxSurge` and `maxUnavailable` (both 25% by default), while `Recreate` kills everything first and causes downtime. Each template change is a revision you can inspect with `kubectl rollout history` and revert with `kubectl rollout undo`. A rollout only stays safe if readiness probes are accurate and the app shuts down gracefully, otherwise traffic hits Pods that are not ready or are mid-termination.
WHAT A STRONG ANSWER COVERS
- Deployment manages ReplicaSets; Service selects Pods by label.
- Services route only to ready endpoints.
- RollingUpdate with maxSurge and maxUnavailable; Recreate as the alternative.
- Revisions and rollback.
- Readiness and graceful shutdown make rollouts zero-downtime.
RED FLAGS
- Thinking a Service is a Pod or a container.
- Assuming a rolling update is zero-downtime without probes or SIGTERM handling.
LIKELY FOLLOW-UPS
- When would you use a StatefulSet instead?
- What is the difference between ClusterIP, NodePort, and LoadBalancer Services?
How did your answer compare?
SOURCES
Your liveness probe calls `/health`, which checks the database. During a database blip every Pod restarts. Why, and what should the probes look like?
Reveal model answer
A liveness failure makes the kubelet restart the container, so tying liveness to a shared dependency turns one database hiccup into a fleet-wide restart storm that adds cold starts and reconnection load exactly when the system is weakest. Liveness should answer only 'is this process wedged in a way a restart fixes?', for example an in-process check with generous thresholds. Readiness is the one that may consider dependencies: failing it removes the Pod from Service endpoints without restarting it. For slow-starting apps add a startup probe, which suspends liveness and readiness until it succeeds, sized for worst-case boot time.
WHAT A STRONG ANSWER COVERS
- Liveness restarts; readiness removes from load balancing; startup gates the others.
- Liveness must not depend on external services.
- Misconfigured liveness probes cause cascading failures under load.
- Startup probes for slow boot instead of huge initial delays.
RED FLAGS
- Using the same deep health check for liveness and readiness.
- Very tight liveness timeouts on a service that pauses for GC under load.
LIKELY FOLLOW-UPS
- Should readiness fail if the database is down, given every Pod would go unready at once?
How did your answer compare?
SOURCES
Explain resource requests and limits. A Pod keeps showing `OOMKilled` with exit code 137; what is happening?
Reveal model answer
Requests are what the scheduler reserves and places Pods by; limits are hard ceilings enforced at runtime. Exceeding a CPU limit throttles the container, while exceeding a memory limit gets it killed by the kernel OOM killer, reported as `OOMKilled` with exit code 137 (128 + SIGKILL), and the kubelet restarts it into CrashLoopBackOff if it repeats. Diagnose by comparing actual memory usage over time with the limit: a steady climb suggests a leak, while a plateau just above the limit means the limit is too low or the runtime is not aware of it (for example a Node heap or JVM sized larger than the container). Set memory requests close to real usage, keep memory limit equal or close to the request, and be wary of tight CPU limits on latency-sensitive services, since throttling shows up as tail latency rather than an obvious error.
WHAT A STRONG ANSWER COVERS
- Requests drive scheduling; limits are enforced.
- CPU over limit throttles; memory over limit is OOM-killed.
- Exit code 137 means SIGKILL.
- Leak versus undersized limit versus runtime heap misconfiguration.
- Pods without requests are first to be evicted under node pressure (QoS classes).
RED FLAGS
- Raising the limit repeatedly without looking at the memory curve.
- Thinking CPU limits cause OOM kills.
LIKELY FOLLOW-UPS
- What are the Guaranteed, Burstable, and BestEffort QoS classes?
- How would you size a Node.js heap inside a 512 MiB container?
How did your answer compare?
SOURCES
Design a CI/CD pipeline for a web service. What stages would it have and what makes it trustworthy?
Reveal model answer
CI on every push: install from the lockfile, lint, type-check, unit tests, and a build, kept to roughly ten minutes so developers integrate to main daily and fix a red build immediately. Build the artifact or image once, tag it with the commit SHA, scan it, and promote that same artifact through staging and production rather than rebuilding per environment. CD stages: deploy to staging, run integration and smoke tests, then a progressive production rollout gated on health metrics with automatic rollback; database migrations are expand-and-contract so old and new versions run side by side. Security of the pipeline itself matters: least-privilege, short-lived credentials via OIDC instead of stored cloud keys, protected branches and environments with required reviews, and no secrets exposed to fork pull requests.
WHAT A STRONG ANSWER COVERS
- Fast feedback and trunk-based integration.
- Build once, promote the same immutable artifact.
- Progressive delivery with automated health gates and rollback.
- Backward-compatible migrations decoupled from deploys.
- Pipeline security: OIDC, scoped permissions, protected environments.
RED FLAGS
- Rebuilding the image separately for each environment.
- Manual SSH deploys as a pipeline step.
- Long-lived admin cloud keys stored as CI secrets.
LIKELY FOLLOW-UPS
- How would you handle a migration that renames a column?
- How do you keep a flaky test suite from eroding trust in CI?
How did your answer compare?
SOURCES
Blue/green versus canary deployments: how do they differ and when would you pick each?
Reveal model answer
Blue/green runs two full production environments: you deploy to the idle one, test it, then switch the router so all traffic moves at once, and rollback is flipping back while the old environment is still intact. Canary sends a small share of real traffic to the new version, compares its error rate and latency with the baseline, and increases the percentage in steps until it serves everyone. Blue/green gives instant cutover and rollback but double capacity and an all-at-once blast radius; canary limits the blast radius and catches issues that only real traffic triggers, but needs good per-version metrics and traffic splitting. Both require backward-compatible database changes, since two versions share the data during the transition.
WHAT A STRONG ANSWER COVERS
- All-at-once switch versus gradual percentage rollout.
- Rollback mechanics for each.
- Cost and blast-radius trade-offs.
- Canary needs automated metric comparison to be meaningful.
- Schema changes must work with both versions.
RED FLAGS
- Calling a rolling update a canary without any metric-based gate.
- Ignoring the database during the transition.
LIKELY FOLLOW-UPS
- How are feature flags different from canary releases?
- How would you canary a change to a background worker that has no HTTP traffic?
How did your answer compare?
SOURCES
What is Terraform state, how should a team store it, and how do you deal with drift?
Reveal model answer
State is Terraform's JSON record mapping resources in the configuration to real objects, plus metadata it uses to plan changes; without it Terraform cannot tell what it manages. Teams keep it in a remote backend with locking (HCP Terraform, or object storage with locking) and tight access control, never in git, because concurrent applies can corrupt it and it often contains secrets in plain text. Drift is when someone changes infrastructure outside Terraform: `terraform plan -refresh-only` shows it, then you either codify the change in configuration (importing resources that were created by hand) or run a normal apply to revert it. Prevent drift by restricting console write access, running plans on a schedule to detect it, and splitting state by environment and blast radius.
WHAT A STRONG ANSWER COVERS
- State maps configuration to real resource IDs.
- Remote backend, locking, and access control.
- State can contain secrets.
- Detect drift with refresh-only plans; reconcile by codifying or reverting.
- Split state to limit blast radius and lock contention.
RED FLAGS
- Committing `terraform.tfstate` to the repository.
- Hand-editing the state file.
- Fixing drift by deleting resources from state without understanding them.
LIKELY FOLLOW-UPS
- How would you rename a resource without destroying it?
- How do you bring an existing manually created bucket under Terraform?
How did your answer compare?
SOURCES
Explain logs, metrics, and traces, and how you would define SLOs and alert on them.
Reveal model answer
Metrics are cheap aggregated numbers for dashboards and alerting, logs are detailed event records for investigating a specific case, and traces follow one request across services with context propagated between them to show where time and errors occur; OpenTelemetry standardises collecting all three. An SLI is a measured ratio of good events, such as the share of requests served successfully under 300 ms; an SLO is the target for it over a window, say 99.9% over 30 days, and the remainder is the error budget that decides whether to ship faster or invest in reliability. Use percentiles rather than averages, since averages hide the slow tail. Alert on error budget burn rate with multiple windows, for example page when 2% of a 30-day budget burns in an hour (a 14.4x burn rate) confirmed by a short window, rather than on CPU or individual errors.
WHAT A STRONG ANSWER COVERS
- When to use each signal and how they link (trace IDs in logs).
- SLI as good events over valid events; SLO as the target; SLA as the contract.
- Error budgets drive release and reliability decisions.
- Percentiles over averages.
- Multiwindow burn-rate alerts on symptoms, not causes.
RED FLAGS
- Targeting 100% availability.
- Paging on CPU usage or every logged exception.
- Using average latency as the SLI.
LIKELY FOLLOW-UPS
- How do you keep high-cardinality labels from blowing up metric costs?
- What SLI would you pick for a batch job?
How did your answer compare?
SOURCES
You are migrating a domain to a new load balancer and its TLS certificate. What DNS and TLS details do you plan for?
Reveal model answer
Resolvers cache records for the TTL set by the zone, so lower the TTL well before the cutover (at least one old TTL ahead), switch the record, and keep the old target serving until the old TTL has expired everywhere. Use the right record type: a CNAME cannot sit at the zone apex, so providers offer ALIAS or flattening there. Issue the new certificate before the switch, covering every hostname (SANs), and serve the full chain. Automate issuance and renewal with ACME and monitor expiry, because maximum public certificate lifetimes are shrinking under CA/Browser Forum ballot SC-081v3: 200 days from 15 March 2026, 100 days from March 2027, and 47 days from March 2029, which makes manual renewal untenable.
WHAT A STRONG ANSWER COVERS
- TTL and caching drive cutover timing; lower it in advance.
- Keep the old target alive during propagation.
- CNAME at the apex limitation and ALIAS or flattening.
- Certificates cover all names and include the intermediate chain.
- Automated renewal and expiry monitoring, given shrinking lifetimes.
RED FLAGS
- 'DNS propagation takes 48 hours' with no understanding of TTLs.
- Renewing certificates from a calendar reminder.
- Shutting down the old endpoint the moment DNS is changed.
LIKELY FOLLOW-UPS
- What happens during a TLS handshake, and where does SNI fit?
- How would you alert before a certificate expires?
How did your answer compare?
SOURCES
How does the Kubernetes Horizontal Pod Autoscaler decide how many replicas to run, and what are its pitfalls?
Reveal model answer
Every sync period (15 seconds by default) the HPA computes `desiredReplicas = ceil(currentReplicas × currentMetric / targetMetric)` within the configured min and max, using resource metrics, per-Pod custom metrics, or external metrics such as queue depth. CPU utilisation targets are measured against the container's CPU request, so Pods without requests cannot be scaled on utilisation, and badly set requests skew everything. Scale-down is stabilised to avoid flapping (a 300-second window by default), and scaling is not instant: new Pods need scheduling, image pulls, and startup, and may need the cluster autoscaler to add nodes first. Pick a metric that tracks load (requests per second or queue lag for workers), keep a headroom margin, and remember that scaling out stateless Pods can just move the bottleneck to a database connection limit.
WHAT A STRONG ANSWER COVERS
- The ratio formula and min and max bounds.
- Utilisation is relative to requests.
- Stabilisation windows and scaling lag.
- Pod autoscaling versus node autoscaling.
- Downstream limits such as database connections.
RED FLAGS
- Autoscaling on CPU for an I/O-bound or queue-driven worker.
- Expecting autoscaling to absorb an instant tenfold spike.
LIKELY FOLLOW-UPS
- How would you autoscale a queue consumer down to zero?
- Why can the HPA and the VPA conflict on the same metric?
How did your answer compare?
SOURCES
You are on call and error rates spike right after a deploy. Walk me through the incident and what happens afterwards.
Reveal model answer
Mitigate first: acknowledge, declare an incident if it meets your criteria, and stop the bleeding, which after a deploy usually means rolling back or turning off the flag before root-causing, while preserving evidence such as logs and the bad version. For anything sizeable, split roles: an incident commander who coordinates and keeps a living incident document, an operations lead who is the only one changing systems, and a communications lead who posts regular updates to stakeholders and the status page. Once service is restored, write a blameless postmortem when it hits predefined triggers (user-visible impact, data loss, on-call intervention, long resolution, or detection by a human rather than monitoring): timeline, impact, contributing causes, what went well, and action items with owners. Focus on why the system allowed the failure, for example why the canary or tests did not catch it, not who pushed the button.
WHAT A STRONG ANSWER COVERS
- Mitigation before diagnosis; rollback is the default after a bad deploy.
- Clear roles: commander, operations, communications.
- Regular stakeholder communication.
- Blameless postmortem with owned, tracked action items.
- Predefined postmortem triggers.
RED FLAGS
- Debugging in production for an hour before considering rollback.
- Several people changing systems at once without coordination.
- A postmortem that concludes 'human error' and stops.
LIKELY FOLLOW-UPS
- What if the deploy included a database migration that cannot be rolled back?
- How do you make sure postmortem action items actually get done?
How did your answer compare?
SOURCES
The cloud bill doubled in a quarter. How do you find out why and bring it down without hurting reliability?
Reveal model answer
First make spend visible and attributable: enforce tagging or labels by team and service, break down the bill by service and usage type, and set budgets and anomaly alerts so the next surprise arrives in days, not at quarter end. Common culprits are overprovisioned instances and inflated Kubernetes requests, idle or forgotten resources (unattached volumes, old snapshots, dev environments running nights and weekends), data transfer such as cross-zone traffic and NAT gateway charges, and log or metric volume. Then act in order of effort: delete waste, right-size from measured utilisation, schedule non-production environments, use autoscaling and spot or preemptible capacity for interruptible work, and commit to savings plans or reserved capacity only for the stable baseline. Make cost a tracked metric owned by the teams who create it, in the spirit of the AWS Well-Architected cost pillar's 'expenditure and usage awareness' practice.
WHAT A STRONG ANSWER COVERS
- Attribution first: tags, per-service breakdowns, budgets, anomaly alerts.
- Knows the usual culprits, including data transfer and observability volume.
- Right-sizing from measured usage, including Kubernetes requests.
- Commitments only for the steady baseline; spot for interruptible work.
- Cost ownership by the teams that create it.
RED FLAGS
- Buying three-year reservations before right-sizing.
- Cutting redundancy blindly to save money.
- Ignoring egress and NAT costs.
LIKELY FOLLOW-UPS
- How would you show each team its own Kubernetes cost?
How did your answer compare?
SOURCES