Cloud & DevOps Essentials
Service giants now screen for Docker, Kubernetes, cloud basics and CI/CD in every technical round: five core topics, three hands-on drills, 30 MCQs and the 20 interview Q&As that repeat.
Virtualization vs Containers
What a container actually is: namespaced processes on a shared kernel — and why that changed deployment.
| Property | Virtual Machine | Docker Container |
|---|---|---|
| Kernel | Own guest OS kernel per VM | Shares the host kernel |
| Boot time | 30s–2min (full OS boot) | Milliseconds (just a process start) |
| Size | GBs (OS image + app) | MBs (app + slim base layer) |
| Isolation | Strong — hypervisor boundary | Process-level — namespaces + cgroups |
| Density per host | 10–30 VMs typical | 100s of containers typical |
| Use case | Strong tenancy, legacy OS | Microservices, CI/CD, scaling |
Docker architecture: client → daemon → registry
The `docker` CLI is a client that talks REST to dockerd (the daemon). The daemon builds images from Dockerfiles, runs containers, and pulls/pushes layers from registries (Docker Hub, ECR, GAR). BuildKit (default since Docker 23) builds layers in parallel and skips unchanged stages.
docker build -t app:v1 . # daemon builds layers, caches each instruction
docker run -d -p 8080:80 app:v1 # -d detached, -p host:container port map
docker push registry.example.com/app:v1Image vs container — the exam trap
An image is an immutable, layered file system snapshot (each Dockerfile instruction creates a layer, cached and shared). A container is a running instance of an image plus a thin writable layer (copy-on-write). Deleting the container never changes the image; `docker commit` bakes a container's state into a new image but is an anti-pattern — images should come from Dockerfiles.
ENTRYPOINT vs CMD
ENTRYPOINT is the fixed executable; CMD is the default argument list (or full command when no ENTRYPOINT). Both together: the final command is `ENTRYPOINT + CMD`, and `docker run image <args>` replaces only the CMD part. `docker run --entrypoint sh` overrides ENTRYPOINT for debugging.
# final argv = ["python", "server.py", "--port", "8080"]
ENTRYPOINT ["python", "server.py"]
CMD ["--port", "8080"]Slimming images: multi-stage builds & .dockerignore
Multi-stage builds compile in a fat toolchain image, then copy only the artifact into a tiny runtime image — compilers, node_modules build deps and caches never ship. `.dockerignore` keeps `.git`, `node_modules`, build output and secrets out of the build context (smaller context, faster builds, no credential leaks).
# ---- build stage ----
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# ---- runtime stage ----
FROM node:20-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY package*.json ./
RUN npm ci --omit=dev
CMD ["node", "dist/server.js"]Container Orchestration: Kubernetes
Control plane vs worker nodes, and the Pod → ReplicaSet → Deployment → Service → Ingress chain.
Control Plane Worker Node xN +---------------+ schedule +------------------------+ | API Server | --------------> | kubelet (pod agent) | | Scheduler | | kube-proxy (rules) | | etcd (state) | | Container runtime | | Controller Mgr| | + Pod [app, sidecar] | +---------------+ +------------------------+
| Object | Job it does | Exam one-liner |
|---|---|---|
| Pod | Smallest schedulable unit; 1+ co-located containers sharing net/volumes | Pods are cattle — never create them directly |
| ReplicaSet | Keeps N identical pods alive | Created by Deployments, not humans |
| Deployment | Rolling updates + rollbacks via ReplicaSet history | Declarative 'run 3 replicas of image X' |
| Service (ClusterIP) | Stable virtual IP + DNS inside the cluster | Pods restart; the service name doesn't |
| NodePort / LoadBalancer | Expose on node port / provision cloud LB | LB is the cloud-native option |
| Ingress | L7 HTTP routing: host/path → services, TLS termination | Needs an Ingress controller installed |
| ConfigMap / Secret | Inject config as env or files | Secrets are base64, not encrypted — enable encryption at rest |
What actually happens on `kubectl apply -f deploy.yaml`
kubectl validates and POSTs the manifest to the API server, which authenticates/authorizes, writes the desired state into etcd, and returns. Controllers (not kubectl) converge reality: the Deployment controller creates a ReplicaSet, which creates pods; the scheduler binds pending pods to nodes; the kubelet on the node pulls images, starts containers, and reports status back through the API server.
Service types and DNS
Every Service gets a DNS name `<svc>.<namespace>.svc.cluster.local`; pods in the same namespace can use just `<svc>`. Services select pods by label selectors — not by IP. ClusterIP = internal VIP; NodePort = port 30000–32767 on every node; LoadBalancer = cloud LB fronting the NodePorts; ExternalName = CNAME to an external endpoint.
Probes, requests and limits
liveness probe failing → kubelet restarts the container; readiness probe failing → pod is removed from Service endpoints (not restarted); startup probe gates both for slow-booting apps. `requests` are what the scheduler reserves (bin-packing), `limits` are the ceiling — exceeding a CPU limit throttles the process, exceeding a memory limit OOM-kills the container (a top cause of CrashLoopBackOff).
resources:
requests: { cpu: "100m", memory: "128Mi" }
limits: { cpu: "500m", memory: "256Mi" }
readinessProbe:
httpGet: { path: /healthz, port: 8080 }
initialDelaySeconds: 5Cloud Fundamentals: AWS / Azure / GCP parity
The four pillars — compute, storage, networking, identity — mapped across the big three clouds.
| Concept | AWS | Azure | GCP |
|---|---|---|---|
| VM compute | EC2 | Virtual Machines | Compute Engine |
| Serverless function | Lambda | Azure Functions | Cloud Functions |
| Object storage | S3 (Standard / IA / Glacier) | Blob Storage (Hot/Cool/Archive) | Cloud Storage (Standard/Nearline/Coldline) |
| Block storage | EBS | Managed Disks | Persistent Disk |
| Managed containers | ECS / EKS | AKS / Container Apps | GKE / Cloud Run |
| Managed DB | RDS | Azure SQL | Cloud SQL |
| IAM | IAM users/roles/policies | Entra ID + RBAC | Cloud IAM |
VPC and networking basics
A VPC is your private network in a region, split into subnets across availability zones. Public subnets route through an Internet Gateway; private subnets reach the internet via a NAT Gateway (outbound only) — databases and internal tiers live in private subnets. Security Groups are stateful instance firewalls (allow rules only, return traffic auto-allowed); NACLs are stateless subnet firewalls evaluated in rule order for both inbound and outbound.
IAM: users, roles, and least privilege
Users are long-lived identities (people, keys); Roles are assumable identities with temporary credentials — the correct way to give a Lambda function, EC2 instance or CI job permissions (instance profile / execution role / workload identity). Policies are JSON allow/deny statements; an explicit Deny always wins. Least privilege = grant only the specific actions on specific resources, never `Action: "*"`.
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::reports-bucket/public/*"
}S3 storage classes and consistency
Standard (frequent access), Standard-IA / Intelligent-Tiering (infrequent, pay retrieval), Glacier Instant/Flexible/Deep Archive (backup, minutes-to-hours retrieval). Lifecycle policies move objects automatically. Writes to a new object are immediately readable; for overwrites all S3 responses now return strong read-after-write consistency.
Lambda mental model
A Lambda is a short-lived (≤15 min) function: pay per request + GB-second, scales to zero, cold start on new execution environment. Keep packages small, initialize clients outside the handler (they're reused across warm invocations), and remember state must live in S3/DynamoDB — the filesystem is ephemeral `/tmp`.
CI/CD Pipelines
Build → test → deploy as code: GitHub Actions syntax, artifacts, secrets, and deployment strategies.
push → [build] → [test] → [scan] → [build image] → push registry
↓ environments
dev (auto) → staging (auto) → prod (approval gate)GitHub Actions syntax you must read fluently
A workflow file lives in `.github/workflows/`. `on` triggers it (push/PR tags, paths, cron), jobs run in parallel by default on runners, `needs` makes dependencies, steps are shell or reusable actions. `actions/cache` restores dependency caches; matrix builds fan out across versions.
name: ci
on: { push: { branches: [main] }, pull_request: {} }
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20, cache: npm }
- run: npm ci
- run: npm test -- --coverage
- run: npm run buildSecrets, environments and gates
Secrets are injected as masked environment variables — never echoed into logs or baked into images. Environments (dev/staging/prod) attach protection rules: prod deploys require manual approval and can be restricted to protected branches. The pipeline is the only road to production; nobody `kubectl apply`s from a laptop.
Blue-green vs canary vs rolling
Blue-green: two identical stacks, LB flips traffic instantly, instant rollback by flipping back — costs double capacity. Canary: route 5% → 25% → 100% to the new version while watching error rate/latency, rollback by shifting traffic back. Rolling (Kubernetes default): replace pods a batch at a time with maxSurge/maxUnavailable; slowest and least dramatic, cheapest. In interviews, pick canary for high-traffic services and explain the metric-based rollback.
Artifacts and traceability
Every build produces an immutable artifact (jar, docker image tagged with the git SHA — never `latest`) promoted through environments unchanged: what was tested in staging is exactly what ships. Image scanning (Trivy/Grype) and SAST/DAST stages gate merges.
Observability & Reliability (SRE)
Metrics vs logs vs traces, Prometheus/Grafana/ELK, and SLA/SLO/SLI with error budgets.
| Signal | Answers | Tooling |
|---|---|---|
| Metrics | Is the system healthy right now? (numbers over time) | Prometheus + Grafana dashboards |
| Logs | Exactly what happened in that request? (event records) | ELK / Loki / CloudWatch Logs |
| Traces | Where did the latency go across services? | OpenTelemetry + Jaeger / Tempo |
Prometheus & Grafana in one paragraph
Prometheus scrapes HTTP `/metrics` endpoints every N seconds and stores time series; PromQL queries them (`sum(rate(http_errors_total[5m])) / sum(rate(http_requests_total[5m]))`). Alertmanager routes firing alerts to Slack/PagerDuty with dedup and silences. Grafana is the dashboard layer on top. Instrument the four golden signals: latency, traffic, errors, saturation.
SLA, SLO, SLI, error budget
SLI = the measured indicator (e.g. % of requests < 300ms). SLO = the internal target you commit to (99.9%). SLA = the contractual promise with penalties — always looser than the SLO. Error budget = 100% − SLO: at 99.9% you may fail 43 minutes/month. Budget remaining → ship features; budget burned → freeze releases and fix reliability. Interviewers love the phrase 'error budgets turn reliability into a business decision.'
Alerting discipline
Page only on symptoms the user feels (error rate over SLO, latency over SLO), not on causes (CPU 80%). Every alert must be actionable; two levels: page (wake someone) and ticket (fix this week). Anti-pattern: alerting on every restart — after alert fatigue, teams ignore the page that mattered.