DevOps & Cloud Interview Prep: Real Scenarios & Answers

https://DevOpsInterview.Cloud

Real DevOps and Cloud interview questions, answered the way a senior engineer actually would. Each episode breaks down a production scenario — Kubernetes, AWS, Azure, GCP, Terraform, CI/CD, observability, security - with the short answer, the deep dive, and the gotchas interviewers probe for. Built for Cloud Engineers, DevOps and Platform Engineers, and SREs prepping for senior roles. Full interview-prep ebooks and guides at DevOpsInterview.Cloud.

  1. 2d ago

    CoreDNS at 100K RPS: ndots, Negative Caching, and Autopath

    A real-world CoreDNS latency incident at high query volume reveals how ndots and Kubernetes search domains silently multiply DNS lookups into a full-blown query storm. You'll learn: Why a single external hostname like api.stripe.com generates 4 upstream queries under Kubernetes' default ndots:5 — and how that 4x amplifier compounds at scale How to override search behavior per-pod via dnsConfig.ndots, and why a trailing dot in your FQDN collapses four queries into one Tuning the CoreDNS cache plugin: setting denial TTLs high enough that NXDOMAIN responses actually stick, and the staleness tradeoff you must articulate in interviews What the autopath plugin actually does differently — moving search-path resolution server-side — and when it helps versus when it shifts the problem Why interviewers use this question to separate engineers who've read the docs from those who've debugged a DNS storm at 3am Keywords: CoreDNS tuning, Kubernetes DNS ndots, negative caching NXDOMAIN, CoreDNS cache plugin, Kubernetes networking interview 🎧 Listen, then go deeper — DevOps & Cloud interview-prep ebooks at DevOpsInterview.Cloud ▶ Daily 30-second interview drills: DevOps Interview Cloud on YouTube Transcript Picture this. Your cluster is doing something like a hundred thousand requests per second across a few hundred services, and suddenly every outbound call to a third-party API starts timing out intermittently. Nothing in your application changed. No deploy went out. But your p99 latency for anything that touches DNS resolution just tripled, and your CoreDNS pods are pegged at max CPU. This is a real failure pattern, and it almost always traces back to two things: how ndots is configured in every pod's resolver, and how CoreDNS is caching, or failing to cache, negative responses. Interviewers ask about this because it separates people who've read the Kubernetes docs from people who've actually had to explain a production DNS storm to their team. Anyone can say 'CoreDNS handles DNS in the cluster.' Far fewer people can explain why a single hostname lookup can turn into four or five actual queries hitting your DNS servers, and what that does to your query volume when you're already running near capacity. This question tests whether you understand resolution mechanics, not just that a service called CoreDNS exists. Here's the mental model. Every pod in a Kubernetes cluster gets a resolv.conf file, and that file has two important settings: a search list and an ndots value. The search list typically looks like namespace dot svc dot cluster dot local, then svc dot cluster dot local, then cluster dot local, and depending on your cloud provider, maybe an additional domain from the node itself. The ndots value, five by default in Kubernetes, tells the resolver: if the name you're looking up has fewer than five dots in it, don't treat it as fully qualified. Instead, try appending each entry in the search list first, in order, before falling back to treating it as an absolute name. Now think about what that means for a completely ordinary external lookup, something like api dot stripe dot com. That name has two dots. Since two is less than the ndots threshold of five, the resolver assumes it might be a relative name inside your cluster. So it tries api dot stripe dot com dot your-namespace dot svc dot cluster dot local first. That fails, comes back NXDOMAIN. Then it tries api dot stripe dot com dot svc dot cluster dot local. Fails again. Then api dot stripe dot com dot cluster dot local. Fails again. Only on the fourth attempt does it try api dot stripe dot com as an absolute name, with a trailing dot, and finally succeeds. So a single application-level DNS call just became four queries hitting CoreDNS, three of which were guaranteed to fail. Now multiply that across your fleet. If you're doing a hundred thousand real DNS-triggering requests per second, and a meaningful chunk of those are external hostnames going through this same four-query pattern, your actual query volume against CoreDNS isn't a hundred thousand queries per second. It's closer to three hundred or four hundred thousand, most of it wasted work resolving things that were never going to exist in your cluster domain in the first place. That's the amplification, and it's the single biggest reason CoreDNS falls over under load that looks survivable on paper. There are two levers here, and good candidates know both. First, ndots itself. You can override the search behavior per pod using the dnsConfig field in the pod spec, setting ndots to something lower, like one, for workloads that mostly talk to external services. Or, simpler and often better, you just get your application code or your service mesh sidecar to use fully qualified domain names with a trailing dot for external calls, which bypasses the search list entirely regardless of ndots. That trailing dot is doing real work. It tells the resolver 'this is already absolute, skip the search list,' and it collapses four queries into one. The second lever is the CoreDNS cache plugin, and this is where negative caching becomes the interesting part. CoreDNS caches two kinds of answers: successful responses, and negative responses, meaning NXDOMAIN or NODATA results. By default, the cache plugin's denial caching, the negative cache, often runs with a fairly short TTL, sometimes as low as a handful of seconds depending on your Corefile. That means those three failed lookups per external hostname, the ones hitting cluster dot local variants, don't get cached long enough to actually help you. Every single request re-triggers the same failed chain. The fix is to explicitly tune the cache plugin in your Corefile. You want a reasonably generous success TTL, something like thirty seconds for internal service records that don't change often, and importantly you want to bump the denial TTL too, maybe to a similar range, so that once CoreDNS has established that api dot stripe dot com dot cluster dot local doesn't exist, it doesn't ask again for that window instead of on every single request. The tradeoff you have to talk about in an interview is staleness. If you cache negative responses for sixty seconds and then a service actually does get created with that exact name mid-window, clients will keep getting NXDOMAIN until the cache expires. For genuinely dynamic environments with frequent service creation, you tune this down. For stable production traffic patterns, you can afford to push it up and take the throughput win. This is also where autopath comes into the conversation, because interviewers like asking what it actually buys you versus just tuning ndots. Autopath is a CoreDNS plugin that moves the search path logic from the client side to the server side. Instead of the pod's resolver blindly firing off four sequential queries and waiting for each response before trying the next, autopath has CoreDNS itself walk the search list server-side and return the final correct answer in a single round trip from the client's perspective. From the pod's point of view, it looks like one query went out and one correct answer came back, even though CoreDNS internally still had to check multiple names. The honest tradeoff to mention here: autopath reduces client-observed latency and reduces the number of round trips over the network, but it doesn't eliminate the internal query cost inside CoreDNS, and it adds memory overhead per pod because it has to track pod IP to namespace mappings to know which search path applies. It also depends on the Kubernetes plugin being configured correctly, and it's had stability caveats across CoreDNS versions, so if you cite it in an interview, mention that you'd test it in a staging environment under real load before trusting it in a high-QPS production path. Combined with proper ndots tuning and cache tuning, it's a genuine option, but it's not a silver bullet you deploy blind. Let's talk about the wrong answers people give under pressure, because interviewers are listening for these. The first wrong answer is 'just scale up CoreDNS replicas.' That helps you survive the amplification, but it doesn't fix it. You're paying more compute to serve queries that shouldn't exist in the first place. The second wrong answer is 'disable DNS caching to get fresher answers.' That's backwards. You'd be removing the one thing protecting your upstream from repeated failed lookups. The third wrong answer, and this one sounds smart but isn't, is 'just increase CPU and memory limits on the CoreDNS pods.' That treats a query-volume problem as a resource problem. It buys you headroom, sure, but the moment traffic grows again, you're back in the same spiral, because the root cause, that four-to-one query amplification from ndots, is still sitting there untouched. So here's the thirty-second version. Under Kubernetes defaults, ndots five means any external hostname with fewer than five dots gets tried against your entire internal search domain before it's resolved as absolute, turning one lookup into four. Fix it by using fully qualified names with a trailing dot for external calls, or override ndots in dnsConfig for the workloads that need it. Tune the CoreDNS cache plugin's success and denial TTLs deliberately, don't just accept the defaults, because negative caching is what protects you from repeatedly re-querying names that don't exist. And consider autopath to collapse client-side search path queries into a single server-side lookup, understanding it trades some CoreDNS-side memory and complexity for lower client latency. If you want the full written version of this with the exact Corefile syntax, the dnsConfig YAML, and the follow-up questions interviewers tend to ask after this one, go grab the prep guide at devopsinterview dot cloud.

    CoreDNS at 100K RPS: ndots, Negative Caching, and Autopath
  2. Jul 22

    VPA vs HPA for Stateful Workloads: Autoscaler Deep Dive

    Your Cassandra node is getting evicted at 2 a.m. or your PostgreSQL replica is sitting on 4× the memory it needs — this episode breaks down exactly which autoscaler to reach for and why VPA vs HPA is a staple senior SRE interview question. You'll learn: Why HPA's scale-out model breaks for StatefulSets (token rings, replication slots, unacknowledged messages) and when vertical scaling is the only safe lever VPA's three components — recommender, admission controller, updater — and why update mode auto is the one that pages you at 2 a.m. for stateful workloads The safe progression: start in Off mode for two weeks, apply recommendations manually, then consider Initial mode — and why Auto is rarely worth it for anything with persistent state The HPA + VPA feedback loop failure: both watching CPU on the same workload, pod count oscillating, resource allocation in chaos The clean split that actually works: HPA on queue depth (custom metric), VPA managing memory requests — distinct signals, no interference Keywords: VPA vs HPA Kubernetes, vertical pod autoscaler stateful workloads, autoscaler SRE interview, HPA VPA conflict, Kubernetes StatefulSet autoscaling 🎧 Listen, then go deeper — DevOps & Cloud interview-prep ebooks at DevOpsInterview.Cloud ▶ Daily 30-second interview drills: DevOps Interview Cloud on YouTube Transcript Your stateful app is getting evicted every few hours, or it's sitting on four times the memory it actually needs, and you're not sure which autoscaler to reach for. That's the exact scenario interviewers love, because most candidates only know one half of the answer. Let's set the stage. You have a Cassandra node, a RabbitMQ broker, or a PostgreSQL read replica running in Kubernetes. It's a StatefulSet. Traffic is not uniform. Some days it's busy, some days it's quiet. Someone on your team says "just add HPA" and someone else says "we need VPA." Who's right? That question shows up in senior SRE and platform engineer interviews constantly, because the answer is not obvious and the wrong choice causes real incidents. Interviewers ask this because autoscaling is one of those topics where surface-level knowledge falls apart fast. Saying "HPA scales pods out, VPA scales pods up" is correct but incomplete. The follow-up is always: okay, so which one do you use for a stateful workload, and why? And then: what happens if you use both at the same time? If you can't answer those, you signal that you've only worked with stateless services. Here's the mental model you need. The HPA, the Horizontal Pod Autoscaler, works by changing the number of pod replicas. It watches a metric, CPU or memory or a custom one, and when that metric crosses a threshold it adds or removes pods. That works beautifully for stateless services. Each replica is identical, sessions don't matter, and spinning up a new pod behind a load balancer is invisible to users. Stateful workloads break that assumption. A Cassandra node owns a subset of the token ring. A RabbitMQ broker may hold unacknowledged messages. A PostgreSQL replica has an open replication slot. Adding a new pod doesn't instantly help because the new pod has to join the cluster, sync data, or acquire state before it can carry load. Scaling out fast is often dangerous. Scaling in is even worse because you might be removing a pod that holds data not yet replicated elsewhere. So for stateful workloads, the more useful lever is usually vertical. Give the existing pod more CPU or more memory so it can handle the load without needing a new replica. That's where the VPA, the Vertical Pod Autoscaler, comes in. VPA has three components. The recommender watches historical resource usage and calculates what your requests and limits should be. The admission controller patches those values into new pods at scheduling time. And the updater, this is the dangerous one, can evict running pods so they restart with the new resource values. The key knob is the update mode, and this is a common interview question on its own. Update mode off means the VPA only calculates recommendations. It never touches your pods. You query the VPA object and apply changes yourself. This is the right starting point for any stateful workload. You get the data without the risk. Update mode initial means the admission controller sets resource values when a pod is first created, but the VPA never evicts a running pod. The pod keeps whatever resources it started with until it's naturally replaced, for example during a rollout. This is a reasonable middle ground for apps that tolerate restarts as part of deployments but not random evictions. Update mode auto, and this is the one that bites teams, allows the VPA updater to evict pods at any time to apply new recommendations. For a stateless deployment this is often fine. For a stateful pod it can be catastrophic. Imagine your primary Redis instance getting evicted at two in the morning because the VPA decided it needed fifty percent more memory. The pod comes back, but during those thirty seconds of restart your application is throwing errors. The fourth mode, recreate, behaves like auto but only triggers on pod creation events. In practice most teams treat auto and recreate as the same risk category for stateful workloads. So the concrete recommendation for stateful apps is: start with update mode off, run it for at least two weeks to cover your traffic patterns, look at the recommended requests in the VPA status, and then apply those values manually to your StatefulSet spec. After you've done that once and confirmed stability, you can consider bumping to initial mode. Staying in auto is rarely worth it for anything with persistent state. Now the tricky part that interviewers really test: can you run HPA and VPA at the same time? The short answer is yes, but only if they're watching different metrics. The classic failure pattern is enabling both on the same workload with both watching CPU. Here's what happens. Load increases. CPU goes up. HPA adds a replica. The CPU per pod drops because the load is now spread. VPA sees lower per-pod CPU and recommends lower requests. It either tells you to reduce requests or, in auto mode, evicts pods to resize them down. Meanwhile HPA is still watching the same CPU signal. You get a feedback loop where both controllers are fighting each other, your pod count oscillates, and your resource allocation is unstable. The safe combination is to give each controller a distinct domain. A common pattern for a message broker is to let HPA scale on queue depth, a custom metric from your metrics pipeline, while VPA manages the memory requests because memory usage on a broker tends to grow with configuration and message size rather than with load spikes. They're watching completely different signals so they don't interfere. Another safe pattern is to disable HPA entirely and rely only on VPA in initial mode, pairing that with a PodDisruptionBudget, the PDB, to prevent the cluster autoscaler from removing nodes that would orphan your pods. This is common for single-instance stateful workloads where horizontal scaling genuinely isn't possible. Let's talk real numbers briefly so you sound credible in the interview. A typical starting point for a moderately loaded RabbitMQ broker might be two hundred and fifty millicores CPU request and five hundred millicores limit, with one gigabyte memory request and two gigabytes limit. After running VPA in off mode for two weeks under normal traffic, you might see the recommender suggesting six hundred millicores CPU and one and a half gigabytes memory. That gap between what you provisioned and what you actually need is exactly the over-provisioning problem VPA is designed to solve. Without it, you're just guessing. On the eviction risk side, the VPA updater respects PodDisruptionBudgets. If your PDB says zero pods unavailable, the updater will not evict your pod even in auto mode. So if you are running VPA auto on a StatefulSet, always pair it with a PDB that reflects your actual availability requirements. This is a detail that separates strong answers from weak ones in interviews. There's also the resource policy inside the VPA spec itself. You can set min allowed and max allowed values per container so the recommender can't suggest something absurd. For example, you can tell it to never recommend less than one hundred millicores or more than four cores, keeping the recommendations inside bounds your infrastructure can actually handle. Always set these bounds for production workloads. One more wrinkle worth knowing. VPA and HPA cannot both target CPU or memory requests at the same time because HPA uses requests as the denominator for its utilization calculation. If VPA changes the request value, the HPA's target threshold shifts underneath it. The percentage-based math breaks. Kubernetes has a known limitation here, and the official guidance is to not use HPA on CPU or memory when VPA is also active on the same workload, unless you're using HPA with custom or external metrics only. Common wrong answers you want to avoid. The first is saying "just use HPA for everything, stateful or not." That ignores the data ownership and sync cost of scaling stateful replicas. The second is saying "VPA is dangerous so never use it." That's overcorrecting. VPA in off or initial mode is genuinely useful and low risk. The third is conflating pod autoscaling with cluster autoscaling. The cluster autoscaler adds nodes. VPA and HPA manage pods within existing nodes. They work at different layers and you need to be clear about which layer you're talking about. The fourth is not mentioning PodDisruptionBudgets when discussing VPA auto mode. Experienced interviewers will notice that gap immediately. Quick recap. For stateful workloads, your default should be VPA in off mode to gather recommendations, and then apply them manually. Use initial mode once you trust the recommendations

    VPA vs HPA for Stateful Workloads: Autoscaler Deep Dive

About

Real DevOps and Cloud interview questions, answered the way a senior engineer actually would. Each episode breaks down a production scenario — Kubernetes, AWS, Azure, GCP, Terraform, CI/CD, observability, security - with the short answer, the deep dive, and the gotchas interviewers probe for. Built for Cloud Engineers, DevOps and Platform Engineers, and SREs prepping for senior roles. Full interview-prep ebooks and guides at DevOpsInterview.Cloud.