Docker & Kubernetes
Docker and Kubernetes Interview Questions With Model Answers
Containers, images, networking, orchestration and troubleshooting questions with model answers.
On this page
In one line: a Docker and Kubernetes interview is not a quiz about commands. It checks whether you understand what a container really is (a process with limits, not a small VM), how images and layers behave, how Kubernetes keeps the state you declared, and whether you can find the cause of a failure by reading the right signal. This lesson has more than 30 questions with model answers, and the traps marked.
You have now seen the whole stack: what a container is, how to write a good image, volumes, networks and safety, Compose, the Kubernetes core objects, Services and Ingress, config, secrets and storage, probes, resources and rollouts, and debugging. This last lesson turns that into answers you can say out loud.
How to use it: read each question, answer it out loud in your own words before reading the model answer, then compare. The model answers are written in first person, short, and honest about where I ran something and where I did not. In an interview that honesty is a strength, not a weakness.
What I ran / checked. Docker Engine 29.8.2 has a real daemon in my sandbox. The Docker claims below that say "I ran" are real runs with output I pasted (host kernel 6.18.44-fc-v114; images from mirror.gcr.io because Docker Hub is rate limited here; timings vary). kubectl v1.34.0, kubeconform v0.7.0 and Node v22.22.0 are real too. There is no worker node in my sandbox. For Kubernetes I started a real v1.34.0 control plane (kube-apiserver, kube-controller-manager, kube-scheduler, etcd 3.5.21) by hand with one fake Node. So where a Kubernetes answer says "I saw", the API server, scheduler or controllers really said it. No Kubernetes container ever ran, so claims about probes failing, pods crashing, mounted ConfigMap files and real autoscaling come from the Kubernetes docs and are marked "from the docs, not run on a cluster here". Sources I read (own words below): the Kubernetes website docs for architecture, namespaces, Services, ConfigMaps, Secrets, volumes, StatefulSets, probes, resource management, Deployments, HPA, PodDisruptionBudgets, Pod lifecycle and debugging, and the dockershim removal page (raw markdown from kubernetes/website on GitHub). Could not reach: the rendered kubernetes.io site and Docker Hub directly. I did not re-read Docker's own reference pages for this lesson, so Docker answers rest on real runs and on the earlier lessons. I verified no GitHub star counts.
Words used in this lesson
- Container is an ordinary Linux process (or a group of them) that the kernel isolates and limits.
- Image is a read-only package of files and settings that a container starts from.
- Layer is one step of an image. Layers are stacked and cached.
- Namespace (Linux) is a kernel feature that gives a process its own private view of something, such as processes or the network.
- cgroup is a kernel feature that limits how much CPU, memory and other resources a group of processes may use.
- Registry is a server that stores and serves images.
- Digest is the SHA-256 fingerprint of an image. Unlike a tag, it never changes.
- Orchestrator is a system (Kubernetes) that runs containers across many machines and keeps them in the shape you declared.
- Control plane is the set of Kubernetes components that decide things: API server, etcd, scheduler and controllers.
- kubelet is the agent on each node that starts and watches containers.
- Declarative means you write down the state you want, and the system works out how to get there.
- Reconcile loop is a controller's endless job: compare desired state with actual state and fix the difference.
- Trap question is a question with a tempting, half-true answer.
How to answer well
Interviewers read answers for four signals, whatever the topic.
- A clear one-line answer first. "A container is a process, not a VM." Then details.
- The mechanism, not just the name. "Namespaces isolate what it sees, cgroups limit what it uses."
- The trap, named. "People say Secrets are encrypted. They are only base64."
- A way to check. "I would run
docker inspectand look at the exit code." Showing how you verify is worth more than showing you remember.
For scenario questions ("the site is down after a deploy"), say the order you would look in. Calm, ordered steps beat a fast guess.
Interview questions
Part 1: Containers and images
What is a container, and how is it different from a virtual machine? (Must know)
A container is a normal process on the host, started with a private view of the system (namespaces) and with resource limits (cgroups). It shares the host's kernel. A virtual machine runs a whole guest operating system, with its own kernel, on virtual hardware. So a container starts in milliseconds and is small, and a VM is slower and heavier but isolated more strongly. I can show the kernel sharing: on my sandbox the host reports kernel 6.18.44-fc-v114, and docker run busybox uname -r printed exactly the same thing, even though an Alpine container says it is Alpine Linux in /etc/os-release. The "operating system" in a container is only the files; the kernel is the host's.
What is the difference between an image and a container? (Must know)
An image is a read-only template: files, metadata and a default command, stored as layers. A container is a running (or stopped) instance made from an image, with a thin writable layer on top and its own process. One image can start many containers. The writable layer is lost when the container is removed, which is why I use volumes for data. If I want an object-oriented comparison: an image is a class, a container is an instance.
What do namespaces and cgroups do? (Senior signal)
Namespaces control what a process can see: its own process tree, network, mounts, hostname, users. cgroups control what it can use: CPU, memory, number of processes. A container is these two plus a filesystem from the image. I have watched cgroups work in a lab: a container with --cpus 0.25 was throttled in 50 of 54 scheduling periods while running a busy loop, and a container with --memory 64m was killed with exit code 137 and OOMKilled true when it grew past the limit.
Are containers secure? Does a container give me a sandbox? (Trap)
Not by themselves. Containers share the host kernel, so a kernel bug or a bad setting can let a process escape. The default user in most images is root, and I saw uid=0(root) in a container I started. Risky settings are --privileged, mounting the Docker socket, mounting host paths, and adding capabilities. I run as a non-root user, drop capabilities, use a read-only filesystem where I can, keep images small and patched, and scan them. For strong isolation of untrusted code, I would add something stronger like a VM-based runtime or a sandbox such as gVisor. I would not say "containers are secure" or "containers are insecure"; I say they are isolated by the kernel, and the isolation is only as good as the settings.
What is an image layer, and how does build caching work? (Must know)
Each Dockerfile instruction that changes the filesystem makes a layer. Docker caches layers, and reuses a cached layer if the instruction and everything before it is unchanged. When one layer changes, every layer after it is rebuilt. So the order matters: put things that change rarely (installing dependencies) before things that change often (your source code). I ran this: I copied package.json, ran the install step, and then copied app.js. After I edited only app.js, the build printed CACHED for the COPY package.json and the RUN install steps, and rebuilt only the last COPY. If I had written COPY . . first, any code change would have invalidated the install.
Explain CMD versus ENTRYPOINT. (Must know)
ENTRYPOINT is the program that always runs. CMD is the default arguments, which are easy to replace. When both exist in exec form, the container runs ENTRYPOINT plus CMD. I tested it with ENTRYPOINT ["echo", "entry:"] and CMD ["default-arg"]. Plain docker run printed entry: default-arg. docker run image my-arg printed entry: my-arg, so the argument replaced CMD but ENTRYPOINT stayed. And docker run --entrypoint echo image replaced printed replaced, which shows that replacing the ENTRYPOINT needs the explicit flag. I always use the exec form (a JSON list), so the program is PID 1 and gets signals.
What is the difference between ARG and ENV, and can you put secrets in either? (Trap)
ARG exists only at build time. ENV is saved in the image and is visible to every container started from it. Neither is a safe place for a secret. I tested the trap: I built with --build-arg BUILD_TOKEN=abc123. At run time the variable was empty (token=[]), which makes people think it is gone. But docker history --no-trunc showed ARG BUILD_TOKEN=abc123 and the RUN |1 BUILD_TOKEN=abc123 ... line. Anyone with the image can read it. For build-time secrets I use BuildKit secret mounts (RUN --mount=type=secret), which do not stay in a layer. For run-time secrets I pass them when the container starts, or from the orchestrator's secret store.
What is a multi-stage build and why use it? (Senior signal)
It is a Dockerfile with more than one FROM. The first stage has the compilers and dev tools and builds the app. The last stage starts from a small base and copies in only the built output with COPY --from=build. The final image has no build tools, so it is smaller, has fewer vulnerabilities, and starts faster. Base image choice alone matters a lot: in my sandbox docker images listed node:22 at 1.65 GB of disk and node:22-alpine at 238 MB (disk usage as Docker reports it), and multi-stage then removes the build tools on top of that. A caution I add: Alpine uses musl instead of glibc, and some native modules misbehave there, so I test.
Why is the latest tag a problem, and what is a digest? (Trap)
A tag is a movable label. latest is just a tag with a default value, and it does not mean "newest" or "safest". The image it points to can change under you, so two machines can run different code with the same name, and a rollback by tag is not a rollback. If I omit the tag, Kubernetes treats it as latest and defaults imagePullPolicy to Always. I pin a version tag at the least, and for strict reproducibility I use the digest (image@sha256:...), which is the fingerprint of the exact content and can never point to something else.
What does EXPOSE do? (Trap)
Almost nothing. It is documentation: it records which port the app listens on. It does not publish the port. I tested: an image with EXPOSE 8080 run with no -p; docker port printed nothing, and curl localhost:8080 failed with exit code 7 (connection refused). To reach it from the host I need -p HOST:CONTAINER (or -P, which publishes all exposed ports to random host ports).
Part 2: Volumes, networks and Compose
What are the ways to persist data in Docker? (Must know)
A named volume is managed by Docker and survives the container. A bind mount maps a host folder into the container, good for development. A tmpfs mount lives in memory only. The container's own writable layer is not for persistence. I proved the volume case: I wrote kept to /data/f in one container with -v l9vol:/data, and a second, new container with the same volume printed kept. A file written in a container without a volume (/tmp/f) was gone with that container. In production on Kubernetes, the same idea is a PersistentVolumeClaim.
How do containers find each other by name? (Senior signal)
On Docker's default bridge network there is no name lookup, only IP addresses. On a user-defined network Docker runs an embedded DNS server, so containers reach each other by container or service name. I ran both: from the default bridge, ping l9-a said bad address 'l9-a'. After I created a network and started the target on it, ping l9-b resolved to 172.19.0.2 and replied. Compose creates a user-defined network for the project, which is why db just works as a host name there.
In Compose, does dependson wait for the database to be ready? (Trap)
By default no. depends_on only controls start order: it starts the dependency container first, not when its service is actually accepting connections. To wait for readiness, I add a healthcheck to the database and use depends_on with condition: service_healthy. I would also make the app retry its database connection, because in any real environment the database can restart at any time, and start-up order is only a help for the first start. (This is from my own use of Compose and the earlier lesson, and I did not re-run Compose for this lesson.)
A container stops in 10 seconds when I run docker stop. Why, and how do I fix it? (Senior signal)
Docker sends SIGTERM and waits 10 seconds before SIGKILL. A process running as PID 1 in a container does not get the kernel's default action for signals; it only reacts if it installed a handler. A Node server with no SIGTERM handler therefore ignores it. I measured: docker stop took 10.2 seconds and the exit code was 137. With docker run --init (a small init process forwards signals) it took 0.2 seconds with exit code 143, and with a handler in the code it took 0.3 seconds with exit code 0. Fixes: handle SIGTERM and close the server, use the exec form of CMD (a shell as PID 1 may not forward signals), and use --init or tini. In Kubernetes the same problem makes each pod wait the full 30 second grace period.
Part 3: Kubernetes basics
What problem does Kubernetes solve? (Must know)
Running containers on one machine is easy. Running hundreds, across many machines, with restarts, scaling, updates, service discovery and storage is hard. Kubernetes is the system that takes a description of what I want ("three copies of this image, reachable at this name, with these settings") and keeps it true: it schedules containers onto nodes, replaces failed ones, rolls out new versions, and balances traffic. It does not build images, and it does not make a badly designed app scale.
Describe the architecture: control plane and nodes. (Must know)
The control plane holds the decisions. The API server is the front door that every tool and component talks to. etcd is the database that stores all objects. The scheduler chooses a node for each new pod. The controller manager runs the controllers that push actual state toward desired state. On each node, the kubelet starts and watches the pod's containers through a container runtime, and kube-proxy programs the rules that make Services work. I have run the control plane pieces by hand in my lab, and the key thing I saw is that they are separate processes that only talk through the API server: the controller manager created ReplicaSets and pods, and the scheduler put those pods on a node, without ever calling each other.
What is a pod, and why not just a container? (Must know)
A pod is the smallest thing Kubernetes schedules: one or more containers that share a network address, ports and optionally volumes, and always run on the same node. I use several containers in one pod only when they must work as a unit, for example an app plus a log shipper or proxy (a sidecar). Otherwise one container per pod. Pods are disposable: when one dies, a controller makes a new one with a new name and IP, which is why I never depend on a pod's IP.
What are Deployment, ReplicaSet and Pod, and how do they relate? (Must know)
A Deployment describes the app and how to update it. It owns a ReplicaSet for each version of the pod template. A ReplicaSet keeps a set number of identical pods running. A pod runs the containers. When I change the image in a Deployment, it makes a new ReplicaSet and shifts pods from the old one to the new one at a pace set by maxSurge and maxUnavailable. I saw it directly: after two image changes, kubectl get rs listed three ReplicaSets, one per revision, and the old ones stayed as the rollback history.
What does "declarative" mean, and what is the reconcile loop? (Senior signal)
Declarative means I give the desired end state in YAML, not a list of steps. Controllers then run a loop forever: read the desired state, observe the actual state, take actions to reduce the difference. If a node dies, the actual count of pods drops below desired, and the ReplicaSet controller creates replacements. It is also why kubectl apply is repeatable, and why I should fix the YAML and not hand-edit live objects. In my lab, scaling a Deployment to 14 made the controllers create the missing pods within seconds and the scheduler place as many as fit on my small fake node, which is the loop doing its job.
What are the Service types, and when would you use each? (Must know)
A Service is a stable name and virtual IP in front of changing pods, found by label selector. ClusterIP (default) works inside the cluster only. NodePort also opens a port on every node. LoadBalancer asks the cloud for an external load balancer. A headless Service (clusterIP: None) returns pod addresses directly, used with StatefulSets. For HTTP from outside I normally use one Ingress or Gateway in front of many ClusterIP Services, instead of one load balancer per Service, because that is cheaper and gives path and host routing.
What is the difference between an Ingress and an Ingress controller? (Trap)
An Ingress is only an object with routing rules. It does nothing alone. An Ingress controller is the program (NGINX, Traefik, a cloud one) that reads those objects and does the routing. If no controller is installed, the Ingress is accepted by the API and nothing happens. The Ingress API is frozen and the Kubernetes project recommends the Gateway API for new work.
Did Kubernetes drop Docker support, and do my Docker images still work? (Trap)
Kubernetes removed its built-in dockershim in release 1.24, which is what let it talk to the Docker Engine directly. It now talks to container runtimes such as containerd or CRI-O through the CRI. Docker-built images still work, because they follow the OCI image format. What breaks is anything that relied on the Docker socket on the node (some monitoring tools, "docker in docker" builds). I read this on the Kubernetes dockershim page.
What is a namespace, and is it a security boundary? (Trap)
A namespace is a scope for names and for policies: two teams can both have a Deployment called api in different namespaces, and I can attach quotas, RBAC rules and network policies per namespace. By itself it does not isolate anything. Pods in different namespaces can still talk to each other by default, and a namespace gives no protection until I add RBAC, NetworkPolicy and quotas. So I say it is a grouping tool, and security comes from the extra rules.
Part 4: Config, storage and reliability
Are Kubernetes Secrets encrypted? (Trap)
No, not by default. The values are base64, which is just an encoding that I can reverse with base64 -d. By default they are stored in etcd as they are. I read one straight from etcd with etcdctl in my lab, and the password was readable in the stored bytes. Then I enabled an EncryptionConfiguration with aescbc, restarted the API server, and the stored value began with k8s:enc:aescbc:v1:key1: and no longer contained the password. Safety needs three things: tight RBAC (anyone who can get or list secrets, or create pods, can read them), encryption at rest (best with a KMS), and not keeping secrets in Git. I also know kubectl apply stores the applied manifest in an annotation, which put a plain copy of my stringData password there.
You update a ConfigMap. Do running pods see the change? (Trap)
It depends. A ConfigMap used as environment variables is never updated in a running container; I need to restart the pods, for example kubectl rollout restart. A ConfigMap mounted as a volume does update after a delay, unless it is mounted with subPath, and the app has to re-read the file. For predictable changes I use an immutable ConfigMap with a version in its name, so the Deployment changes and a normal rolling update happens (and I can roll back). I confirmed that an immutable ConfigMap rejects edits: field is immutable when immutable is set. The update behaviour itself is from the docs, not run on a cluster here.
Explain PersistentVolume, PersistentVolumeClaim and StorageClass. (Must know)
The PV is a real piece of storage. The PVC is a pod's request for storage with a size and access mode. The StorageClass is the recipe for making storage on demand (dynamic provisioning). I create the claim, the provisioner creates the volume, Kubernetes binds them, and the pod mounts the claim. A claim with no matching class or volume stays Pending; I saw the event no persistent volumes available for this claim and no storage class is set. I also mention WaitForFirstConsumer (create the disk in the same zone as the pod) and reclaimPolicy (Delete removes the disk when the claim is deleted).
When do you use a StatefulSet instead of a Deployment? (Senior signal)
When each pod needs a stable identity and its own storage: databases, queues, anything clustered. A StatefulSet gives stable names (pg-0, pg-1), stable DNS through a headless Service, a PVC per pod from volumeClaimTemplates that follows the pod, and ordered start and stop. It does not give replication or failover; the database software or an operator does that. Its PVCs are kept on scale-down by default. For a production database I often prefer a managed service.
What is the difference between liveness, readiness and startup probes? (Must know)
Readiness decides whether the pod gets traffic; failing it removes the pod from the Service but does not restart it. Liveness decides whether to restart a stuck container. Startup holds off the other two until a slow app has started. The big trap is a liveness probe that checks the database: when the database is slow, all pods fail liveness at once and are restarted together, which turns a small problem into an outage. Liveness should only test the process; dependency checks go in readiness. The behaviour is from the docs, not run on a cluster here, but I confirmed the defaults on the API server: period 10 s, timeout 1 s, failure threshold 3.
What is the difference between resource requests and limits? (Must know)
A request is what the scheduler reserves when it places the pod. A limit is the cap enforced at run time. Over a CPU limit, the container is throttled. Over a memory limit, it is killed (OOMKilled, exit code 137). The scheduler works from requests, not from real usage: in my lab a pod asking for 100 CPUs got 0/1 nodes are available: 1 Insufficient cpu, and a node can be "full" for the scheduler while the machine is idle. From the numbers, Kubernetes sets the QoS class: Guaranteed, Burstable or BestEffort (I created one of each and read the class from the API). My default is to set CPU and memory requests, a memory limit, and think hard before setting a CPU limit because of throttling.
How would you do a zero-downtime deployment? (Senior signal)
A rolling update with maxUnavailable: 0 and maxSurge: 1 (or more), so a new pod must be ready before an old one is stopped. That only works with an honest readiness probe. I also add: a SIGTERM handler and a short preStop sleep so in-flight and just-routed requests finish, enough replicas (at least two), a PodDisruptionBudget for node maintenance, and a way to roll back (kubectl rollout undo). Both maxSurge and maxUnavailable cannot be zero; the API server refuses that. I add a progress deadline, because Kubernetes reports a stuck rollout but does not roll it back by itself.
How does the HPA decide how many pods? What can go wrong? (Senior signal)
It computes ceil(currentReplicas x currentMetric / targetMetric), within min and max, and ignores changes inside a 10% tolerance. For CPU, the metric is average usage as a percentage of the pods' requests, so pods must have CPU requests, and the cluster needs metrics-server. It scales down slowly, using a five minute stabilization window by default. Things that go wrong: no metrics (I saw cpu: <unknown>/70% and the condition FailedGetResourceMetric), Deployment YAML that still sets replicas and fights the HPA on each apply, and new pods staying Pending because the HPA adds pods and not nodes. A cluster autoscaler adds nodes.
What does a PodDisruptionBudget protect against? (Senior signal)
Voluntary disruptions: node drains, upgrades, autoscaler scale-down. It sets minAvailable or maxUnavailable for pods that match a selector, and the Eviction API checks it. It does not protect against crashes. It counts only ready pods, so if my pods are not ready the allowed disruptions are zero (I saw ALLOWED DISRUPTIONS 0). A budget equal to the replica count blocks every drain. And pods in Pending can always be evicted, which surprised me when my eviction succeeded.
Part 5: Troubleshooting scenarios
A pod is in CrashLoopBackOff. What do you do? (Must know)
kubectl logs POD --previous for the crashed instance (plain logs shows the new one), then kubectl describe pod for the exit code, reason and events. Exit 1 plus an error means app or config. 137 means killed: OOM or probe. 126 or 127 means a bad command. If it dies too fast to exec into, kubectl debug POD --copy-to=copy --container=app -- sleep 3600 and exec into the copy. I reproduced the Docker version of this loop: a container missing DATABASE_URL restarted six times in six seconds and the same error was in the logs each time.
A pod has restarted several times and the logs show no error. (Trap)
Think OOM kill first. SIGKILL cannot be caught, so the app prints nothing. I run kubectl describe pod and look for Last State: Terminated, Reason: OOMKilled, Exit Code: 137. I reproduced it with Docker: logs ended at held 50 MiB with no message, and docker inspect showed exit=137 oom=true. Otherwise it could be a failing liveness probe, which shows in the events as Liveness probe failed.
A pod is stuck in Pending. (Must know)
I run kubectl describe pod and read the scheduler events. They have the shape 0/N nodes are available: followed by the reasons. I have seen three: Insufficient cpu, node(s) didn't match Pod's node affinity/selector, and persistentvolumeclaim "..." not found. Others: untolerated taints, or an unbound PVC. If the pod does not exist at all and the Deployment shows 0 ready, I check the ReplicaSet events, since a ResourceQuota can block pod creation (must specify limits.memory ...).
ImagePullBackOff. (Must know)
The node cannot pull the image and retries with a growing delay, up to five minutes. I read the events in describe, then try docker pull of the same image. not found means the name or tag is wrong. unauthorized means missing or wrong credentials, so I check imagePullSecrets in the same namespace. I also check registry rate limits and node network access.
Users get errors through a Service, but the pods look Running. (Must know)
I go from near to far. Are the pods Ready (Running is not Ready)? Does the app answer inside the pod (exec or port-forward)? Does the Service have endpoints (kubectl get endpointslices -l kubernetes.io/service-name=NAME)? If empty: selector typo, or unready pods. Does targetPort match the real port? DNS from another pod? NetworkPolicy? Ingress? I have seen the empty endpoint list (ENDPOINTS <unset>) when the pod was not ready.
A pod is stuck in Terminating. (Trap)
A delete was requested but cannot finish. The usual reasons: a finalizer that nothing removes (for example an admission webhook that blocks the update), a node that is gone so the kubelet cannot confirm, or a process that ignores SIGTERM and is waiting for the grace period. I saw something close in my lab: pods placed on my fake node stayed Terminating forever, because there was no kubelet to confirm the delete. I look at describe, the finalizers, and the node state before reaching for --force, because force-deleting only removes the object, not the process that may still be running.
A node goes NotReady. What happens and what do you check? (Senior signal)
The kubelet stopped reporting. After about five minutes the pods are evicted and recreated elsewhere (from the docs). I run kubectl describe node for conditions and events, then check the machine: kubelet logs, disk, memory, network plugin, instance health. My apps should survive it anyway: more than one replica, spread across nodes, with a PDB for planned work.
Walk me through deploying a Node.js API to Kubernetes, end to end. (Senior signal)
I build a small image with a multi-stage Dockerfile, a non-root user, an exec-form CMD, pinned versions, and .dockerignore. I scan it and push it to a registry with a specific tag. In Kubernetes I write a Deployment (2+ replicas, readiness/liveness/startup probes, resource requests and a memory limit, a rolling update with maxUnavailable: 0, a SIGTERM handler and preStop), a ConfigMap and Secret for settings (secrets from an external store or encrypted at rest), a Service, and an Ingress or Gateway route with TLS. I add an HPA, a PodDisruptionBudget and a NetworkPolicy. I validate the YAML with kubeconform -strict in CI, and I deploy with a pipeline that waits on rollout status and rolls back on failure. For logs and metrics I use the cluster's collection stack. I say clearly which parts I have run on a real cluster and which I know from the docs.
Quick-fire round
These are short questions that often open an interview. Practise answering each in one sentence.
| Question | One-sentence answer |
|---|---|
| What is PID 1 in a container? | The main process; it gets the signals and must reap child processes. |
docker run vs docker start? | run creates a new container and starts it; start restarts an existing stopped one. |
docker exec vs docker attach? | exec starts a new process in the container; attach connects to the main process. |
What does docker system prune do? | Removes stopped containers, unused networks and dangling images (be careful). |
What is .dockerignore for? | Keeps files out of the build context: smaller, faster builds, no leaked secrets. |
| Name the main Kubernetes objects for stateless apps. | Deployment, ReplicaSet, Pod, Service, ConfigMap, Secret, Ingress. |
| What is a label vs an annotation? | Labels are for selecting; annotations are for extra info that tools read. |
What does kubectl apply do vs create? | apply creates or updates from a file and tracks changes; create fails if the object exists. |
| What is a DaemonSet? | One pod on every node (log agents, monitoring). |
| What is a Job / CronJob? | Run to completion once / on a schedule. |
| What is a sidecar? | A second container in the same pod that helps the main one. |
| What is an init container? | A container that must finish before the app containers start. |
What does kubectl rollout undo do? | Creates a new revision with an older pod template. |
| Where do you look first for a Pending pod? | kubectl describe pod, the scheduler events. |
| Where do you look first for CrashLoopBackOff? | kubectl logs --previous. |
Try it: a mock round
Set a 25 minute timer. Answer the six questions below out loud, with no notes. Then compare.
- "A new version goes out and half of your users see errors for a minute. What could be wrong, and how do you prevent it?"
- "Your container works on your laptop but exits immediately in the cluster with no useful logs. What do you do?"
- "How would you make sure a database password never ends up in a Git repository or an image?"
- "Your API costs a lot because every pod requests 2 CPUs and uses 0.2. How do you right-size it safely?"
- "A teammate says 'Kubernetes will restart my app if it crashes, so I don't need a health check.' What do you say?"
- "Explain, in two minutes, what happens from
kubectl apply -f deployment.yamluntil a user's request reaches a pod."
Answers
- Probably new pods got traffic before they were ready (no readiness probe, or one that always passes), old pods were killed with requests in flight (no SIGTERM handling or
preStop), or the update was too aggressive (maxUnavailabletoo high). Prevent with an honest readiness probe,maxUnavailable: 0, graceful shutdown,minReadySeconds, and a quick rollback path. Watch withkubectl rollout status. - Get the facts in order:
kubectl describe pod(state, exit code, events),kubectl logs --previous, compare environment and config with the laptop (a missing env var or ConfigMap key is the top cause), check architecture (an image built for another CPU type fails with an exec format error), thenkubectl debug --copy-towith a sleep command to look inside. Reproduce withdocker runusing the same image and env. - Do not put it in the image (
ARG/ENVend up in layers and indocker history) and do not commit manifests with it. Use an external secret manager synced into Kubernetes, or sealed/encrypted files, with encryption at rest on the cluster and tight RBAC. Prefer mounting as a file over env vars for the most sensitive values. - Measure real use over a period with
kubectl topand metrics (peak and typical), set requests near typical use plus headroom, keep a memory limit above peak, and use an HPA for load. Change in steps and watch for throttling, OOM kills and latency. A VPA in recommendation mode can suggest values. - Kubernetes restarts a process that exits. It cannot know a process that is alive but stuck, or a pod that runs but cannot serve. Readiness decides who gets traffic, and liveness catches stuck processes. Without them, the Service may route to a pod that is not ready.
kubectlsends the object to the API server, which validates it and stores it in etcd. The Deployment controller sees it and creates a ReplicaSet; the ReplicaSet controller creates pods; the scheduler assigns each pod to a node (by requests, selectors, taints); the kubelet on that node pulls the image, starts the containers through the runtime, and runs probes. When the pod is ready it is added to the Service's EndpointSlice; kube-proxy rules (or an Ingress controller for outside traffic) send the request to it. I have seen the first half of this chain happen for real, from the apply to a scheduled pod, in my control-plane lab.
Key takeaways
- A container is a process with isolation and limits, sharing the host kernel. It is not a small VM. (Proof: same
uname -ras the host.) - Image layers are cached in order. Put slow, stable steps first. Pin tags, and use digests for exact reproducibility.
EXPOSEdocuments,-ppublishes.ARGvalues can be read fromdocker history. Default bridge has no DNS; user networks do.CMDis default arguments,ENTRYPOINTis the program. Use exec form so signals reach your app.- Kubernetes keeps declared state through reconcile loops. The control plane components only talk through the API server.
- Pod, ReplicaSet and Deployment: the Deployment makes a ReplicaSet per version and shifts pods between them.
- Secrets are base64 and, by default, readable in etcd. Safety needs RBAC, encryption at rest, and an external source.
- Probes decide traffic and restarts. Requests schedule, limits enforce. OOM kills leave no log message.
- Zero downtime needs the readiness probe,
maxUnavailable: 0, graceful shutdown, enough replicas and a PDB. - In troubleshooting, say the order you will look in, and name the exact command that shows each answer.
What's next
This is the last lesson of the series. A good next step is to build something small end to end: containerise a Node app, run it with Compose, then deploy it to a local cluster (kind or minikube) with a Deployment, Service, ConfigMap, probes, requests and an HPA, and break it on purpose using the failures from lesson 8. To keep going on the interview side, try the Security series, because container security, secrets and least privilege come up in almost every Kubernetes interview.
Published by Jainik ยท Last updated ยท How these lessons are made
Keep learning
Related lessons
- Containers, Kubernetes, Terraform and AWS for Full-Stack Interviews ยท Full-Stack Questions
Part of the study guide
Related series