{"id":1161,"date":"2026-07-11T09:25:15","date_gmt":"2026-07-11T03:55:15","guid":{"rendered":"https:\/\/lastroundai.com\/blog\/?post_type=iq&#038;p=1161"},"modified":"2026-07-19T09:23:29","modified_gmt":"2026-07-19T03:53:29","slug":"kubernetes","status":"publish","type":"iq","link":"https:\/\/lastroundai.com\/interview-questions\/kubernetes","title":{"rendered":"Kubernetes Interview Questions (2026): 39 Most Asked, With Answers"},"content":{"rendered":"<p>Kubernetes production use among container users hit 82 percent in CNCF&#8217;s January 2026 Annual Cloud Native Survey, up from 66 percent just two years earlier (<a href=\"https:\/\/www.cncf.io\/announcements\/2026\/01\/20\/kubernetes-established-as-the-de-facto-operating-system-for-ai-as-production-use-hits-82-in-2025-cncf-annual-cloud-native-survey\/\" target=\"_blank\" rel=\"noopener noreferrer\">CNCF, 2026<\/a>). That&#8217;s a fast jump for a tool most engineering teams were still calling &#8220;too much for us&#8221; as recently as 2022. It shows up directly in interviews now: almost nobody runs a Kubernetes-flavored loop assuming you&#8217;ve only read about a cluster.<\/p>\n<p>Here&#8217;s an opinion that might be wrong: I think Kubernetes interviews still over-index on object trivia, what field goes where in a Pod spec, what the third flag to kubectl does, and under-index on judgment. Knowing that a Deployment manages a ReplicaSet is table stakes, five minutes of memorization. Knowing why a rollout is stuck at 2 of 5 replicas ready, with three plausible causes and only one that&#8217;s actually true for this cluster, is the real skill, and it&#8217;s the part almost nobody drills before the actual loop.<\/p>\n<p>This page covers the Kubernetes interview questions that come up across architecture, Pods, Deployments and ReplicaSets, Services and Ingress, ConfigMaps and Secrets, storage, namespaces, scheduling, scaling, networking, RBAC, health checks, and troubleshooting, roughly the order most 2026 platform or DevOps loops move through. Some of it is definitional. Most of it is &#8220;here&#8217;s a cluster doing something weird, walk me through how you&#8217;d find out why,&#8221; because that&#8217;s closer to what the job actually is once you&#8217;re the one holding the pager.<\/p>\n<div class=\"iq-stats not-prose\"><div class=\"iq-stat\"><span class=\"iq-stat__value\">55<\/span><span class=\"iq-stat__label\">Questions<\/span><\/div><div class=\"iq-stat\"><span class=\"iq-stat__value\">14<\/span><span class=\"iq-stat__label\">Topics Covered<\/span><\/div><div class=\"iq-stat\"><span class=\"iq-stat__value\">82% (CNCF, 2026)<\/span><span class=\"iq-stat__label\">K8s Production Use<\/span><\/div><div class=\"iq-stat\"><span class=\"iq-stat__value\">Pod, Deployment, Service<\/span><span class=\"iq-stat__label\">Core Objects<\/span><\/div><\/div>\n<h2>Architecture: control plane, kubelet, and etcd<\/h2>\n<p>Every loop touches this early, even for application-focused roles. It&#8217;s a warm-up in theory, but a vague answer here tells an interviewer you&#8217;ve deployed to a cluster without ever wondering what&#8217;s actually running it.<\/p>\n<div class=\"iq-dsec iq-dsec--easy\"><div class=\"iq-dsec__row\"><h2 class=\"iq-dsec__h\" id=\"easy\"><span class=\"iq-dsec__dot\" aria-hidden=\"true\"><\/span>Easy questions<\/h2><span class=\"iq-dsec__n\">16<\/span><\/div><div class=\"iq-dsec__bar\" aria-hidden=\"true\"><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What are the core control plane components, and what does each one actually do?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Architecture<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>The kube-apiserver is the front door, every read and write to cluster state goes through it, and it&#8217;s the only component that talks to etcd directly. etcd is the cluster&#8217;s source of truth, a distributed key-value store holding every object&#8217;s current desired state. The kube-scheduler watches for unscheduled Pods and assigns them to a node. The kube-controller-manager runs the reconciliation loops (the ones that notice a ReplicaSet has 2 Pods when it should have 3, and creates the third) (<a href=\"https:\/\/kubernetes.io\/docs\/concepts\/overview\/components\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes docs, Components<\/a>).<\/p>\n<p>Interviewers use this question to check whether &#8220;control plane&#8221; is a real mental model or just a phrase you&#8217;ve heard. A candidate who lumps etcd, the apiserver, and the scheduler into one vague &#8220;the master&#8221; is going to struggle two questions later when asked what actually breaks if only one of them goes down.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Why is a Pod, not a container, the smallest deployable unit in Kubernetes?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Pods<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A Pod is a shared context for one or more containers: they share a network namespace (same IP, can reach each other over localhost) and can share storage volumes. Kubernetes models &#8220;one instance of my application&#8221; as a Pod because real applications sometimes need a tightly coupled helper running alongside the main process, a log shipper, a proxy, something that only makes sense co-located.<\/p>\n<p>Scheduling, scaling, and networking all happen at the Pod level, never per-container. Two containers in one Pod always land on the same node, always scale together, and always share the same IP address.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s the relationship between a Deployment and a ReplicaSet, and why do you rarely create a ReplicaSet directly?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Deployments<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A Deployment manages ReplicaSets, and a ReplicaSet manages Pods. The ReplicaSet&#8217;s whole job is keeping N identical Pods running; it doesn&#8217;t know anything about rollout strategy, revision history, or rollback.<\/p>\n<p>A Deployment adds all of that on top: rolling updates, a revision history you can roll back to, and pause\/resume for a rollout. Creating a bare ReplicaSet directly means giving up rollout and rollback entirely, so almost nobody does it outside of a lab exercise.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s a StatefulSet, and why would you reach for one instead of a Deployment?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">StatefulSets<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A StatefulSet is for workloads that need a stable, unique identity per replica, most commonly a database, a message queue, or anything where &#8220;which specific instance am I talking to&#8221; matters. Deployment replicas are interchangeable and disposable, Pod names carry a random suffix, and any replica can stand in for any other. StatefulSet replicas get a predictable name instead, <code>web-0<\/code>, <code>web-1<\/code>, <code>web-2<\/code>, and that identity survives a restart.<\/p>\n<p>The practical trigger for picking one is whether replica 2 needs to come back as replica 2 with the same disk it had before, or whether it genuinely doesn&#8217;t matter which replica handles a given request. Stateless web servers almost never need this. A 3-node Postgres cluster or a Kafka broker almost always does.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s a DaemonSet, and when do you actually need one instead of a Deployment with a lot of replicas?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">DaemonSets<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A DaemonSet guarantees exactly one Pod per node, or per node matching a selector, and it automatically adds a Pod when a new node joins the cluster and removes it when a node leaves. A Deployment has no concept of &#8220;one per node&#8221; at all, its replica count is a fixed number you set, unrelated to how many nodes exist.<\/p>\n<p>Log collectors, node-level monitoring agents, and CNI plugins themselves are the classic DaemonSet use cases, anything that has to run on every single node regardless of what else gets scheduled there. Faking that with a Deployment means manually tracking node count and updating <code>replicas<\/code> every time the cluster scales, which nobody actually does in practice.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s a Job, and how is a CronJob different from just running a Job manually?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Jobs &amp; CronJobs<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A Job runs a Pod, or several, to completion and then stops, unlike a Deployment, which expects its Pods to run forever and restarts them if they exit. Set <code>completions<\/code> and <code>parallelism<\/code> to control how many successful runs are needed and how many can run at once, and a Job&#8217;s <code>restartPolicy<\/code> has to be <code>Never<\/code> or <code>OnFailure<\/code>, never <code>Always<\/code>.<\/p>\n<p>A CronJob is a Job template instantiated on a schedule, standard cron syntax, and Kubernetes creates a fresh Job object every time the schedule fires. The field worth knowing is <code>concurrencyPolicy<\/code>: <code>Allow<\/code> lets overlapping runs pile up if one&#8217;s still going when the next is due, <code>Forbid<\/code> skips the new one entirely, and <code>Replace<\/code> kills the old run and starts the new one. Forgetting to set this to <code>Forbid<\/code> on a job that isn&#8217;t safe to run twice at once is a common source of very confusing double-writes.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">ClusterIP, NodePort, LoadBalancer, and ExternalName, what&#039;s each Service type actually for?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Services<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>ClusterIP is the default: a stable virtual IP reachable only from inside the cluster. NodePort opens the same port on every node in the cluster and forwards to the Service, giving external access without a cloud load balancer, useful for bare-metal or local testing. LoadBalancer provisions an actual cloud load balancer (an ELB, say) that routes to the Service, the standard way to expose something to the public internet on a managed cloud. ExternalName is different from the other three entirely, it&#8217;s just a DNS alias to an external hostname, no proxying or load balancing involved at all.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s the actual difference between a ConfigMap and a Secret, and is a Secret genuinely more secure by default?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">ConfigMaps &amp; Secrets<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Structurally, almost nothing, both store key-value data and both can be mounted as environment variables or a volume. A Secret&#8217;s values are base64-encoded rather than plain text.<\/p>\n<p>Base64 is encoding, not encryption. Anyone with API access to read the Secret object can decode it in one line. Without encryption at rest enabled on etcd, a Secret sitting in etcd is genuinely no more protected than a ConfigMap, it&#8217;s just less readable at a glance. Real protection comes from RBAC restricting who can read Secrets, encryption at rest on etcd, and for anything genuinely sensitive, an external secrets manager like Vault instead of relying on the built-in object alone.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s the difference between a Volume, a PersistentVolume, and a PersistentVolumeClaim?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Storage<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A plain Volume (like <code>emptyDir<\/code>) is tied to a Pod&#8217;s lifecycle, gone when the Pod is. A PersistentVolume (PV) is a cluster-level resource representing actual durable storage, an EBS volume, an NFS share, whatever the underlying infrastructure provides, independent of any specific Pod. A PersistentVolumeClaim (PVC) is a request: &#8220;I need 10Gi of storage with these access modes,&#8221; which Kubernetes binds to a matching PV.<\/p>\n<p>Pods never reference a PV directly. They reference a PVC, and the PVC is what&#8217;s bound to a PV behind the scenes. That indirection is what lets storage survive a Pod being deleted and recreated, as long as the PVC itself isn&#8217;t deleted too.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Are namespaces a security boundary? What do they actually isolate, and what do they not isolate?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Namespaces<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Not by default, and this catches people out. A namespace isolates names (two Deployments called <code>api<\/code> can coexist in different namespaces without conflicting) and gives you a scope for RBAC rules and ResourceQuotas. It does not isolate network traffic on its own, a Pod in namespace A can reach a Pod in namespace B over the network unless a NetworkPolicy explicitly blocks it.<\/p>\n<p>Real isolation between namespaces takes RBAC (who can do what, scoped per namespace) plus NetworkPolicies (what traffic is allowed between namespaces) working together. Neither alone gets you there.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What does the Horizontal Pod Autoscaler actually scale, and what does it need to work at all?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">HPA<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>HPA adjusts the replica count on a Deployment, ReplicaSet, or StatefulSet based on observed metrics, CPU and memory by default, or custom and external metrics through the metrics API. It needs the metrics-server (or a custom metrics adapter for anything beyond CPU and memory) actually running in the cluster, without it, HPA has nothing to read and won&#8217;t scale at all (<a href=\"https:\/\/kubernetes.io\/docs\/tasks\/run-application\/horizontal-pod-autoscale\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes docs, Horizontal Pod Autoscaling<\/a>).<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s the difference between a Role and a ClusterRole, and a RoleBinding and a ClusterRoleBinding?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">RBAC<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A Role grants permissions scoped to a single namespace. A ClusterRole grants permissions across the whole cluster, or for cluster-scoped resources like Nodes that don&#8217;t belong to any namespace at all. A RoleBinding attaches a Role (or even a ClusterRole) to a subject within one specific namespace. A ClusterRoleBinding attaches a ClusterRole to a subject across every namespace in the cluster.<\/p>\n<p>The trap: a ClusterRole bound with a RoleBinding only grants those permissions in the RoleBinding&#8217;s namespace, not cluster-wide, which is a legitimately useful pattern (reuse one ClusterRole definition, bind it narrowly per namespace) but confuses people who assume ClusterRole always means cluster-wide access.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Liveness vs. readiness vs. startup probes, what does each one actually control?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Probes<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A liveness probe answers &#8220;is this container alive, or should Kubernetes restart it.&#8221; A readiness probe answers &#8220;is this container ready for traffic right now,&#8221; and failing it just pulls the Pod out of the Service&#8217;s Endpoints without restarting anything. A startup probe answers &#8220;has this container finished its slow initial boot,&#8221; and it delays the other two probes until it passes, which matters for JVM apps or anything with a genuinely long warmup.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\nlivenessProbe:\n\n  httpGet:\n\n    path: \/healthz\n\n    port: 8080\n\n  initialDelaySeconds: 10\n\n  periodSeconds: 10\n\nreadinessProbe:\n\n  httpGet:\n\n    path: \/ready\n\n    port: 8080\n\n  periodSeconds: 5\n\nstartupProbe:\n\n  httpGet:\n\n    path: \/healthz\n\n    port: 8080\n\n  failureThreshold: 30\n\n  periodSeconds: 2\n<\/code><\/pre><\/div><br \/>\n<\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Besides an HTTP check, what other ways can a probe determine if a container is healthy?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Probes<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Three mechanisms exist beyond <code>httpGet<\/code>. <code>exec<\/code> runs a command inside the container and treats exit code 0 as success and anything else as failure. <code>tcpSocket<\/code> just checks whether a TCP connection to a given port succeeds, no HTTP involved at all. <code>grpc<\/code>, stable since 1.27, calls the standard gRPC health checking protocol directly.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\nlivenessProbe:\n\n  exec:\n\n    command:\n\n      \u2013 cat\n\n      \u2013 \/tmp\/healthy\n\nreadinessProbe:\n\n  tcpSocket:\n\n    port: 5432\n<\/code><\/pre><\/div><\/p>\n<p><code>tcpSocket<\/code> is the common choice for anything that isn&#8217;t HTTP: a database, a message broker, a raw TCP service with no health endpoint at all. <code>exec<\/code> is the fallback when nothing else fits, checking for a file&#8217;s existence or running a small script, but it&#8217;s the slowest of the three since it forks a process inside the container on every single check.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">A pod is stuck in ImagePullBackOff. What are the likely causes, in order of frequency?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Troubleshooting<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A typo in the image name or tag is the most common cause by a wide margin. Second: missing or wrong imagePullSecrets for a private registry. Third: the image genuinely doesn&#8217;t exist at that tag, someone forgot to push it, or a CI job tagged the wrong build. Fourth, and rarer: registry rate limiting, which shows up as intermittent pull failures rather than a consistent one.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">In general, not tied to a rollout, what actually causes CrashLoopBackOff, and what&#039;s the fastest way to narrow it down?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Troubleshooting<\/span><span class=\"iq-badge iq-badge--easy\">Easy<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>CrashLoopBackOff means the container keeps exiting and Kubernetes keeps restarting it with an increasing backoff delay between attempts, up to 5 minutes. The container itself, not the Pod, is what&#8217;s crashing, so the cause is almost always inside it: a bad command or entrypoint, a missing environment variable the app requires at startup, a dependency such as a database or config file that isn&#8217;t reachable yet, or the app hitting an unhandled exception seconds after boot.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">bash<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-bash\">\n\nkubectl logs &lt;pod-name&gt; \u2013previous\n\nkubectl describe pod &lt;pod-name&gt;\n<\/code><\/pre><\/div><\/p>\n<p><code>--previous<\/code> is the detail people forget. By the time you notice the crash loop, the current container attempt might not have logged anything useful yet, but the one before it usually did. If logs are empty even with <code>--previous<\/code>, the crash is happening before the app can log anything at all, which usually points at the entrypoint or command being wrong, not the application code.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-dsec iq-dsec--medium\"><div class=\"iq-dsec__row\"><h2 class=\"iq-dsec__h\" id=\"medium\"><span class=\"iq-dsec__dot\" aria-hidden=\"true\"><\/span>Medium questions<\/h2><span class=\"iq-dsec__n\">24<\/span><\/div><div class=\"iq-dsec__bar\" aria-hidden=\"true\"><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s the difference between the kube-apiserver and the kubelet, and why can&#039;t the kubelet talk directly to another node&#039;s kubelet?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Architecture<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>The kube-apiserver is centralized, one logical instance (usually run 3-way for high availability) that every other component talks to. The kubelet is per-node: an agent that watches the API server for Pods assigned to its own node and makes sure the containers described in those PodSpecs are actually running and healthy.<\/p>\n<p>Kubelets never gossip with each other directly. There&#8217;s no peer-to-peer layer. Everything routes through the apiserver, which is what lets Kubernetes enforce RBAC and admission control consistently instead of trusting whatever a node claims about itself.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s the difference between a control plane node and a worker node, and can a cluster survive losing its only control plane node?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Architecture<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Worker nodes run application Pods. Control plane nodes run the apiserver, scheduler, controller-manager, and usually etcd (in a &#8220;stacked&#8221; topology, though etcd can also run externally). Most production clusters run 3 or 5 control plane nodes specifically so no single failure takes the whole thing down.<\/p>\n<p>If you&#8217;re running a single control plane node and it dies, already-running Pods on worker nodes keep serving traffic, since kube-proxy rules and running containers don&#8217;t depend on the control plane staying up. What stops working: no new scheduling, no self-healing (a crashed Pod won&#8217;t get replaced), no kubectl access, and no rollouts. It&#8217;s degraded, not dead, and that distinction trips up candidates who assume &#8220;control plane down&#8221; means &#8220;cluster down.&#8221;<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s a static Pod, and why does the kubelet manage some Pods without ever talking to the API server about them?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Architecture<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A static Pod is defined by a manifest file sitting directly on a node&#8217;s filesystem, usually under <code>\/etc\/kubernetes\/manifests<\/code>, and the kubelet on that node watches the directory itself, not the API server, to decide what should be running. The kubelet still creates a mirror Pod object in the API server so <code>kubectl get pods<\/code> shows it, but that mirror is read-only. Deleting it through kubectl accomplishes nothing, the kubelet just recreates it because the real source of truth is the file on disk.<\/p>\n<p>This is exactly how kubeadm bootstraps a cluster: kube-apiserver, kube-scheduler, kube-controller-manager, and often etcd itself run as static Pods on the control plane nodes. It&#8217;s a neat fix for a chicken-and-egg problem, the apiserver needs to be running before normal Pods can get scheduled, but the apiserver can&#8217;t be a normal Pod if nothing&#8217;s running yet to schedule it.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s a sidecar container, and how is it different from just running two unrelated processes in the same container?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Multi-Container Pods<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A sidecar is a second container in the same Pod that supports the main application container, a service mesh proxy, a log forwarder, a config-reloader, without being bundled into the same container image. It has its own lifecycle, its own image, its own restart behavior, but it shares the Pod&#8217;s network and can share volumes with the main container.<\/p>\n<p>As of Kubernetes 1.29 (default-enabled) and stable since 1.33, sidecars can be declared as init containers with <code>restartPolicy: Always<\/code>. That fixes a real problem the old pattern had: native sidecars start before the main container, and Kubernetes waits for a sidecar&#8217;s own startup probe to pass before moving on, instead of racing both containers to start at the same time and hoping the proxy comes up first (<a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/pods\/sidecar-containers\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes docs, Sidecar Containers<\/a>).<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: v1\n\nkind: Pod\n\nmetadata:\n\n  name: app-with-sidecar\n\nspec:\n\n  initContainers:\n\n    \u2013 name: log-shipper\n\n      image: fluent-bit:2.2\n\n      restartPolicy: Always\n\n      volumeMounts:\n\n        \u2013 name: logs\n\n          mountPath: \/var\/log\/app\n\n  containers:\n\n    \u2013 name: app\n\n      image: myapp:1.4\n\n      volumeMounts:\n\n        \u2013 name: logs\n\n          mountPath: \/var\/log\/app\n\n  volumes:\n\n    \u2013 name: logs\n\n      emptyDir: {}\n<\/code><\/pre><\/div><br \/>\n<\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What are the possible Pod phases, and what does Running actually guarantee, or not guarantee?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Pods<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Pending, Running, Succeeded, Failed, and Unknown. Pending means the Pod&#8217;s been accepted by the cluster but at least one container image is still being pulled, or the Pod hasn&#8217;t been scheduled yet at all.<\/p>\n<p>Running only means at least one container is running, not that the application inside is healthy or serving traffic. That&#8217;s the gap readiness probes exist to close. A Pod can sit in Running for hours while its actual app is deadlocked, and kubectl get pods will show it as if nothing&#8217;s wrong unless something&#8217;s actually checking.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Walk through what happens, step by step, when you update the image on a Deployment with the default rolling update strategy.<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Rollouts<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>The Deployment controller creates a new ReplicaSet with the updated Pod template and revision 0 replicas. It then scales the new ReplicaSet up and the old one down incrementally, bounded by <code>maxSurge<\/code> (how many extra Pods beyond the target count it can create at once) and <code>maxUnavailable<\/code> (how many Pods below the target count it can tolerate at once).<\/p>\n<p>Each new Pod has to pass its readiness probe before the controller scales the old ReplicaSet down further, that&#8217;s the mechanism that actually prevents a bad rollout from taking down all your capacity at once.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: apps\/v1\n\nkind: Deployment\n\nmetadata:\n\n  name: checkout\n\nspec:\n\n  replicas: 6\n\n  strategy:\n\n    type: RollingUpdate\n\n    rollingUpdate:\n\n      maxSurge: 1\n\n      maxUnavailable: 1\n\n  selector:\n\n    matchLabels:\n\n      app: checkout\n\n  template:\n\n    metadata:\n\n      labels:\n\n        app: checkout\n\n    spec:\n\n      containers:\n\n        \u2013 name: checkout\n\n          image: checkout:2.6.1\n\n          readinessProbe:\n\n            httpGet:\n\n              path: \/healthz\n\n              port: 8080\n\n            initialDelaySeconds: 5\n<\/code><\/pre><\/div><br \/>\n<\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">How does a StatefulSet give each Pod a stable network identity, and what role does a headless Service play in that?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">StatefulSets<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Each StatefulSet Pod gets a DNS name in the form <code>&lt;pod-name&gt;.&lt;service-name&gt;.&lt;namespace&gt;.svc.cluster.local<\/code>, and that name is stable across restarts because the Pod name itself is stable. A headless Service, one created with <code>clusterIP: None<\/code>, is what makes this resolvable. Instead of load-balancing across every Pod behind one virtual IP the way a normal Service would, a headless Service returns the individual Pod IPs directly through DNS.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: v1\n\nkind: Service\n\nmetadata:\n\n  name: web\n\nspec:\n\n  clusterIP: None\n\n  selector:\n\n    app: web\n\n  ports:\n\n    \u2013 port: 5432\n\n\u2014\n\napiVersion: apps\/v1\n\nkind: StatefulSet\n\nmetadata:\n\n  name: web\n\nspec:\n\n  serviceName: web\n\n  replicas: 3\n\n  selector:\n\n    matchLabels:\n\n      app: web\n\n  template:\n\n    metadata:\n\n      labels:\n\n        app: web\n\n    spec:\n\n      containers:\n\n        \u2013 name: web\n\n          image: postgres:16\n<\/code><\/pre><\/div><\/p>\n<p>That&#8217;s the mechanism a client uses to reach <code>web-1<\/code> specifically instead of whichever Pod answers first, which matters for a primary-replica database setup where writes have to land on one particular Pod.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">How does a ClusterIP Service actually route traffic to the right Pod?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Services<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>The Service gets a stable virtual IP and selects Pods by label, which populates an Endpoints object (or EndpointSlice, the newer, more scalable version) with the real Pod IPs currently behind it. kube-proxy on every node watches the API server for changes to Services and Endpoints and programs actual packet routing, historically through iptables rules, though IPVS or an eBPF dataplane like Cilium scale better once a cluster has thousands of Services.<\/p>\n<p>When a client hits the Service&#8217;s virtual IP, the node intercepts the packet and rewrites the destination to one of the healthy Pod IPs behind it. The client never talks to a Pod IP directly, which is exactly what lets Pods die and get replaced without the client noticing anything changed.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">How does Service discovery actually work inside the cluster? What does a name like checkout.prod.svc.cluster.local resolve to?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Services<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>CoreDNS runs as a cluster-internal DNS server, and every Pod&#8217;s <code>\/etc\/resolv.conf<\/code> is configured by the kubelet to send DNS queries there by default. When a Pod looks up <code>checkout.prod.svc.cluster.local<\/code>, CoreDNS resolves it to the Service&#8217;s stable ClusterIP, not to any specific Pod. Resolution to an actual Pod happens later, at the kube-proxy layer, once a packet actually gets sent to that ClusterIP.<\/p>\n<p>The short form, just <code>checkout<\/code> from within the same namespace, works because of the search domains Kubernetes automatically appends to <code>resolv.conf<\/code>. Cross-namespace calls need at least <code>checkout.prod<\/code>. Dropping the namespace is the single most common reason &#8220;it works from this namespace but not that one&#8221; bugs show up, and it&#8217;s rarely a networking problem at all, it&#8217;s just an incomplete DNS name.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What does an Ingress do that a Service can&#039;t, and what do you need installed before an Ingress resource does anything at all?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Ingress<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A Service load-balances traffic once it&#8217;s already inside the cluster and operates at Layer 4, it doesn&#8217;t understand HTTP paths, hosts, or headers. An Ingress adds Layer 7 routing on top: host-based and path-based rules, and usually TLS termination, so one entry point can route <code>api.example.com<\/code> and <code>app.example.com<\/code> to two completely different backend Services.<\/p>\n<p>An Ingress resource by itself does nothing. It&#8217;s just a set of rules. You need an Ingress Controller actually running in the cluster (nginx-ingress and Traefik are the common ones) to read those rules and configure the real proxy that does the routing. A fresh cluster with an Ingress manifest applied and no controller installed will just sit there, rules defined, nothing happening.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: networking.k8s.io\/v1\n\nkind: Ingress\n\nmetadata:\n\n  name: app-routes\n\n  annotations:\n\n    nginx.ingress.kubernetes.io\/rewrite-target: \/\n\nspec:\n\n  rules:\n\n    \u2013 host: app.example.com\n\n      http:\n\n        paths:\n\n          \u2013 path: \/api\n\n            pathType: Prefix\n\n            backend:\n\n              service:\n\n                name: api-service\n\n                port:\n\n                  number: 80\n\n          \u2013 path: \/\n\n            pathType: Prefix\n\n            backend:\n\n              service:\n\n                name: frontend-service\n\n                port:\n\n                  number: 80\n<\/code><\/pre><\/div><br \/>\n<\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Two Ingress rules define a host and path both mapping to different backends. Which one wins, and why?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Ingress<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>The most specific path match wins, not first-defined-in-the-file order. An exact <code>pathType: Exact<\/code> match on <code>\/api\/health<\/code> beats a <code>pathType: Prefix<\/code> match on <code>\/api<\/code>, and a longer prefix beats a shorter one.<\/p>\n<p>This is a real source of confusion when two teams add rules to the same Ingress resource (or two separate Ingress resources for the same host) without checking what&#8217;s already there. Most Ingress Controllers log a warning about conflicting rules, but not all of them do, and a silent conflict routes traffic somewhere nobody expected.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">A Pod is mounting a ConfigMap as a volume, and you update the ConfigMap. Does the Pod pick up the change without a restart?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">ConfigMaps &amp; Secrets<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Usually yes, eventually. Volume-mounted ConfigMaps sync on an interval (the kubelet&#8217;s sync period, typically under a minute) so the file inside the container updates without restarting anything. Environment-variable-based ConfigMap values behave completely differently: they&#8217;re injected once at container start and never update until the Pod is recreated.<\/p>\n<p>That&#8217;s the trap. A team that switches from env vars to a mounted volume assuming &#8220;same behavior, just a different mechanism&#8221; gets surprised the first time they expect a restart-free config change and it doesn&#8217;t apply, because they never actually changed how they were consuming it.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What does marking a ConfigMap or Secret as immutable actually change, and why would you want that in production?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">ConfigMaps &amp; Secrets<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Setting <code>immutable: true<\/code> on a ConfigMap or Secret does exactly what it sounds like, any attempt to edit its data after creation gets rejected by the API server. To change a value, you create a new object, commonly with a content hash in the name, and update whatever references it, rather than editing in place.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: v1\n\nkind: ConfigMap\n\nmetadata:\n\n  name: app-config-a1b2c3\n\ndata:\n\n  LOG_LEVEL: \u201cinfo\u201d\n\nimmutable: true\n<\/code><\/pre><\/div><\/p>\n<p>Two real reasons to do this, not just caution. First, it stops an accidental edit to a shared ConfigMap from silently affecting every Deployment that references it. Second, and this one surprises people, the kubelet doesn&#8217;t need to keep watching an immutable object for changes, which measurably cuts load on the API server in clusters with thousands of ConfigMaps mounted across thousands of Pods (<a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/configmap\/#configmap-immutable\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes docs, Immutable ConfigMaps<\/a>). It&#8217;s a performance feature wearing a safety feature&#8217;s clothes.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What does a StorageClass actually do, and what&#039;s the difference between Immediate and WaitForFirstConsumer binding?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Storage<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A StorageClass is a template for dynamically provisioning PVs on demand, instead of an admin pre-creating a pool of PVs by hand and hoping the sizes match what gets requested. It defines the provisioner (which storage backend to use), parameters like disk type, and a reclaim policy for what happens to the underlying storage once the PVC is deleted.<\/p>\n<p>Immediate binding provisions the volume as soon as the PVC is created, before any Pod using it is even scheduled. WaitForFirstConsumer delays provisioning until a Pod actually references the PVC, which matters in multi-zone clusters, an Immediate-bound volume can end up in a different availability zone than the Pod that needs it, and the Pod will sit unschedulable forever because storage and compute can&#8217;t cross zones.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: storage.k8s.io\/v1\n\nkind: StorageClass\n\nmetadata:\n\n  name: fast-ssd\n\nprovisioner: ebs.csi.aws.com\n\nparameters:\n\n  type: gp3\n\nreclaimPolicy: Delete\n\nvolumeBindingMode: WaitForFirstConsumer\n<\/code><\/pre><\/div><br \/>\n<\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s the difference between a ResourceQuota and a LimitRange, and when would you need both in the same namespace?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Resource Quotas<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A ResourceQuota caps the aggregate resource consumption across an entire namespace, total CPU requests can&#8217;t exceed 20 cores, total Pod count can&#8217;t exceed 50. A LimitRange sets defaults, minimums, and maximums for individual containers, so a container that doesn&#8217;t specify its own requests or limits gets a sane default instead of none at all.<\/p>\n<p>You need both together the moment a namespace has a ResourceQuota that requires every Pod to specify requests and limits (which most quotas do), because without a LimitRange providing defaults, any Pod submitted without explicit requests gets rejected outright rather than falling back to something reasonable.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What are resource requests and limits actually used for, and how do they determine a Pod&#039;s QoS class?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">QoS Classes<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A request is what the scheduler uses to decide which node has room for a Pod, it&#8217;s a reservation, not a cap. A limit is the real ceiling: exceed it on memory and the container gets OOMKilled, exceed it on CPU and the container gets throttled, not killed. Kubernetes derives a QoS class from the relationship between the two. <code>Guaranteed<\/code> applies when every container&#8217;s requests equal its limits for both CPU and memory. <code>Burstable<\/code> applies when at least one request is set but doesn&#8217;t equal its limit. <code>BestEffort<\/code> applies when neither is set at all.<\/p>\n<p>QoS class decides eviction order under node memory pressure, and it&#8217;s not close: BestEffort Pods get evicted first, then Burstable ones exceeding their requests, and Guaranteed Pods last, in practice almost never. A database Pod without explicit requests and limits is BestEffort by default, which means it&#8217;s first in line to get killed the moment a noisy neighbor Pod on the same node starts eating memory, regardless of how important that database actually is.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s the difference between a taint and a node selector, and why can&#039;t you use a nodeSelector to keep pods off a node?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Scheduling<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A nodeSelector is opt-in from the Pod&#8217;s side: it says &#8220;only schedule me on nodes with this label,&#8221; and Pods that don&#8217;t specify it can still land anywhere. A taint is opt-out from the node&#8217;s side: it repels every Pod by default, and only Pods with a matching toleration are allowed to schedule there.<\/p>\n<p>That&#8217;s the whole reason taints exist. A nodeSelector can steer Pods toward a node, but it can&#8217;t stop a Pod that doesn&#8217;t care about labels at all from landing there. Taints are how you dedicate a node (a GPU node, say) to only the workloads that explicitly tolerate being scheduled on it.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">NoSchedule, PreferNoSchedule, and NoExecute, what&#039;s the actual behavioral difference between the three taint effects?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Scheduling<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>NoSchedule blocks new Pods from being scheduled there unless they tolerate it, but Pods already running on the node when the taint is added stay put. PreferNoSchedule is the soft version, the scheduler tries to avoid the node but will still place a Pod there if nothing else fits.<\/p>\n<p>NoExecute is the one people forget: it evicts Pods that are already running and don&#8217;t tolerate the taint, not just new ones. Add a NoExecute taint to a node that&#8217;s about to be drained for maintenance, and every non-tolerating Pod already on it gets kicked off immediately, which is exactly the behavior you want for planned node decommissioning.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\ntolerations:\n\n  \u2013 key: \u201cdedicated\u201d\n\n    operator: \u201cEqual\u201d\n\n    value: \u201cgpu\u201d\n\n    effect: \u201cNoSchedule\u201d\n\n  \u2013 key: \u201cnode.kubernetes.io\/unreachable\u201d\n\n    operator: \u201cExists\u201d\n\n    effect: \u201cNoExecute\u201d\n\n    tolerationSeconds: 300\n<\/code><\/pre><\/div><br \/>\n<\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What&#039;s a PodDisruptionBudget, and what problem does it actually solve during a voluntary node drain?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Disruption Budgets<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A PodDisruptionBudget (PDB) sets a floor, a minimum number or percentage of Pods from a given selector that must stay available, that voluntary disruptions aren&#8217;t allowed to cross. <code>kubectl drain<\/code>, cluster autoscaler scale-downs, and node upgrades all check the PDB before evicting a Pod. If evicting one would violate the budget, the eviction is refused, not queued, refused, until enough replacement Pods come up elsewhere.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: policy\/v1\n\nkind: PodDisruptionBudget\n\nmetadata:\n\n  name: checkout-pdb\n\nspec:\n\n  minAvailable: 2\n\n  selector:\n\n    matchLabels:\n\n      app: checkout\n<\/code><\/pre><\/div><\/p>\n<p>PDBs only cover voluntary disruptions, things an operator or controller chooses to do. They do nothing for involuntary ones, a node hardware failure or a kernel panic doesn&#8217;t check a PDB first, it just happens. That distinction is worth stating explicitly if asked, because &#8220;does a PDB protect me during an outage&#8221; and &#8220;does a PDB protect me during a planned drain&#8221; have different answers.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Why is running HPA and VPA on the same CPU metric for the same workload usually a bad idea?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">VPA<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>HPA changes replica count in response to CPU usage. VPA changes each container&#8217;s CPU request and limit in response to the same observed usage. Point both at CPU for the same workload and they can fight: VPA resizes a Pod&#8217;s request upward, which changes the per-Pod CPU utilization percentage HPA is watching, which triggers HPA to scale differently, which changes aggregate usage per Pod again.<\/p>\n<p>The common fix is splitting responsibilities: VPA in &#8220;Off&#8221; or recommendation-only mode just to size requests sensibly, HPA doing the actual live scaling. Running both in fully automatic mode on the same metric is the kind of setup that looks fine in a demo and gets weird two weeks into real traffic.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">What problem does a CNI plugin actually solve, and why can&#039;t Kubernetes just use regular Docker networking?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">CNI<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Kubernetes assumes a flat network model: every Pod gets its own IP, and every Pod can reach every other Pod&#8217;s IP directly, no NAT, regardless of which node they&#8217;re on. Docker&#8217;s default bridge networking doesn&#8217;t give you that across multiple hosts out of the box.<\/p>\n<p>A CNI plugin (Calico, Cilium, and Flannel are the common ones) is what actually implements that flat network across nodes, wiring up routes or an overlay so cross-node Pod-to-Pod traffic just works. Different CNIs make different tradeoffs, Cilium&#8217;s eBPF dataplane, for instance, scales noticeably better than iptables-based routing once a cluster has thousands of Services, but the core contract, every Pod reachable from every other Pod, is the same regardless of which one you pick.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">You wrote a NetworkPolicy to block traffic between two namespaces, and it&#039;s not doing anything. What&#039;s the first thing to check?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">CNI<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Whether your CNI plugin actually enforces NetworkPolicy at all. This is the single most common cause of a &#8220;policy that does nothing.&#8221; Flannel, for example, doesn&#8217;t enforce NetworkPolicies by default, it just handles the networking, not policy enforcement, so a NetworkPolicy object sits there parsed and accepted by the API server but never actually applied to traffic.<\/p>\n<p>Calico, Cilium, and most enterprise-grade CNIs do enforce it. If you&#8217;re on one of those and it&#8217;s still not working, the next check is whether the policy&#8217;s selector actually matches the Pods you think it does, a label typo in the selector is a close second on the list of causes.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">A ServiceAccount&#039;s pod can list Secrets across the entire cluster. Is that a Kubernetes default, and how would you fix it?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">RBAC<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>No, it&#8217;s not a default, Kubernetes ships with fairly restrictive out-of-the-box RBAC. Cluster-wide Secret read access almost always traces back to someone binding a permissive ClusterRole (or worse, <code>cluster-admin<\/code>) to a ServiceAccount because a narrower Role would&#8217;ve taken more time to write correctly.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: rbac.authorization.k8s.io\/v1\n\nkind: Role\n\nmetadata:\n\n  namespace: payments\n\n  name: secret-reader\n\nrules:\n\n  \u2013 apiGroups: [\u201d\u201d]\n\n    resources: [\u201dsecrets\u201d]\n\n    verbs: [\u201dget\u201d, \u201clist\u201d]\n\n\u2014\n\napiVersion: rbac.authorization.k8s.io\/v1\n\nkind: RoleBinding\n\nmetadata:\n\n  name: secret-reader-binding\n\n  namespace: payments\n\nsubjects:\n\n  \u2013 kind: ServiceAccount\n\n    name: payments-api\n\n    namespace: payments\n\nroleRef:\n\n  kind: Role\n\n  name: secret-reader\n\n  apiGroup: rbac.authorization.k8s.io\n<\/code><\/pre><\/div><\/p>\n<p>Replace the ClusterRoleBinding with a namespaced Role and RoleBinding scoped to exactly the Secrets that ServiceAccount needs, and audit what&#8217;s currently bound with <code>kubectl get clusterrolebindings -o wide<\/code> before assuming the fix worked.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Pod is Running but 0\/1 ready and never receiving traffic. Walk through your debugging steps.<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Troubleshooting<\/span><span class=\"iq-badge iq-badge--medium\">Medium<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Start with <code>kubectl describe pod<\/code>, the readiness probe&#8217;s failure reason is usually right there in the events section. If the probe&#8217;s an HTTP check, confirm the path and port actually match what the app listens on, a surprising number of these bugs are just a probe pointed at the wrong port after a config change.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">bash<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-bash\">\n\nkubectl describe pod checkout-7f8b9c-xk2q9 -n prod\n\nkubectl logs checkout-7f8b9c-xk2q9 -n prod\n\nkubectl exec -it checkout-7f8b9c-xk2q9 -n prod \u2014 curl -s localhost:8080\/ready\n\nkubectl get endpoints checkout -n prod\n<\/code><\/pre><\/div><\/p>\n<p>If the app looks healthy from inside the container but the Pod&#8217;s still not in the Service&#8217;s Endpoints, check the label selector on the Service against the Pod&#8217;s actual labels next, a mismatched label is invisible in most dashboards but obvious the moment you diff the two.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-dsec iq-dsec--hard\"><div class=\"iq-dsec__row\"><h2 class=\"iq-dsec__h\" id=\"hard\"><span class=\"iq-dsec__dot\" aria-hidden=\"true\"><\/span>Hard questions<\/h2><span class=\"iq-dsec__n\">15<\/span><\/div><div class=\"iq-dsec__bar\" aria-hidden=\"true\"><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Why does etcd need a quorum, and what happens to a 5-node etcd cluster if 3 members die at once?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">etcd<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>etcd uses the Raft consensus algorithm, and Raft requires a strict majority of members to agree before a write is considered committed. For a 5-node cluster, quorum is 3. Losing exactly 2 members still leaves 3 alive, which is a majority, so the cluster keeps accepting writes.<\/p>\n<p>Lose 3 at once and you&#8217;re down to 2 members, below the majority of 3. The cluster can&#8217;t elect a leader or commit new writes at all. Existing Pods that are already scheduled keep running (kubelets don&#8217;t need etcd to keep containers alive), but nothing new gets scheduled, no Deployment can roll out, and the API server itself starts rejecting most write requests until quorum is restored.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">A rollout to a new image version is failing pods into CrashLoopBackOff, but kubectl rollout status just hangs. What&#039;s happening, and how do you get out of it?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Rollouts<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>The new ReplicaSet&#8217;s Pods keep crashing before passing their readiness probe, so the Deployment controller never advances past <code>maxUnavailable<\/code>, it&#8217;s protecting you from a bad rollout, not stuck by accident. <code>kubectl rollout status<\/code> will sit there waiting forever because &#8220;done&#8221; never arrives.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">bash<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-bash\">\n\nkubectl rollout status deployment\/checkout -n prod\n\nkubectl get pods -n prod -l app=checkout\n\nkubectl logs &lt;pod-name&gt; -n prod \u2013previous\n\nkubectl rollout undo deployment\/checkout -n prod\n<\/code><\/pre><\/div><\/p>\n<p>Check <code>kubectl logs --previous<\/code> on one of the crashing Pods first, most of the time it&#8217;s a config problem or a bad dependency in the new image. If it&#8217;s not a quick fix, <code>kubectl rollout undo<\/code> rolls back to the last good revision immediately. Debug the actual cause after the bleeding&#8217;s stopped, not during.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">You scale a StatefulSet down from 5 replicas to 3. What happens to the PVCs that belonged to web-3 and web-4?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">StatefulSets<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>By default, nothing. The Pods terminate, but their PersistentVolumeClaims stay behind untouched. Scale back up to 5 and the new <code>web-3<\/code> and <code>web-4<\/code> Pods reattach to the exact same PVCs they had before, same data, not a fresh volume. That&#8217;s deliberate. A StatefulSet assumes scaling down is often temporary, not a signal to throw the data away.<\/p>\n<p>It surprises people in the other direction too: deleting a StatefulSet entirely, not just scaling it down, still leaves the PVCs behind unless you delete them separately, which is a safety net right up until it&#8217;s the reason a namespace teardown didn&#8217;t actually free the storage everyone assumed it would. Kubernetes 1.27 added an optional <code>persistentVolumeClaimRetentionPolicy<\/code> field if you want PVCs deleted automatically on scale-down or StatefulSet deletion instead of the conservative default.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\nspec:\n\n  persistentVolumeClaimRetentionPolicy:\n\n    whenScaled: Delete\n\n    whenDeleted: Retain\n<\/code><\/pre><\/div><br \/>\n<\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">A PVC has been stuck in Pending for eleven minutes. What are you checking first?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Storage<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Start with <code>kubectl describe pvc<\/code>, the events section almost always names the actual problem: no StorageClass matches what was requested, the requested size exceeds what any available PV or the provisioner&#8217;s quota allows, or (with WaitForFirstConsumer) there&#8217;s simply no Pod referencing it yet, which looks identical to a real problem but isn&#8217;t one.<\/p>\n<p>If a provisioner is involved, check its controller Pod logs next, a misconfigured cloud IAM permission preventing the CSI driver from actually creating the underlying disk is a common cause that <code>describe pvc<\/code> alone won&#8217;t always surface clearly.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Explain node affinity versus pod anti-affinity, and give a real scenario where you&#039;d reach for each.<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Scheduling<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Node affinity steers Pods toward (or away from) nodes based on node labels, like preferring nodes in a specific availability zone or with an SSD-labeled node pool. Pod anti-affinity steers Pods away from other Pods based on their labels, most commonly used to spread replicas of the same Deployment across different nodes or zones so a single node failure doesn&#8217;t take out every replica at once.<\/p>\n<p>Both come in <code>requiredDuringSchedulingIgnoredDuringExecution<\/code> (a hard rule, the scheduler won&#8217;t place the Pod if it can&#8217;t satisfy this) and <code>preferredDuringSchedulingIgnoredDuringExecution<\/code> (best-effort) flavors. I&#8217;ve seen more outages caused by making pod anti-affinity required, and then the cluster running out of eligible nodes during a scale-up, than by any anti-affinity misconfiguration in the other direction. Preferred is usually the safer default unless you genuinely need the hard guarantee.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Can a node show as fully allocated by the scheduler and still have plenty of free RAM sitting idle? Walk through why.<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Scheduling<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Yes, and it&#8217;s one of the more counterintuitive things about how the scheduler bin-packs. It sums up the <em>requests<\/em> of every Pod already placed on a node, not their actual live usage, and compares that sum against the node&#8217;s allocatable capacity. A node can be scheduling-full on paper, every Pod&#8217;s requested memory adding up to the node&#8217;s capacity, while every Pod is actually using a fraction of what it requested, leaving real RAM sitting unused that the scheduler will never place a new Pod into.<\/p>\n<p>This is exactly why teams that set requests well above real usage &#8220;just to be safe&#8221; end up with clusters that look 90% allocated in a dashboard but run at 30% actual utilization, and adding nodes doesn&#8217;t fix it, tightening requests to match real usage does. It&#8217;s also why VPA in recommendation mode is worth running even if you never turn on its automatic resizing, seeing the gap between requested and actual usage is often the first time a team notices how much headroom it&#8217;s been paying for.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">An HPA target is set to 50% CPU, but replica count is oscillating between 3 and 8 every couple minutes. What&#039;s likely wrong?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">HPA<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Most likely, the stabilization window is too short, or missing entirely, so a brief spike scales up, the spike passes, it scales back down, and the next spike starts the cycle over. HPA&#8217;s default scale-down stabilization window is 5 minutes, but if that&#8217;s been overridden to something small, or the metrics being sampled are genuinely noisy, this exact flapping pattern shows up.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: autoscaling\/v2\n\nkind: HorizontalPodAutoscaler\n\nmetadata:\n\n  name: checkout-hpa\n\nspec:\n\n  scaleTargetRef:\n\n    apiVersion: apps\/v1\n\n    kind: Deployment\n\n    name: checkout\n\n  minReplicas: 3\n\n  maxReplicas: 10\n\n  metrics:\n\n    \u2013 type: Resource\n\n      resource:\n\n        name: cpu\n\n        target:\n\n          type: Utilization\n\n          averageUtilization: 50\n\n  behavior:\n\n    scaleDown:\n\n      stabilizationWindowSeconds: 300\n\n    scaleUp:\n\n      stabilizationWindowSeconds: 60\n<\/code><\/pre><\/div><\/p>\n<p>Widening the stabilization window, and checking whether the workload&#8217;s CPU usage is genuinely spiky versus an artifact of too few replicas averaging out the noise, are the two things to check before assuming the HPA config itself is broken.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Design least-privilege RBAC for a CI pipeline that only needs to deploy to one namespace. What would you actually grant it?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">RBAC<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>A ServiceAccount dedicated to the pipeline, never a shared one. A Role scoped to that single namespace with only the verbs it actually uses, typically <code>get<\/code>, <code>list<\/code>, <code>update<\/code>, and <code>patch<\/code> on Deployments (for the rollout), plus maybe <code>get<\/code> on Pods for status checks. No <code>delete<\/code> unless the pipeline genuinely tears things down. No access to Secrets or RBAC objects themselves.<\/p>\n<p>I&#8217;ve seen more CI pipelines granted <code>cluster-admin<\/code> &#8220;temporarily, to get it working&#8221; than pipelines that ever got that permission scoped back down afterward. The honest answer to &#8220;why is this pipeline so over-permissioned&#8221; is almost always deadline pressure the first time it was set up, not a deliberate decision.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Beyond RBAC, what does an admission controller actually enforce, and what&#039;s the practical difference between a mutating and a validating webhook?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Admission Control<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>RBAC answers &#8220;is this user allowed to make this request at all.&#8221; Admission control runs after that check passes and before the object is persisted to etcd, and it answers a different question: even though you&#8217;re allowed to submit this, does it meet the cluster&#8217;s policy. A mutating admission webhook can change the object on the way in, injecting a sidecar, setting a default resource limit a team forgot. A validating webhook can only accept or reject it, no edits, and validating webhooks always run after every mutating webhook has already had a chance to modify the object.<\/p>\n<p>Kyverno and OPA Gatekeeper are the two tools most commonly built on this. Rules like &#8220;every Deployment must set resource limits&#8221; or &#8220;no image from an untrusted registry&#8221; get enforced here, not in RBAC, because RBAC has no concept of what a Pod spec actually contains (<a href=\"https:\/\/kubernetes.io\/docs\/reference\/access-authn-authz\/admission-controllers\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes docs, Admission Controllers<\/a>). I&#8217;ve watched candidates confidently answer the RBAC question and then go quiet the moment &#8220;how do you stop someone from deploying a container running as root&#8221; comes up, because the real answer lives outside RBAC entirely.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Pod Security Policy was removed in Kubernetes 1.25. What replaced it, and what do the Privileged, Baseline, and Restricted levels actually enforce?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Pod Security<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Pod Security Admission (PSA), a built-in admission controller, replaced PodSecurityPolicy, and it&#8217;s applied per namespace with a label rather than a separate cluster-wide policy object. Privileged enforces nothing, it exists mostly so infrastructure namespaces running genuinely privileged workloads, a CNI plugin, say, have somewhere to opt out cleanly. Baseline blocks the most obviously dangerous settings, running as a privileged container, using the host&#8217;s network or PID namespace, while still allowing a fairly permissive default Pod spec otherwise. Restricted is the hardened tier: no root user allowed, no privilege escalation, a required seccomp profile, and dropped Linux capabilities by default.<\/p>\n<p>The label goes directly on the namespace, and you can set warn or audit modes alongside enforce, which is the practical rollout path, run Restricted in warn mode against real traffic for a couple weeks, see what actually breaks, before flipping it to enforce and finding out the hard way (<a href=\"https:\/\/kubernetes.io\/docs\/concepts\/security\/pod-security-admission\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes docs, Pod Security Admission<\/a>). Most teams I&#8217;ve seen skip the warn phase entirely and pay for it with a production incident the day they turn Restricted on for real.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: v1\n\nkind: Namespace\n\nmetadata:\n\n  name: prod\n\n  labels:\n\n    pod-security.kubernetes.io\/enforce: restricted\n\n    pod-security.kubernetes.io\/warn: restricted\n<\/code><\/pre><\/div><br \/>\n<\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">A liveness probe with a 2-second timeout is restarting a pod that&#039;s healthy but slow to respond under load. Walk through the fix.<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Probes<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>The probe timeout is shorter than the app&#8217;s actual response time under real load, so Kubernetes concludes the container is dead and restarts it, and the restart itself adds more load to the remaining Pods, which makes their probes slower too. It&#8217;s a self-inflicted outage that looks identical to a genuine crash from the outside.<\/p>\n<p>Fix: raise the liveness timeout and failure threshold to something realistic under actual production load, not the load from a quiet staging environment, and separate the liveness check (something cheap and internal, &#8220;is my process responding at all&#8221;) from a readiness or deep health check that might touch a database or downstream dependency. A liveness probe that checks database connectivity is a common mistake, a slow database now restarts your application containers too.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Exit code 137 vs. 143, what&#039;s the actual difference and how do you tell which one you&#039;re looking at?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Troubleshooting<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>137 is 128 plus signal 9 (SIGKILL), almost always OOMKilled in a Kubernetes context, the container exceeded its memory limit and the kernel killed it with no chance to clean up. 143 is 128 plus signal 15 (SIGTERM), a graceful shutdown request, usually from a Pod deletion or rolling update, that the app either handled and exited, or ignored until the grace period ran out and got a 137 anyway.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">bash<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-bash\">\n\nkubectl get pod checkout-7f8b9c-xk2q9 -n prod -o jsonpath=&#039;{.status.containerStatuses[0].lastState.terminated.reason}\u2019\n\nkubectl get pod checkout-7f8b9c-xk2q9 -n prod -o jsonpath=&#039;{.status.containerStatuses[0].lastState.terminated.exitCode}\u2019\n<\/code><\/pre><\/div><\/p>\n<p><code>kubectl describe pod<\/code> usually names the reason directly (OOMKilled shows up as text, not just a number), but the exit code confirms it when the reason field is empty or ambiguous. A 137 means go raise the memory limit or find the leak. A 143 that keeps recurring on every deploy usually means the app isn&#8217;t handling SIGTERM at all, and is just getting force-killed once its grace period expires.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">A Pod keeps getting OOMKilled even though its average memory usage, based on your dashboards, sits well under the limit. What&#039;s actually going on?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Troubleshooting<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Averages hide spikes. cgroups enforce the memory limit instantly, the moment usage crosses it even for a fraction of a second, the kernel kills the container. It doesn&#8217;t care what the average looked like over the last hour. A JVM doing a large garbage collection pass, a request handler loading an oversized payload into memory, or a batch job processing one unusually large record can all spike past the limit briefly and get killed, while every dashboard sampled at 30-second intervals shows a flat, comfortable line.<\/p>\n<p>The fix isn&#8217;t raising the limit blindly, it&#8217;s checking the actual memory ceiling the process needs during its worst moment, not its typical moment. <code>kubectl top pod<\/code> polled frequently, or better, the container&#8217;s own memory metrics scraped at a few-second interval, will usually show the spike a dashboard built for capacity planning was never sampling fast enough to catch.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">A Deployment shows 3 of 3 replicas ready in kubectl get deployments, but users are reporting 500s. Where do you look?<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Troubleshooting<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>Ready doesn&#8217;t mean correct. All three Pods can be passing a shallow readiness probe (a plain <code>\/healthz<\/code> that just checks the process is up) while a downstream dependency, a database, a config value, a feature flag, is actually broken for all three at once. Since every replica shares the same bad state, this looks nothing like a typical single-Pod failure.<\/p>\n<p>Check application logs across all three Pods for the actual error, not just their health status. Then check what changed recently that all three would share: a ConfigMap update, a Secret rotation, a downstream service deploy, a database migration. The bug almost never lives in &#8220;which Pod,&#8221; it lives in whatever all three Pods have in common.<\/p>\n<p><\/div><\/div><\/div>\n<div class=\"iq-qa\"><button class=\"iq-qa__q\" type=\"button\" aria-expanded=\"false\"><span class=\"iq-qa__qtext\">Two containers in the same Pod need to share files. Walk through how you&#039;d set that up.<\/span><span class=\"iq-qa__meta\"><span class=\"iq-qa__tag\">Multi-Container Pods<\/span><span class=\"iq-badge iq-badge--hard\">Hard<\/span><span class=\"iq-qa__chev\" aria-hidden=\"true\"><\/span><\/span><\/button><div class=\"iq-qa__a\"><div class=\"iq-qa__a-inner\"><\/p>\n<p>An <code>emptyDir<\/code> volume, declared once at the Pod level and mounted into both containers, is the standard fix. It&#8217;s created fresh when the Pod is scheduled to a node and deleted when the Pod is removed, so it&#8217;s not durable storage, just a shared scratch space for the Pod&#8217;s lifetime.<\/p>\n<p><div class=\"iq-code not-prose\"><div class=\"iq-code__bar\"><span class=\"iq-code__lang\">yaml<\/span><button class=\"iq-code__copy\" type=\"button\">Copy<\/button><\/div><pre><code class=\"language-yaml\">\n\napiVersion: v1\n\nkind: Pod\n\nmetadata:\n\n  name: shared-scratch\n\nspec:\n\n  containers:\n\n    \u2013 name: writer\n\n      image: writer:1.0\n\n      volumeMounts:\n\n        \u2013 name: shared-data\n\n          mountPath: \/data\n\n    \u2013 name: reader\n\n      image: reader:1.0\n\n      volumeMounts:\n\n        \u2013 name: shared-data\n\n          mountPath: \/data\n\n          readOnly: true\n\n  volumes:\n\n    \u2013 name: shared-data\n\n      emptyDir: {}\n<\/code><\/pre><\/div><\/p>\n<p>The detail interviewers listen for: emptyDir survives a container restart within the same Pod (Kubernetes doesn&#8217;t delete it just because one container crashed and got restarted), but it&#8217;s gone the moment the whole Pod is rescheduled or deleted. Candidates who assume it&#8217;s persistent storage are going to have a bad time in production.<\/p>\n<p><\/div><\/div><\/div>\n<h2>How to prepare for a Kubernetes interview in 2026<\/h2>\n<p>Skip another round of flashcards on API object fields. Spin up a local cluster (kind or minikube, either is fine) and deliberately break it: set a memory limit too low and watch the OOMKill, remove a readiness probe and watch traffic route to a Pod that isn&#8217;t actually ready yet, taint a node and see what happens to Pods that don&#8217;t tolerate it. Fixing your own mess teaches the mental model faster than reading about someone else&#8217;s incident does.<\/p>\n<p>Across mock interview sessions run through LastRoundAI tagged Kubernetes, DevOps, or SRE, the stumble that shows up most isn&#8217;t a definitions question. It&#8217;s the second follow-up on a scenario, &#8220;okay, and then what do you check next,&#8221; where a candidate who nailed the first answer runs out of things to say. We don&#8217;t have a clean number to put on that, only that it comes up often enough across sessions to be worth calling out here. If you can only practice one thing before a real loop, practice narrating a debugging path three steps deep instead of stopping after the first plausible guess.<\/p>\n<h2>Debugging out loud is the actual interview<\/h2>\n<p>Reading the answer to a CrashLoopBackOff question is not the same as defending it live once an interviewer changes one variable on you. <a href=\"\/products\/mock-interviews\">LastRoundAI&#8217;s mock interview mode<\/a> runs Kubernetes and platform-engineering rounds with real-time follow-ups instead of a static question bank, and the free plan includes 15 credits a month that reset monthly. Starter is $19\/mo if a handful of sessions a month isn&#8217;t enough.<\/p>\n<p>If landing enough interviews is the slower part of the job hunt right now, rather than passing them once you&#8217;re in the room, <a href=\"\/products\/auto-apply\">Auto-Apply<\/a> matches and applies to DevOps, SRE, and platform roles for you, 10 applications a month on the free plan, up to 400 a month on Ultimate, with every application held in a review queue until you approve it. Nothing goes out on your behalf without you looking at it first. There&#8217;s no native mobile app yet, just a desktop app and a browser that works fine on a phone.<\/p>\n<p>Questions about either product go to contact@lastroundai.com. That&#8217;s the only inbox we check.<\/p>\n<div class=\"iq-sources not-prose\"><div class=\"iq-sources__title\">Sources &amp; further reading<\/div><ul class=\"iq-sources__list\"><li><a href=\"https:\/\/www.cncf.io\/announcements\/2026\/01\/20\/kubernetes-established-as-the-de-facto-operating-system-for-ai-as-production-use-hits-82-in-2025-cncf-annual-cloud-native-survey\/\" target=\"_blank\" rel=\"nofollow noopener\">CNCF: Kubernetes Established as the De Facto Operating System for AI, 2025 Annual Cloud Native Survey<\/a><\/li><li><a href=\"https:\/\/kubernetes.io\/docs\/concepts\/overview\/components\/\" target=\"_blank\" rel=\"nofollow noopener\">Kubernetes Docs: Kubernetes Components<\/a><\/li><li><a href=\"https:\/\/kubernetes.io\/docs\/concepts\/workloads\/pods\/sidecar-containers\/\" target=\"_blank\" rel=\"nofollow noopener\">Kubernetes Docs: Sidecar Containers<\/a><\/li><li><a href=\"https:\/\/kubernetes.io\/docs\/tasks\/run-application\/horizontal-pod-autoscale\/\" target=\"_blank\" rel=\"nofollow noopener\">Kubernetes Docs: Horizontal Pod Autoscaling<\/a><\/li><li><a href=\"https:\/\/kubernetes.io\/docs\/reference\/access-authn-authz\/admission-controllers\/\" target=\"_blank\" rel=\"nofollow noopener\">Kubernetes Docs: Admission Controllers<\/a><\/li><li><a href=\"https:\/\/kubernetes.io\/docs\/concepts\/security\/pod-security-admission\/\" target=\"_blank\" rel=\"nofollow noopener\">Kubernetes Docs: Pod Security Admission<\/a><\/li><li><a href=\"https:\/\/kubernetes.io\/docs\/concepts\/configuration\/configmap\/#configmap-immutable\" target=\"_blank\" rel=\"nofollow noopener\">Kubernetes Docs: Immutable ConfigMaps and Secrets<\/a><\/li><\/ul><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Kubernetes production use among container users hit 82 percent in CNCF&#8217;s January 2026 Annual Cloud Native Survey, up from 66 percent just two years earlier (CNCF, 2026). That&#8217;s a fast jump for a tool most engineering teams were still calling &#8220;too much for us&#8221; as recently as 2022. It shows up directly in interviews now:&#8230;<\/p>\n","protected":false},"author":4,"featured_media":1711,"comment_status":"open","ping_status":"closed","template":"","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"tags":[],"class_list":["post-1161","iq","type-iq","status-publish","has-post-thumbnail","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Kubernetes Interview Questions (2026) | LastRoundAI<\/title>\n<meta name=\"description\" content=\"39 real Kubernetes interview questions covering architecture, Pods, Deployments, RBAC, scaling, and troubleshooting, with answers built for 2026 loops.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/lastroundai.com\/interview-questions\/kubernetes\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Kubernetes Interview Questions (2026) | LastRoundAI\" \/>\n<meta property=\"og:description\" content=\"39 real Kubernetes interview questions covering architecture, Pods, Deployments, RBAC, scaling, and troubleshooting, with answers built for 2026 loops.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/lastroundai.com\/interview-questions\/kubernetes\" \/>\n<meta property=\"og:site_name\" content=\"LastRound AI\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-19T03:53:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/lastroundai.com\/blog\/wp-content\/uploads\/2026\/07\/iq-kubernetes-og.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"28 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/lastroundai.com\\\/interview-questions\\\/kubernetes\",\"url\":\"https:\\\/\\\/lastroundai.com\\\/interview-questions\\\/kubernetes\",\"name\":\"Kubernetes Interview Questions (2026) | LastRoundAI\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/lastroundai.com\\\/interview-questions\\\/kubernetes#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/lastroundai.com\\\/interview-questions\\\/kubernetes#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/iq-kubernetes-og.png\",\"datePublished\":\"2026-07-11T03:55:15+00:00\",\"dateModified\":\"2026-07-19T03:53:29+00:00\",\"description\":\"39 real Kubernetes interview questions covering architecture, Pods, Deployments, RBAC, scaling, and troubleshooting, with answers built for 2026 loops.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/lastroundai.com\\\/interview-questions\\\/kubernetes#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/lastroundai.com\\\/interview-questions\\\/kubernetes\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/lastroundai.com\\\/interview-questions\\\/kubernetes#primaryimage\",\"url\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/iq-kubernetes-og.png\",\"contentUrl\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/iq-kubernetes-og.png\",\"width\":1200,\"height\":630,\"caption\":\"Kubernetes interview questions \u2014 LastRoundAI\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/lastroundai.com\\\/interview-questions\\\/kubernetes#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/lastroundai.com\\\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Interview Questions\",\"item\":\"https:\\\/\\\/lastroundai.com\\\/interview-questions\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Kubernetes Interview Questions (2026): 39 Most Asked, With Answers\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/\",\"name\":\"LastRound AI\",\"description\":\"Interview Assistant prep, tech careers and AI tools\",\"publisher\":{\"@id\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/#organization\",\"name\":\"LastRound AI\",\"url\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/lastroundai-transprant-logo-optimized-BxEo2Wtq.png\",\"contentUrl\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/06\\\/lastroundai-transprant-logo-optimized-BxEo2Wtq.png\",\"width\":400,\"height\":400,\"caption\":\"LastRound AI\"},\"image\":{\"@id\":\"https:\\\/\\\/lastroundai.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Kubernetes Interview Questions (2026) | LastRoundAI","description":"39 real Kubernetes interview questions covering architecture, Pods, Deployments, RBAC, scaling, and troubleshooting, with answers built for 2026 loops.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/lastroundai.com\/interview-questions\/kubernetes","og_locale":"en_US","og_type":"article","og_title":"Kubernetes Interview Questions (2026) | LastRoundAI","og_description":"39 real Kubernetes interview questions covering architecture, Pods, Deployments, RBAC, scaling, and troubleshooting, with answers built for 2026 loops.","og_url":"https:\/\/lastroundai.com\/interview-questions\/kubernetes","og_site_name":"LastRound AI","article_modified_time":"2026-07-19T03:53:29+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/lastroundai.com\/blog\/wp-content\/uploads\/2026\/07\/iq-kubernetes-og.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"28 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/lastroundai.com\/interview-questions\/kubernetes","url":"https:\/\/lastroundai.com\/interview-questions\/kubernetes","name":"Kubernetes Interview Questions (2026) | LastRoundAI","isPartOf":{"@id":"https:\/\/lastroundai.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/lastroundai.com\/interview-questions\/kubernetes#primaryimage"},"image":{"@id":"https:\/\/lastroundai.com\/interview-questions\/kubernetes#primaryimage"},"thumbnailUrl":"https:\/\/lastroundai.com\/blog\/wp-content\/uploads\/2026\/07\/iq-kubernetes-og.png","datePublished":"2026-07-11T03:55:15+00:00","dateModified":"2026-07-19T03:53:29+00:00","description":"39 real Kubernetes interview questions covering architecture, Pods, Deployments, RBAC, scaling, and troubleshooting, with answers built for 2026 loops.","breadcrumb":{"@id":"https:\/\/lastroundai.com\/interview-questions\/kubernetes#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/lastroundai.com\/interview-questions\/kubernetes"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/lastroundai.com\/interview-questions\/kubernetes#primaryimage","url":"https:\/\/lastroundai.com\/blog\/wp-content\/uploads\/2026\/07\/iq-kubernetes-og.png","contentUrl":"https:\/\/lastroundai.com\/blog\/wp-content\/uploads\/2026\/07\/iq-kubernetes-og.png","width":1200,"height":630,"caption":"Kubernetes interview questions \u2014 LastRoundAI"},{"@type":"BreadcrumbList","@id":"https:\/\/lastroundai.com\/interview-questions\/kubernetes#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/lastroundai.com\/blog"},{"@type":"ListItem","position":2,"name":"Interview Questions","item":"https:\/\/lastroundai.com\/interview-questions"},{"@type":"ListItem","position":3,"name":"Kubernetes Interview Questions (2026): 39 Most Asked, With Answers"}]},{"@type":"WebSite","@id":"https:\/\/lastroundai.com\/blog\/#website","url":"https:\/\/lastroundai.com\/blog\/","name":"LastRound AI","description":"Interview Assistant prep, tech careers and AI tools","publisher":{"@id":"https:\/\/lastroundai.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/lastroundai.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/lastroundai.com\/blog\/#organization","name":"LastRound AI","url":"https:\/\/lastroundai.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/lastroundai.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/lastroundai.com\/blog\/wp-content\/uploads\/2026\/06\/lastroundai-transprant-logo-optimized-BxEo2Wtq.png","contentUrl":"https:\/\/lastroundai.com\/blog\/wp-content\/uploads\/2026\/06\/lastroundai-transprant-logo-optimized-BxEo2Wtq.png","width":400,"height":400,"caption":"LastRound AI"},"image":{"@id":"https:\/\/lastroundai.com\/blog\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/lastroundai.com\/blog\/wp-json\/wp\/v2\/iq\/1161","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lastroundai.com\/blog\/wp-json\/wp\/v2\/iq"}],"about":[{"href":"https:\/\/lastroundai.com\/blog\/wp-json\/wp\/v2\/types\/iq"}],"author":[{"embeddable":true,"href":"https:\/\/lastroundai.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/lastroundai.com\/blog\/wp-json\/wp\/v2\/comments?post=1161"}],"version-history":[{"count":3,"href":"https:\/\/lastroundai.com\/blog\/wp-json\/wp\/v2\/iq\/1161\/revisions"}],"predecessor-version":[{"id":1496,"href":"https:\/\/lastroundai.com\/blog\/wp-json\/wp\/v2\/iq\/1161\/revisions\/1496"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lastroundai.com\/blog\/wp-json\/wp\/v2\/media\/1711"}],"wp:attachment":[{"href":"https:\/\/lastroundai.com\/blog\/wp-json\/wp\/v2\/media?parent=1161"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lastroundai.com\/blog\/wp-json\/wp\/v2\/tags?post=1161"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}