Back to Interview Briefs
KubernetesIntermediate35 min

Kubernetes Architecture Deep Dive

Understand the control plane, worker nodes, etcd, kube-scheduler, and how pods are actually scheduled.

control planeetcdkube-schedulerkubeletpod scheduling

THE STORY

The pod that wouldn't die — and the one that wouldn't start

It's a Friday afternoon. Your team just deployed a new version of the payment service. Everything looks fine in staging. You push to production.

Within 3 minutes, Slack explodes. Payments are failing. You check the pods. Status: CrashLoopBackOff. You check the logs. The app starts, runs for 8 seconds, then dies. Starts again. Dies again. Kubernetes keeps restarting it — helpfully, automatically, endlessly — while real users can't pay.

You find the issue: a missing environment variable that only exists in production. The app crashes without it. But here's what nobody tells you in tutorials — Kubernetes didn't cause this problem. Kubernetes was doing exactly its job. It detected the crash, restarted the pod, detected the crash again. The desired state said 3 replicas running. Reality said 3 replicas crashing. Kubernetes kept trying to close that gap.

Now multiply this by a team of 8 engineers all staring at their screens on a Friday evening, half of them running kubectl delete pod hoping a fresh restart will fix it. It won't. Because the problem isn't the pod. The problem is the desired state doesn't match reality — and until you fix the root cause, Kubernetes will keep restarting that pod forever.

Understanding this one thing — that Kubernetes is a reconciliation loop, not a deployment tool — changes how you debug everything.

THE CONCEPT

What Kubernetes actually does — and everything you need to explain it in an interview

Kubernetes has one job: make reality match what you declared.

You write a YAML file that says 'I want 3 replicas of this app running, with 512MB RAM each, exposed on port 3000.' That is your desired state. Kubernetes reads it, stores it in etcd, and then spends every second of every day trying to make the cluster look like that declaration. This is called the reconciliation loop.

THE CONTROL PLANE — the brain of Kubernetes:

API Server: Every kubectl command, every Helm chart, every CI/CD pipeline talks to the API server. It is the single entry point for all cluster operations. It validates requests, authenticates them, and persists state to etcd.

etcd: A distributed key-value store that holds the entire cluster state. Every pod spec, every service definition, every config map lives in etcd. If etcd goes down, the cluster cannot make any scheduling decisions — existing pods keep running but nothing new can be created or modified. This is why etcd backup is non-negotiable in production.

Scheduler: When a new pod is created, it starts as Pending with no node assigned. The scheduler watches for unscheduled pods and assigns them to nodes based on: available resources (CPU, memory), node affinity rules, taints and tolerations, pod anti-affinity (don't put two replicas on the same node). The scheduler does not start the pod — it just picks the node.

Controller Manager: Runs dozens of controllers in a single process. The Deployment controller watches for Deployment objects and creates ReplicaSets. The ReplicaSet controller watches for ReplicaSets and creates Pods. The Node controller watches for node failures. Each controller runs its own reconciliation loop.

THE WORKER NODES — where your code actually runs:

kubelet: An agent running on every node. It watches the API server for pods assigned to its node, pulls the container image, starts the container via the container runtime (containerd or CRI-O), and reports back pod status. If a container crashes, kubelet reports it to the API server, which triggers the CrashLoopBackOff backoff logic.

kube-proxy: Manages iptables or IPVS rules on each node to implement Service networking. When you create a Service with ClusterIP, kube-proxy creates rules on every node so that traffic to the ClusterIP gets load-balanced to the correct pods.

Container Runtime: containerd or CRI-O. Actually pulls images and runs containers. Docker was removed as a runtime in Kubernetes 1.24.

WHAT ACTUALLY HAPPENS WHEN YOU RUN kubectl apply:

1. kubectl sends the YAML to the API server 2. API server validates and stores it in etcd 3. Deployment controller detects new desired state, creates a ReplicaSet 4. ReplicaSet controller creates 3 Pod objects (Pending state, no node assigned) 5. Scheduler assigns each pod to a node 6. kubelet on each node detects a pod assigned to it 7. kubelet pulls the container image 8. kubelet starts the container 9. Pod status changes to Running

kubectl returns after step 2. Steps 3-9 happen asynchronously. This is why kubectl apply returns instantly but your pod takes 30-60 seconds to be Running.

RESOURCE REQUESTS VS LIMITS — the source of most production incidents:

requests: memory: 256Mi cpu: 250m limits: memory: 512Mi cpu: 500m

Requests are what the scheduler uses. It finds a node where 256Mi is available and schedules the pod there. The pod might use more — requests are not a hard cap.

Limits are hard caps enforced by the kernel. If the container exceeds memory limit, the OOM killer terminates it immediately — no warning, no graceful shutdown. Exit code 137. If it exceeds CPU limit, it gets throttled — slowed down, not killed.

The production mistake everyone makes: setting memory limits too close to average usage. Your app uses 300MB normally but spikes to 700MB during report generation. With a 512Mi limit it gets OOMKilled every time someone runs a report. You see CrashLoopBackOff at 9AM every day. The logs look healthy because the OOM kill happens at the kernel level before the app can write anything.

Fix: set limits at 2-3x your average usage. Use kubectl top pod to measure actual usage before setting limits.

PROBES — the thing that separates zero-downtime deployments from outages:

Liveness Probe: Is this container still alive? If it fails, kubelet kills and restarts the container. Use for deadlock detection — your app is running but stuck in an infinite loop and not processing requests.

Readiness Probe: Is this container ready to receive traffic? If it fails, the pod is removed from the Service endpoints — traffic stops going to it but the container is not restarted. Use for startup time — your app takes 20 seconds to load config on startup. Without a readiness probe, Kubernetes sends traffic before it is ready and users get errors.

Startup Probe: Is the container still starting up? Disables liveness and readiness probes until startup succeeds. Use for slow-starting legacy apps.

The critical production insight: a failing readiness probe does NOT restart your pod. A failing liveness probe does. Mixing them up causes either unnecessary restarts or traffic being sent to unhealthy pods.

DEPLOYMENT STRATEGIES:

Rolling Update (default): Replaces pods one by one. Zero downtime if health checks are configured correctly. maxSurge controls how many extra pods can exist during rollout. maxUnavailable controls how many pods can be down during rollout.

Recreate: Kills all old pods then creates new ones. Causes downtime. Only use when you cannot run two versions simultaneously (database schema changes that are not backward compatible).

Blue/Green: Run two identical environments. Switch traffic at the load balancer level. Instant rollback. Expensive — doubles infrastructure cost.

Canary: Send a small percentage of traffic to the new version. Monitor error rates. Gradually increase traffic. Best for high-risk deployments.

PRESSURE TEST

The Kubernetes interview questions that separate candidates who've read docs from those who've run production

QUESTION 1

What happens when you run kubectl apply -f deployment.yaml?

WEAK (5/10)

'It deploys your application to the cluster.'

STRONG (9/10)

'kubectl apply sends the manifest to the API server which validates and stores it in etcd. The Deployment controller creates a ReplicaSet. The ReplicaSet controller creates Pod objects in Pending state. The scheduler assigns each pod to a node based on resource requests, taints, and affinity rules. The kubelet on each assigned node pulls the image and starts the container. The whole process is asynchronous — kubectl returns after etcd write but pods take 30-60 seconds to reach Running state.'

SENIOR INSIGHT

When you mention etcd and the asynchronous nature, interviewers at Flipkart and Razorpay level up their assessment of you immediately. Most candidates describe the user-visible behavior. Senior engineers describe the internal mechanism.


QUESTION 2

A pod is in CrashLoopBackOff. Walk me through your debugging.

WEAK (5/10)

'I would check kubectl logs to see what the error is.'

STRONG (9/10)

'First kubectl describe pod to check the exit code and last state. Exit code 1 is application error. Exit code 137 is OOMKilled — memory limit exceeded. Exit code 143 is SIGTERM — graceful shutdown signal. For exit 137 I immediately check kubectl top pod and compare to the memory limit. No point reading logs for an OOMKill because the kernel kills the process before it can write anything. For exit 1, I use kubectl logs --previous to see the last run output. I also check the Events section in describe — image pull failures, volume mount errors, and probe failures appear there.'

SENIOR INSIGHT

The exit code tells you which tool to reach for next. Exit 137 means you need kubectl top and resource limit review — not log analysis. This saves 30 minutes of confusion in a real incident.


QUESTION 3

What is the difference between a liveness probe and a readiness probe?

WEAK (5/10)

'Liveness checks if the app is alive. Readiness checks if it is ready to serve traffic.'

STRONG (9/10)

'A failing liveness probe causes kubelet to kill and restart the container. Use it to detect deadlocks — the app process is running but frozen. A failing readiness probe removes the pod from Service endpoints so no new traffic is routed to it, but the container is not restarted. Use it to handle startup time and temporary unavailability. The critical difference: liveness failure = restart. Readiness failure = traffic isolation without restart. Misconfiguring them causes either constant unnecessary restarts or traffic being sent to unhealthy pods.'

SENIOR INSIGHT

In production, readiness probes save you more often than liveness probes. A deployment with no readiness probe will send traffic to pods that are still initializing, causing a flood of errors during every deployment. I have seen this take down services during peak hours.


QUESTION 4

Your deployment has 3 replicas. One node dies. What happens?

WEAK (5/10)

'Kubernetes will restart the pods on another node.'

STRONG (9/10)

'The Node controller detects the node has not responded to heartbeats for the node-monitor-grace-period, which defaults to 40 seconds. It marks the node NotReady. After the pod-eviction-timeout, which defaults to 5 minutes, it marks all pods on that node as Terminating and creates replacement pods on healthy nodes. During those 5 minutes, if you had 3 replicas and 1 was on the dead node, your Service continues routing to the 2 healthy pods. The replacement pod is scheduled on a healthy node and starts up. Total time from node failure to replacement pod running is typically 5-7 minutes with default settings. You can reduce this with custom timeout values but it increases false positive evictions on slow nodes.'

SENIOR INSIGHT

The 5-minute default eviction timeout surprises most people. If you have a 3-replica deployment and a node dies taking 2 replicas with it, you are running on 1 replica for up to 5 minutes. This is why pod anti-affinity rules matter — spread replicas across nodes so a single node failure cannot take down most of your capacity.


QUESTION 5

What is etcd and why does it matter?

WEAK (5/10)

'etcd is a database where Kubernetes stores its data.'

STRONG (9/10)

'etcd is a distributed key-value store that holds the entire desired state of the cluster — every pod spec, service, config map, secret, and deployment. It uses the Raft consensus algorithm to maintain consistency across multiple etcd nodes. If etcd goes down, the control plane cannot make new scheduling decisions — existing pods keep running because kubelet does not depend on etcd directly, but no new pods can be created, no deployments can be rolled out, and no scaling can happen. This is why etcd backup and high availability is non-negotiable in production. We back up etcd every hour with etcdctl snapshot save and store snapshots in S3.'

SENIOR INSIGHT

'Existing pods keep running even if etcd is down' is the senior insight here. Most engineers assume the cluster falls apart when the control plane fails. In reality, your running workloads continue — you just lose the ability to make changes. This is an important distinction during incidents.

Follow-Up Probes

  • ·How does a Service route traffic to pods? What is kube-proxy doing?
  • ·What is the difference between a ClusterIP, NodePort, and LoadBalancer service?
  • ·What is a DaemonSet and when would you use it?
  • ·How do you roll back a bad deployment in Kubernetes?
  • ·What happens to in-flight requests during a rolling update?
  • ·What is pod disruption budget and why does it matter?
  • ·How does Kubernetes handle secrets differently from config maps?

FURTHER READING

Sign up for the full library + AI-graded practice on this topic →