Incident Response Runbooks for Kubernetes
How to write, organize, test, and use step-by-step guides for the worst hours of your on-call life, with ready-made runbooks for the most common Kubernetes failures, explained from zero.
Imagine you are a pilot and an alarm sounds in the cockpit. You do not sit and think about how engines work. You reach for a laminated checklist, read the first line, do what it says, and move to the next. The checklist was written calmly, on the ground, by people who had time to think. Its whole purpose is to let a tired, stressed person do the right thing in the right order, when thinking is hardest.
An incident response runbook is that checklist for software. It is a short, tested, step-by-step guide that says: when you see this problem, check these things, in this order, and do this to fix or contain it. Kubernetes makes runbooks especially valuable, because a single symptom, such as “the website is slow”, can come from a dozen layers: the application, the pod, the node, the network, the control plane, or the cloud underneath. Without a map, an engineer at three in the morning wanders between layers and loses precious minutes. This post explains runbooks from the very beginning, assuming you know nothing yet. By the end, you will know how to design a runbook, how to run an incident, and you will have a library of runbooks for the most common Kubernetes failures that you can adapt for your own team.
1The Problem: Three in the Morning and No Map
To appreciate runbooks, let us first feel the problem they solve. It is not a lack of skill. It is a lack of calm, shared, written knowledge at the exact moment it is needed.
A typical bad night
A phone buzzes at three in the morning. An alert says that the checkout service has a high error rate. The engineer on call is new to this service. She opens a dashboard that shows many graphs, but she is not sure which ones matter. She asks in the team chat, but everyone who knows the service is asleep. She starts running commands she half remembers from a training course. Twenty minutes pass. A senior colleague wakes up and joins, and in two minutes says, “Oh, that is the certificate again. It expires every year.” Total time to fix: forty minutes. Real fixing time: two minutes. The rest was searching.
Think of a hospital emergency room. Doctors there are very skilled, yet they still follow written protocols for common emergencies such as a heart attack or a stroke. The protocols do not replace skill. They remove avoidable delay and mistakes, and they let a junior doctor act correctly while a senior one is on the way.
Why Kubernetes makes this harder
Many layers
A symptom can come from the application, the container, the node, the network, the control plane, or the cloud. Each layer has its own tools.
Moving parts
Pods are created and destroyed constantly, so evidence disappears quickly. The pod you want to inspect may already be gone.
Many owners
Different teams own different parts of the platform, so the person on call may not own the broken piece.
Misleading symptoms
A restart loop, a pending pod, and a slow website may all trace back to one quiet node problem.
Self-healing hides trouble
Kubernetes restarts things automatically, so an incident may look like a mild flicker while it silently burns capacity.
Fast change
Frequent deployments mean a recent change is often the cause, but finding which change takes discipline.
What runbooks give you
This post describes runbook steps in plain words, such as “list recent events” or “describe the pod”, rather than giving exact commands. Tool names, options, and defaults change between Kubernetes versions and cloud providers. Your own runbooks should contain the exact commands for your environment, tested on your clusters.
2What an Incident Is, and How It Unfolds
Before writing a runbook, we need a shared meaning for the word “incident” and a picture of how one unfolds from start to finish.
A plain definition
An incident is an unplanned event that harms, or threatens to harm, the service your users depend on. A single failed pod that Kubernetes replaces within seconds is usually an event, not an incident. A checkout page that returns errors for ten minutes is an incident. The difference is impact on users or on the business, or a credible risk of it soon.
The life of an incident
flowchart LR
D["Detect: an alert or a user report"] --> T["Triage: judge impact and severity"]
T --> M["Mitigate: stop the harm quickly"]
M --> R["Resolve: fix the real cause"]
R --> V["Verify: confirm users are healthy"]
V --> P["Review: write the postmortem and improve runbooks"]
P -.-> D
Mitigate before you resolve
The most important idea in incident response is the difference between mitigation and resolution. Mitigation means stopping the pain for users, even if you do not yet know the cause. Resolution means fixing the underlying problem. During an outage, users care about the first. A rollback to the previous version, moving traffic away from a bad zone, or adding capacity are mitigations. They buy time. The deeper investigation can often wait until the service is healthy again.
If a pipe bursts in your kitchen, you first turn off the main water valve. That is mitigation. Then you find out why the pipe burst and replace it. That is resolution. Nobody stands in the flood studying the pipe before closing the valve.
Time matters in two ways
| Measure | Meaning | How runbooks help |
|---|---|---|
| Time to detect | How long the problem existed before anyone knew | Good alerts, each linked to a runbook |
| Time to mitigate | How long users felt the problem | Clear first actions: rollback, scale, fail over |
| Time to resolve | How long until the true cause was fixed | Diagnostic steps that narrow the cause fast |
| Time between incidents | How often similar problems recur | Postmortems that feed improvements back into runbooks |
Production example: the mitigation-first culture
Large technology companies that run reliability teams, such as those who popularized site reliability engineering, teach responders to roll back first and investigate later whenever a recent change is suspected. This habit alone shortens many outages, because the quickest reliable fix is often to undo the last change.
3What a Runbook Is, and What It Is Not
The word runbook is used loosely. Let us separate it from its close cousins so that your team builds the right thing.
Four kinds of document
| Document | Purpose | When it is read | Style |
|---|---|---|---|
| Runbook | Tells a responder what to check and do for a specific symptom | During an incident, under stress | Short, numbered, action-focused |
| Playbook | Describes the wider process for a type of event, including roles, communication, and decisions | During and before incidents | Broader, process-focused |
| Architecture document | Explains how a system is built and why | While learning or designing | Explanatory, long |
| Postmortem | Records what happened and what to change afterwards | After an incident | Narrative, blameless, analytical |
Think of a car. The owner’s manual explains how everything works, like the architecture document. The sticker on the dashboard that says “if the red oil light shows, stop and check the oil” is the runbook. The roadside assistance procedure that says who to call and what to say is the playbook. The mechanic’s report after a breakdown is the postmortem.
What makes something a good runbook
A runbook is tied to a symptom or alert, not to a component. Responders do not wake up thinking “something is wrong with the scheduler”. They wake up with “pods are pending” or “latency is high”. A runbook should begin at the symptom, because that is what the responder holds in their hand. It should then lead them, step by step, through the checks that separate one cause from another.
Qualities to aim for
A good runbook is
- Short enough to read at three in the morning.
- Specific about what to look at and what each result means.
- Ordered from the most common and safest check to the rarest and riskiest.
- Clear about who to call when it stops helping.
- Tested and dated.
A poor runbook is
- A wall of text that explains theory.
- Written once and never opened again.
- Full of steps that say “investigate” without saying how.
- Missing warnings for dangerous actions.
- Stored where nobody can find it during an outage.
Runbooks cover known, repeating problems. New failures will happen that no document predicts. A good runbook says so, and includes a clear point where the responder should stop following steps and escalate for help from someone who can think freely about the new problem.
4The Anatomy of a Good Runbook
Every runbook in this post follows the same shape. A fixed shape matters, because a tired responder can find what they need without thinking about where it is.
The standard sections
Title and symptom
Name the problem the way an alert or a user would describe it. Include the alert name, so a search finds it.
Impact and severity
Say who is affected and how serious this usually is, so the responder can judge whether to wake others.
Quick mitigation
Offer the fastest safe action that stops user pain, before any deep diagnosis. Often a rollback, a scale-up, or a traffic shift.
Diagnosis steps
List numbered checks. Each says what to look at, what a healthy result looks like, and what an unhealthy result means.
Fix steps
For each likely cause, give the fix, with warnings about risks and a way to undo it.
Verification
Describe how to confirm that the problem is truly gone, such as which graph should recover and by when.
Escalation
Name the team, the channel, or the person to contact if the steps do not work, and the time limit before doing so.
Context and history
Link to dashboards, past incidents, related runbooks, the owning team, and the date it was last tested.
flowchart TD
A["Alert fires with a link"] --> B["Runbook opens at the symptom"]
B --> C["Check impact: how bad, who is affected"]
C --> D["Quick mitigation if available"]
D --> E["Diagnosis steps in order"]
E --> F{"Cause found?"}
F -->|"yes"| G["Apply the matching fix"]
F -->|"no"| H["Escalate to the named owner"]
G --> I["Verify recovery"]
H --> I
Decision points make runbooks useful
A runbook is not a list; it is a small map with branches. The best ones use plain questions: “Is the pod restarting? If yes, go to step four. If no, go to step six.” These questions turn a long document into a path of only a few steps for any given case. If a runbook has more than about ten steps on any path, it probably needs splitting into two.
It works like the troubleshooting section in a printer manual. It does not say “learn how printers work”. It says “Is the light blinking? Yes: open the cover and check for paper. No: go to the next question.” You arrive at the answer in a few clear moves.
Write each runbook for a tired, stressed engineer who is new to the service and reading on a phone. If it works for that person, it works for everyone. Short sentences, one action per step, and bold warnings for risky steps.
Production example: runbook links inside alerts
Mature operations teams attach the link to the matching runbook directly inside every alert notification. The responder taps the alert and lands on the right page. Teams commonly report that this one habit reduces the time to the first useful action more than any dashboard improvement.
5Roles During an Incident
A runbook guides what to do. Roles decide who does it. Without clear roles, many well-meaning people try to fix the same thing at once, or everyone assumes someone else is communicating.
The core roles
Incident commander
Coordinates the response. Decides priorities, assigns tasks, and keeps the big picture. Does not dive into fixing, so the view stays wide.
Operations lead
Runs the hands-on investigation and changes. Follows the runbook, reports findings, and asks the commander before risky actions.
Communications lead
Updates stakeholders and customers on a regular rhythm, so engineers are not interrupted by questions.
Scribe
Writes down a timeline of what was seen and done, with times. This record becomes the base of the postmortem.
Subject experts
Join when needed, such as a database or networking specialist, and leave when their part is done.
Think of an orchestra. The conductor does not play an instrument, yet the music only works because someone keeps the whole in view. In a small incident, one person may play several roles. In a large one, separate people for each role keep everyone calm and focused.
flowchart TD
IC["Incident commander: decides and coordinates"] --> OPS["Operations lead: investigates and acts"]
IC --> COM["Communications lead: updates stakeholders"]
IC --> SCR["Scribe: records the timeline"]
OPS --> SME["Subject experts: called in as needed"]
Rules that keep it calm
One voice decides
The commander makes the final call. Others advise. This prevents conflicting changes to the cluster at the same time.
Announce before you act
Say in the incident channel what you are about to change. Silent changes confuse the investigation.
One incident channel
Keep all talk in one place, so latecomers can read the story from the top.
Hand over cleanly
When people tire, hand the role to a fresh person with a short summary. Long incidents need rest.
Blameless habits
- Ask what the system allowed, not who made the mistake.
- Thank people for raising problems early.
- Treat every incident as a chance to improve.
Habits that hurt
- Blaming individuals in the channel.
- Hiding mistakes to avoid embarrassment.
- Heroic solo fixing with no record.
A minor issue does not need five roles and a formal channel. Define a small threshold: below it, one person follows the runbook; above it, open a formal incident and assign roles. Clear thresholds stop both under-reaction and over-reaction.
6Severity Levels and Escalation
Not every problem deserves the same response. Severity levels are a shared language that tells everyone how fast to move, who to wake, and how often to update.
A simple severity scale
| Level | Typical meaning | Response | Update rhythm |
|---|---|---|---|
| Severity 1 | Major outage or data loss risk, most users affected, revenue stopped | Immediate, all hands needed, formal roles | Every fifteen to thirty minutes |
| Severity 2 | Serious degradation, a large feature broken or many users slowed | Urgent, on-call plus the owning team | Every thirty to sixty minutes |
| Severity 3 | Limited impact, a workaround exists, few users affected | Handled during working hours or by on-call alone | As needed |
| Severity 4 | Minor issue, no user impact yet | Ticket and normal planning | None |
It is like triage in a hospital waiting room. A person with a paper cut and a person with chest pain do not wait in the same queue. A clear scale lets staff sort quickly, so the most urgent case is helped first without arguments.
How to judge severity fast
In the first minutes, three questions are enough. How many users are affected? How badly: slow, partly broken, or fully down? Is it getting worse? If you are unsure, choose the higher level, and lower it later. Raising severity late costs more than lowering it early.
Escalation: asking for help on time
Escalation is not failure. It is the normal part of the process. A good runbook gives a time limit: “If you have not found the cause within fifteen minutes, escalate.” This removes the pressure on the responder to prove themselves, and prevents the common mistake of struggling alone while the outage grows.
flowchart TD
A["Alert fires"] --> B["Primary on-call acknowledges"]
B --> C{"Resolved or mitigated in the runbook time limit?"}
C -->|"yes"| D["Verify and close"]
C -->|"no"| E["Escalate to secondary on-call and service owner"]
E --> F{"Severity 1 or widening impact?"}
F -->|"yes"| G["Open formal incident, assign roles, notify leadership"]
F -->|"no"| H["Continue with owner and update on a schedule"]
If waking a colleague feels expensive, people delay. Teams that celebrate early escalation, and never criticize a page that turned out to be small, find that incidents shrink. The cost of a false alarm is minutes. The cost of a delayed call can be hours.
7A Mental Map of Kubernetes Failures
Before the individual runbooks, you need a map of where things can break. Kubernetes is a stack of layers, and a good responder works through them in a sensible order.
The layers, from top to bottom
flowchart TD
U["Users and clients"] --> L1["Layer 1: Application code and configuration"]
L1 --> L2["Layer 2: Pods and containers"]
L2 --> L3["Layer 3: Workload controllers and scheduling"]
L3 --> L4["Layer 4: Nodes and the container runtime"]
L4 --> L5["Layer 5: Cluster networking and DNS"]
L5 --> L6["Layer 6: Control plane and its datastore"]
L6 --> L7["Layer 7: Cloud infrastructure: machines, disks, networks, identity"]
Think of a tap that gives no water. You check the tap first, then the pipe under the sink, then the main valve of the house, then the street supply. You move from the nearest, cheapest check to the farthest. Troubleshooting Kubernetes follows the same path, from the application down to the cloud.
What each layer contains
| Layer | What lives here | Typical symptoms |
|---|---|---|
| 1. Application | Code, settings, secrets, dependencies on other services | Errors, wrong results, slowness with healthy pods |
| 2. Pods and containers | Images, startup, health checks, resource limits | Restart loops, killed containers, failing probes |
| 3. Controllers and scheduling | Deployments, scheduling decisions, autoscalers | Pods pending, rollouts stuck, wrong replica counts |
| 4. Nodes and runtime | Machines, kubelet, disk, memory, runtime | Node not ready, evictions, disk pressure |
| 5. Networking and DNS | Services, ingress, network plugins, name lookups | Timeouts, name errors, partial connectivity |
| 6. Control plane | API server, scheduler, controller manager, datastore | Commands slow or failing, nothing changes |
| 7. Cloud | Virtual machines, load balancers, storage, identity, quotas | Nodes cannot start, disks cannot attach, permissions denied |
Two helpful questions at the start
The first question is “What changed?” Most incidents follow a change: a deployment, a configuration edit, a certificate expiry, a traffic surge, or a cloud event. The second is “What is the blast radius?” If only one service is broken, look at layers one to three. If many unrelated services break together, look lower: nodes, networking, control plane, or cloud. The blast radius is a strong hint to the layer.
One service affected
- Suspect the application, its recent change, or its dependencies.
- Check pods, probes, and resource limits first.
Many services affected
- Suspect shared layers: nodes, network, DNS, control plane, or cloud.
- Check cluster-wide health and recent platform changes first.
Spend the first minute getting the shape of the problem: how many things are broken, since when, and what changed. A responder who dives deep into one pod while half the cluster is failing wastes time on a symptom.
8The First Five Minutes: A Universal Triage Runbook
If you write only one runbook, write this one. It is the opening sequence that works for almost any Kubernetes alert, and it points you to the more specific runbooks that follow.
Step by step
Acknowledge and note the time
Tell the team you are on it. Write the start time. The timeline begins now.
Confirm the impact
Check the user-facing signals first: error rate, latency, and traffic. Is the problem real, how big, and growing?
Ask what changed
Look at recent deployments, configuration changes, scaling events, and cloud notices in the last hour or two.
Check the blast radius
Is it one service, one namespace, one node, one zone, or the whole cluster?
Look at the pods
List pods for the affected service. Note their states: running, pending, restarting, or failing to start.
Read recent events
List cluster events for the namespace, sorted by time. Events often state the cause in plain words.
Check the nodes
Are any nodes not ready or under pressure from memory, disk, or processes?
Decide on a quick mitigation
If a recent change is suspected, roll it back. If capacity is short, add it. If one node or zone is bad, move work away from it.
Jump to the specific runbook
Match the symptom to the next chapters: restart loops, pending pods, node trouble, networking, and so on.
flowchart TD
S["Symptom reported"] --> A["Confirm impact and severity"]
A --> B["Ask: what changed recently?"]
B --> C{"Recent change likely the cause?"}
C -->|"yes"| D["Mitigate: roll back the change"]
C -->|"no"| E["Check blast radius"]
E --> F{"One service or many?"}
F -->|"one"| G["Pods, events, logs, resources, dependencies"]
F -->|"many"| H["Nodes, network, DNS, control plane, cloud"]
D --> V["Verify recovery"]
G --> V
H --> V
This is the “ABC” of first aid: check airway, breathing, circulation. Whatever the injury, you always start with the same few quick checks. Only after those do you look at the specific wound.
Kubernetes replaces failing pods quickly, and the evidence goes with them. Before deleting or restarting anything, capture the pod’s description, its logs, and the previous container’s logs if it has restarted. A few seconds of saving now can save an hour of guessing later.
Production example: a one-page triage card
Many on-call teams keep this universal sequence on a single page, pinned in the incident channel and linked from every alert. New engineers practice it in their first week. Teams report that responders who follow the same opening steps produce incident timelines that are much easier to compare and learn from.
9Reading the Evidence: Status, Events, and Logs
Every runbook step asks you to look at something. This chapter explains the three main sources of evidence in Kubernetes, so that you know what each one can and cannot tell you.
Pod status: the headline
Each pod has a status that is a one-word summary of its state. It is a headline, and headlines can mislead, but they point you in the right direction. The common values mean the following.
| Status | Plain meaning | Go to |
|---|---|---|
| Pending | The pod has not been placed on a node, or is waiting for something such as storage | Pending pods runbook |
| ContainerCreating | A node was chosen, and it is preparing the container | Image and storage checks |
| ImagePullBackOff or ErrImagePull | The node cannot download the container image | Image pull runbook |
| CrashLoopBackOff | The container starts, fails, and is restarted again and again with growing pauses | Restart loop runbook |
| OOMKilled (shown as the last reason) | The container used more memory than its limit and was killed | Memory runbook |
| Running but not ready | The container runs but is failing its readiness check, so it receives no traffic | Probe and dependency checks |
| Terminating (stuck) | The pod is being deleted but has not finished | Stuck deletion checks |
| Evicted | The node removed the pod, often due to resource pressure | Node pressure runbook |
Events: the cluster’s diary
Kubernetes records events as short messages about what it is doing: pod scheduled, image pulled, probe failed, volume could not attach. When you describe a pod, the bottom of the output lists its events. They often state the cause in plain words, such as “insufficient memory” or “failed to pull image”. Two cautions apply: events are kept only for a short time, often about an hour, and they are summarized, so rapid repeats appear as one line with a count.
Think of a pilot’s black box and a ship’s logbook. The status is the dashboard light, telling you something is wrong. The events are the logbook entries, saying what the system tried and where it failed. The container logs are the voice recorder, capturing what the application itself said.
Logs: the application’s own words
Container logs are what the application printed. They tell you about problems inside the program, such as failed database connections, bad settings, or unhandled errors. If a container has restarted, you must ask for the previous container’s logs, because the current one may be brand new and empty. If your cluster ships logs to a central system, search there, since the pod may no longer exist.
Status
Quick summary of where the pod is in its life. Good for direction, poor for detail.
Events
The cluster’s own notes. Best for scheduling, image, storage, and probe problems. Short-lived.
Logs
The application’s voice. Best for code and dependency problems. Check previous logs after restarts.
Metrics
Numbers over time: CPU, memory, errors, latency. Best for spotting when it began and how it grew.
Traces
The path of a request across services. Best for finding which dependency is slow.
When a container stops, Kubernetes records an exit code and a reason. A code of zero means a clean exit. Small non-zero numbers usually mean the program itself failed. A code of one hundred thirty-seven usually means the process was killed from outside, often for memory. These clues shorten the search.
10Runbook: Pods in CrashLoopBackOff
This is the most famous Kubernetes symptom. A container starts, dies, and is restarted again and again, with longer and longer pauses between attempts. The pause is the “back off”.
Symptom and impact
Symptom: pods show restart counts rising, and a status of CrashLoopBackOff. Impact: fewer healthy replicas, possibly none, so traffic fails or capacity falls. Usual severity: two if a main service has few healthy replicas, three if only some replicas are affected.
Quick mitigation
Was there a recent change?
If a deployment or configuration edit happened just before the loop began, roll back to the last good version. This is the fastest cure.
Keep old replicas alive
During a bad rollout, make sure the old healthy replicas are still serving. Rolling updates normally protect them, so confirm the rollout is paused or reversed.
Diagnosis
flowchart TD
A["Container restarting"] --> B["Describe the pod: read last state, reason, exit code"]
B --> C{"Reason is OOMKilled?"}
C -->|"yes"| D["Go to memory runbook"]
C -->|"no"| E["Read previous container logs"]
E --> F{"Logs show a clear error?"}
F -->|"missing config or secret"| G["Fix the missing setting"]
F -->|"cannot reach dependency"| H["Check the dependency and network"]
F -->|"application bug"| I["Roll back or hotfix"]
F -->|"no logs at all"| J["Check the command, entry point, and image"]
E --> K{"Liveness probe failing?"}
K -->|"yes"| L["Probe too strict or app too slow to start"]
The common causes, in order of how often they occur
| Cause | How to recognize it | Fix |
|---|---|---|
| Bad recent change | Loop started right after a release | Roll back, then investigate calmly |
| Missing or wrong configuration | Logs say a setting, file, or secret is missing | Restore the setting and restart the pods |
| Dependency unreachable | Logs show connection errors to a database or service | Check that dependency, its network path, and its credentials |
| Memory limit too low | Last state says OOMKilled | Use the memory runbook |
| Liveness probe too strict | Container is killed while still starting, no error in logs | Lengthen the initial delay or use a startup probe |
| Wrong command or image | Exits at once with no logs, or an error about a missing program | Correct the command or image reference |
| Permission problem | Logs show access denied to files or the platform interface | Fix security settings or service account permissions |
It is like a car that starts, stalls, and is restarted again by an impatient driver who waits longer each time. The driver is Kubernetes. The question is not “why does the driver keep trying”, but “why does the engine stall each time?” The previous logs are the dashboard readings from just before it stalled.
Deleting a looping pod produces a new pod that loops again, and destroys the evidence. Capture the description and previous logs first. Only restart pods after you have changed what causes the failure.
Verification and escalation
Verify that pods reach ready, that restart counts stop rising for at least ten minutes, and that error rates return to normal. Escalate to the owning team if you cannot find a clear error after fifteen minutes, or if the logs point to a defect you cannot fix by configuration.
Production example: the strict probe
A very common story is a new version that takes longer to start than the old one, for example because it loads a larger cache. The liveness probe, tuned for the old version, kills the container before it finishes starting. Teams solve this by adding a startup probe that allows a longer start, while keeping the liveness probe strict afterwards.
11Runbook: Pods Stuck in Pending
A pending pod has been accepted by the cluster but has not been placed on a node. It is waiting. The question is: waiting for what?
Symptom and impact
Symptom: new pods remain in the Pending state for minutes. A rollout stalls, or an autoscaler adds replicas that never start. Impact: the service cannot grow, and during a traffic spike this becomes an outage. Usual severity: two if it blocks scaling during load, three otherwise.
The key to the diagnosis
The scheduler writes the reason onto the pod’s events. It usually says something like “zero of N nodes are available”, followed by the reasons it rejected each node. Reading that message is almost always the first and best step.
flowchart TD
A["Pod pending"] --> B["Describe the pod and read the scheduling message"]
B --> C{"What does the message say?"}
C -->|"insufficient CPU or memory"| D["Capacity or requests too large"]
C -->|"node taints not tolerated"| E["Pod lacks a needed toleration"]
C -->|"node selector or affinity not matched"| F["Labels do not match any node"]
C -->|"volume problem"| G["Storage not bound or in another zone"]
C -->|"too many pods"| H["Node pod limit reached"]
C -->|"no message at all"| I["Check scheduler health and quotas"]
Causes and fixes
| Cause | What you see | Fix |
|---|---|---|
| Not enough capacity | Message about insufficient CPU or memory on all nodes | Add nodes, check that the node autoscaler is working, or reduce requests if they are inflated |
| Request larger than any node | Pod asks for more than any single node can offer | Lower the request or add a larger node type |
| Taints without toleration | Nodes are tainted, pod does not tolerate | Add the right toleration, or use different nodes |
| Affinity or selector mismatch | No node carries the required label | Correct the labels or loosen the rule |
| Storage not ready | Claim pending, or volume in a different zone | See the storage runbook |
| Quota exceeded | Namespace quota blocks new pods | Raise the quota or remove unused workloads |
| Node pod limit | Nodes have free CPU but no pod slots left | Add nodes or choose larger types, and check network address limits |
Imagine a hotel reception telling a guest, “no room available”. The reason matters. Maybe the hotel is truly full, or the guest asked for a sea view with a balcony and none is free, or the booking system is down. The message from the scheduler is the receptionist explaining which of these applies.
When the autoscaler should have helped
If the cause is simple lack of capacity, the node autoscaler should add machines. If it does not, check its own logs and events. Common reasons are that the cloud account has reached its machine quota, the chosen machine type is unavailable in the zone, the pod’s rules cannot be satisfied by any available machine type, or the autoscaler has hit its configured maximum size.
Cloud accounts have limits on machines, addresses, and disks per region. A quota ceiling looks exactly like a lack of capacity. Checking quota usage in the cloud console early can save a long investigation.
Production example: the sale-day stall
Retail platforms often describe a pattern in which a traffic spike causes autoscaling to request more pods, but the node pool has reached its configured maximum, so pods stay pending. Teams add an alert for “pending pods for more than five minutes”, linked to this runbook, and review node pool maximums before known high-traffic events.
12Runbook: Image Pull Failures
Before a container can run, the node must download its image from a registry. When this step fails, pods sit in a state called ImagePullBackOff or ErrImagePull.
Symptom and impact
Symptom: pods never start, and events say that the image could not be pulled. Impact: a new release cannot roll out, and any replacement pods cannot start, which becomes serious if nodes are also being replaced. Usual severity: three, rising to one or two if it blocks recovery from another incident.
Checks in order
Read the exact error
Describe the pod and read the message. It usually says “not found”, “unauthorized”, “timeout”, or “rate limit”.
Check the image name and tag
A typing mistake in the name or tag is the most common cause. Confirm the tag exists in the registry.
Check credentials
For private registries, confirm the pull secret exists in the namespace, is referenced by the pod, and has not expired.
Check the registry itself
Is the registry up? Is it throttling you? Public registries can limit anonymous pulls, which breaks large rollouts.
Check the network from the node
Nodes need a path to the registry, through gateways, proxies, or private endpoints. A recent network change may have cut it.
| Error clue | Likely cause | Fix |
|---|---|---|
| Not found, or manifest unknown | Wrong name or tag, or image not yet pushed | Correct the reference or finish the build pipeline |
| Unauthorized or access denied | Missing, wrong, or expired credentials | Renew the pull secret or fix cloud identity permissions |
| Too many requests | Registry rate limit | Use authenticated pulls, or a mirror or cache inside your network |
| Timeout or connection refused | Network path or registry outage | Check routes, gateways, and registry status |
| No space left | Node disk full of old images | Clean up images, or see the node pressure runbook |
It is like sending a courier to collect a parcel from a warehouse. The trip can fail because the parcel number is wrong, because the courier has no permission slip, because the warehouse is closed, or because the road is blocked. The error message is the courier’s note about which one happened.
Make this failure rare
Good prevention habits
- Use specific image versions, not a moving label.
- Run a registry cache or mirror close to the cluster.
- Alert before pull secrets expire.
- Keep a copy of images needed for recovery.
Habits that cause trouble
- Depending on a single public registry for critical images.
- Pulling the latest version of everything on every start.
- Manual secret renewal with no reminders.
A registry outage prevents any new pod from starting anywhere. Already-running pods keep working. So during such an outage, avoid restarting things unnecessarily, and pause deployments until the registry recovers.
13Runbook: Out of Memory and Resource Exhaustion
Memory problems are among the most frequent causes of Kubernetes incidents. They come in two forms: a container exceeding its own limit, and a whole node running short.
Symptom and impact
Symptom: containers restart with the reason OOMKilled, or pods are evicted, or latency rises as the system struggles. Impact: dropped requests, lost in-memory work, and sometimes cascading failures. Usual severity: two to three.
Two different problems
Container over its limit
The container used more memory than its own limit, and the system killed it. Only that container is affected. Fix the limit or the leak.
Node out of memory
The machine itself ran low, so the node’s agent evicts pods, or the system kills processes. Many pods may be affected. Fix capacity or overcommitment.
Think of a shared apartment. Each flatmate has a cupboard (the limit). If one stuffs more than the cupboard holds, only that flatmate’s items are thrown out. But if all flatmates together fill the whole apartment, the landlord (the node) starts removing belongings from several people to make room.
Diagnosis
flowchart TD
A["Memory trouble suspected"] --> B{"Which scope?"}
B -->|"one container restarts with OOMKilled"| C["Compare usage over time with the limit"]
B -->|"many pods evicted on one node"| D["Check node memory pressure and total requests"]
C --> E{"Does usage grow steadily without ever falling?"}
E -->|"yes"| F["Likely a leak: roll back, restart on schedule as a stopgap, file a defect"]
E -->|"no, it spikes"| G["Limit too low for the real peak: raise limit and request"]
D --> H["Move pods off, add nodes, and lower overcommitment"]
Fix steps
Stop the bleeding
If a recent release started the kills, roll it back. If not, temporarily raise the memory limit and request to a safe higher value, and watch.
Look at the memory curve
A steady climb that never falls suggests a leak. A sawtooth that jumps with certain requests suggests an oversized workload or an unbounded cache.
Check runtime settings
Some runtimes, such as those that manage their own heap, need their internal limits tuned to the container limit. A mismatch causes kills even when the program thinks it has room.
Right-size permanently
After the incident, set requests and limits from measured peaks plus margin, and review at the next cycle.
If memory grows without bound, a bigger limit only delays the next kill. Treat a raised limit as a stopgap, and open a defect for the leak. Also remember that raising requests changes how pods pack onto nodes, which may need extra capacity.
Node-level pressure
Nodes report pressure conditions for memory, disk, and process counts. When pressure appears, the node’s agent starts evicting pods, beginning with those using more than they requested and of lower priority. Pods with no requests set are the most exposed. Setting honest requests for every container, and priorities for important services, protects them during pressure.
Production example: the cache that never shrank
A frequently told story involves a service with an in-memory cache that had no size limit. Under normal traffic memory settled, but a new feature increased the variety of requests, and the cache grew until the container was killed every few hours. The fix was a bounded cache, and the lesson was to alert on memory growth trend, not just on the kill.
14Runbook: Node NotReady
A node is a machine. When a node stops reporting that it is healthy, Kubernetes marks it NotReady and, after a delay, begins moving its pods elsewhere. This is both a protection and a source of trouble.
Symptom and impact
Symptom: one or more nodes show NotReady. Pods on them become unreachable, and later are rescheduled. Impact: lost capacity, and a burst of restarts as pods move. If several nodes fail together, replacements may not fit. Usual severity: three for one node, one or two for many at once.
The sequence of events
sequenceDiagram
participant N as Node agent (kubelet)
participant C as Control plane
participant P as Pods on the node
N->>C: Regular heartbeat
Note over N: Node problem begins
N--xC: Heartbeats stop
C->>C: Waits for a grace period
C->>C: Marks node NotReady and adds taints
C->>P: Evicts pods after the toleration period
C->>C: Creates replacement pods on other nodes
Diagnosis steps
How many nodes, and which?
One node suggests a machine fault. Many nodes, especially in one zone or one node pool, suggest a shared cause such as a network, cloud, or image change.
Read the node’s conditions
Describe the node. Look for memory, disk, or process pressure, and for the reason on the ready condition.
Check the machine in the cloud
Is the virtual machine running? Did the cloud provider schedule maintenance, retire the host, or terminate a spot node?
Check the node agent and runtime
If you can reach the machine, check that the node agent and container runtime are running, and read their logs for errors.
Check disk, memory, and processes
A full disk, an exhausted memory, or too many processes are common causes of a node that goes quiet.
Check connectivity to the control plane
The node may be healthy but cut off by a network, firewall, or certificate problem.
Mitigation and fix
| Finding | Action |
|---|---|
| Single node, hardware or host fault | Cordon and drain if possible, then delete the node and let the autoscaler or group replace it |
| Disk full | Free space by removing unused images and logs, or replace the node, and fix the cause such as noisy logging |
| Memory exhausted | Reduce load on the node, review pod requests, replace the node |
| Many nodes after a change | Roll back the change to node images, network, or configuration |
| Cloud-wide event | Check the provider’s status, shift load to healthy zones, and add capacity elsewhere |
Imagine a branch office that stops answering the phone. Head office waits a while, because the line may just be busy. Then it assumes the branch is down and reroutes customers to other branches. Your job is to find out whether the office is closed, the phone line is cut, or the staff are simply overwhelmed.
When many nodes fail, resist the urge to restart or replace them all together. Replace gradually, confirm each replacement joins and takes work, and keep enough capacity to absorb the pods that move. Draining too quickly can turn a partial failure into a full outage.
Production example: the bad node image
A pattern teams commonly report is a new node image rolled out to a pool, with a subtle fault such as a runtime setting that fails under load. Nodes join, look healthy, and later go NotReady one after another. The mitigation is to stop the rollout, shift the pool back to the previous image, and add a canary pool for future node image changes.
15Runbook: DNS Failures Inside the Cluster
Almost every request inside Kubernetes begins with a name lookup. When DNS misbehaves, many unrelated services seem to break at once, which is why DNS is a famous suspect.
Symptom and impact
Symptom: errors such as “could not resolve host”, intermittent timeouts to other services, slowness at the start of requests. Impact: widespread, because most service calls depend on names. Usual severity: one or two when it is cluster-wide.
DNS is the phone book of the cluster. If the phone book is missing, slow, or wrong, nobody can reach anyone, even though every phone works perfectly. All services look broken, but the real problem is a single shared book.
How lookups work, in brief
Each pod is configured to send name lookups to the cluster’s DNS service, which is run by a set of DNS pods. Those pods answer names for cluster services themselves, and forward other names to outside resolvers. A lookup can fail at the pod’s own settings, at the DNS pods, at the network between them, or at the upstream resolver.
flowchart LR
APP["Application pod"] --> RES["Pod resolver settings"]
RES --> SVC["Cluster DNS service"]
SVC --> DNSP["DNS pods"]
DNSP -->|"cluster names"| API["Cluster service records"]
DNSP -->|"outside names"| UP["Upstream resolver"]
Diagnosis steps
Are the DNS pods healthy?
Check that they are running, ready, and not restarting. Check their CPU and memory use, and their logs.
Test a lookup from a test pod
Start a small debugging pod and look up a cluster service name and an outside name. Compare the results to find which type fails.
Cluster names fail, outside names work
Suspect the service records, or the DNS pods’ connection to the control plane.
Outside names fail, cluster names work
Suspect the upstream resolver, or the route from DNS pods to it.
Both are slow or intermittent
Suspect overload of DNS pods, network packet loss, or limits on connection tracking on nodes.
Common causes and fixes
DNS pods overloaded
Too few replicas for the query rate. Scale them up, and consider a node-local DNS cache.
Query amplification
Default search settings cause several lookups per name. Using fully qualified names or tuning settings reduces load.
Network policy blocking
A new policy accidentally blocks traffic to the DNS pods. Check recent policy changes.
Upstream trouble
The outside resolver is slow or down. Check it and consider alternate resolvers.
Packet loss on nodes
Lookups use small, quick messages and suffer first when nodes drop packets. Check node network health.
Engineers joke that when something is mysteriously broken and many services are involved, it is DNS. Starting with a quick DNS test costs one minute and rules a very common culprit in or out.
Production example: scaling DNS with the cluster
Teams running large clusters commonly report that default DNS replica counts were fine at first and became a bottleneck as the cluster grew. They adopted automatic scaling of the DNS pods in proportion to cluster size, and a node-local cache to reduce load and latency, which removed a recurring source of intermittent errors.
16Runbook: A Service Is Unreachable
The pods look fine, yet clients cannot reach the service. This runbook walks the path a request takes, from the outside to the pod, and finds where it stops.
Symptom and impact
Symptom: timeouts, connection refused, or errors from the gateway such as “bad gateway” or “no healthy upstream”. Impact: users cannot use the feature, even though the application may be healthy. Usual severity: one or two for public services.
Follow the path of a request
flowchart LR
C["Client"] --> LB["External load balancer"]
LB --> ING["Ingress or gateway"]
ING --> SVC["Service"]
SVC --> EP["Endpoints: ready pods"]
EP --> POD["Pod and container"]
Check each hop, from the inside out
Does the pod answer directly?
From a debugging pod, call the pod’s own address and port. If this fails, the problem is the application, not the network.
Does the service have endpoints?
A service routes only to ready pods that match its selector. Empty endpoints mean no pod is ready, or the selector does not match the pod labels.
Does the service name answer inside the cluster?
Call the service by name from a test pod. If this works but outside access fails, the problem is further out.
Is the ingress or gateway healthy?
Check its pods, its rules, and its logs. Look for recent rule changes and for certificate errors.
Is the external load balancer healthy?
Check its health checks, its target list, and the cloud’s status. Misconfigured health checks often mark good targets as bad.
Are network policies or firewalls blocking?
A new policy or security rule can silently drop traffic. Check recent changes.
Think of a letter that never arrives. You check each step: was it posted, did the sorting office process it, did the local delivery office receive it, and does the address match the house? You test the last step first by asking whether the person at the house is home, then work backwards.
Typical findings
| Finding | Cause | Fix |
|---|---|---|
| Service has no endpoints | Pods not ready, or labels do not match | Fix readiness or correct selector labels |
| Pod answers, service does not | Wrong port mapping | Match the service target port to the container port |
| Service works inside, not outside | Ingress rule, load balancer, or certificate | Fix the rule, health check, or certificate |
| Works from some pods, not others | Network policy or one bad node | Adjust policy, or cordon the bad node |
| Intermittent failures | Some replicas unhealthy, or connection limits | Fix bad replicas, tune readiness, scale up |
A readiness check that is too strict can remove every pod from service at once during a slow dependency, turning a partial slowdown into a full outage. Readiness should reflect the pod’s own ability to serve, and not depend on every downstream service being perfect.
Production example: the selector typo
A classic and humbling incident is a label edited during a release so that it no longer matches the service selector. The pods run happily and pass their checks, but the service has no endpoints. Teams add an alert for “service with zero ready endpoints”, which catches this class of problem within a minute.
17Runbook: The API Server Is Slow or Unavailable
The control plane is the brain of the cluster, and the API server is its front door. When it struggles, commands hang, and nothing seems to change. Fortunately, running applications usually keep running.
Symptom and impact
Symptom: commands time out, dashboards show errors, deployments do not progress, autoscalers do not react. Impact: you cannot change anything, and failed pods are not replaced. Existing pods keep serving traffic, which is a comfort, but any new failure will not heal. Usual severity: one or two.
Imagine an airport whose control tower loses power. Planes already in the air keep flying and planes on the ground are fine, but no new instructions can be given, no gates reassigned, and no new problems handled. The airport is “up” but cannot adapt, which makes every other failure much riskier.
Who owns the control plane?
On managed services, the cloud provider operates the control plane, and your levers are limited. You can still check the provider’s status page, your own request patterns, and the components you installed. On self-managed clusters, you own all of it, including the machines and the datastore. The runbook should state clearly which case applies, because the available actions are very different.
Diagnosis steps
Is it everyone or just you?
Test from another network or another person. A local problem such as a credential expiry or a bad connection looks the same.
Check the provider status
For managed services, look for ongoing incidents in your region.
Check API server metrics
Look at request rate, error rate, latency, and the number of requests in flight. A sudden rise suggests a noisy client.
Find the heavy client
A misbehaving controller, a monitoring tool that lists everything too often, or a loop that creates and deletes objects can flood the server. Audit data or server metrics show the top callers.
Check admission webhooks
A slow or failing webhook blocks every create and update that it covers, and can make the whole cluster appear stuck.
Check the datastore health
On self-managed clusters, a slow or unhealthy datastore slows every request. See the next chapter.
flowchart TD
A["API slow or failing"] --> B{"Managed control plane?"}
B -->|"yes"| C["Check provider status, open a support case, reduce your own request load"]
B -->|"no"| D["Check API server, scheduler, controller manager, and datastore health"]
C --> E["Find heavy callers and stop them"]
D --> E
E --> F{"Webhook failing or slow?"}
F -->|"yes"| G["Fix or temporarily relax the webhook failure policy"]
F -->|"no"| H["Scale or repair control plane components"]
A validating or mutating webhook that is set to reject requests when it is unreachable can block the very pods needed to fix it. Design webhooks to exclude critical system namespaces and to fail safely, and write the emergency steps for disabling a webhook in your runbook ahead of time.
What still works
Remind the team that running pods continue to serve, existing connections continue, and node agents keep their pods alive using the last instructions they received. This knowledge prevents panicked restarts, which would be fatal since restarted pods cannot be recreated if the control plane is down. The rule during a control plane problem is: do not make it worse by disturbing healthy workloads.
Production example: a monitoring tool floods the API
Teams have reported incidents where a newly installed tool listed all objects in the cluster every few seconds, loading the API server until other clients timed out. The fix was to throttle the tool and use watch-based access, and the lasting improvement was server-side rate limiting policies and an alert on the top callers by request volume.
18Runbook: The Datastore (etcd) Is Unhealthy
Behind the API server sits a small, careful database called etcd, which stores the entire state of the cluster. If you use a managed service, the provider runs it for you. If you run your own cluster, this runbook can save your cluster.
Why it matters so much
Everything Kubernetes knows is stored in this datastore: every object, every secret, every setting. It uses a voting system among several members, and needs a majority to accept changes. If a majority is lost, the cluster can no longer change anything. If the data is lost or corrupted without a backup, the cluster’s memory is gone.
Think of a committee of five people that keeps the official minutes of an organization. Decisions are valid only if at least three agree. If two members are away, it still works. If three are away, no decisions can be recorded until some return. And if every copy of the minutes is lost, nobody remembers what the organization decided.
Symptoms
Slow writes
The API server is slow to accept changes. Datastore latency metrics rise, often because of slow disks.
Leader changes
Frequent changes of the leading member suggest network or disk trouble among members.
Space alarm
The datastore has a size limit. When it fills, it stops accepting writes until it is cleaned up and the alarm is cleared.
Lost majority
Too many members are down, so the cluster is read-only or frozen.
Runbook steps for self-managed clusters
Check member health and count
How many members are healthy and reachable? Do you still have a majority?
Check disk latency
This datastore is very sensitive to slow disks. Slow disks cause missed heartbeats and leader changes. Use fast, dedicated storage.
Check size and alarms
If the database is near its limit, find which objects are growing, such as events or custom resources, then compact and defragment following the official procedure.
Restore the failed member
Replace or repair a lost member and let it rejoin, following your tested procedure.
Restore from backup only as a last resort
If a majority is permanently lost, restore from the most recent backup, accepting the loss of newer changes.
Restoring a datastore from backup affects the entire cluster and can lose recent changes. Never do this for the first time during an incident. Practice the full restore on a test cluster regularly, record how long it takes, and make sure the backups are recent, stored outside the cluster, and encrypted.
Prevention
Good habits
- Automatic, frequent backups stored off the cluster.
- Regular restore drills.
- Alerts on size, latency, and leader changes.
- An odd number of members, spread across zones.
Risky habits
- Never testing restores.
- Storing backups on the same machines.
- Letting events and custom objects grow unchecked.
- Running the datastore on slow shared disks.
Production example: the full datastore
Operators of self-managed clusters have described outages where a runaway controller created huge numbers of objects, filling the datastore until writes were rejected. Recovery required removing the objects, compacting the datastore, and clearing the alarm. They now alert at seventy percent of capacity and cap the object counts that controllers may create.
19Runbook: A Bad Deployment and the Rollback
Most incidents begin with a change. This runbook covers the single most useful mitigation in all of operations: undoing the change.
Symptom and impact
Symptom: errors, latency, or crashes that began shortly after a release or configuration change. Impact: depends on how many replicas have the new version. Usual severity: depends on traffic share affected.
How a rolling update behaves
A Deployment replaces old pods with new ones gradually. It starts a few new pods, waits for them to become ready, then removes old ones. If the new pods never become ready, the rollout stalls, and the old pods keep serving. That is a safety feature. The danger is a bad version that does pass the readiness check but behaves badly, because then the rollout completes and the bad version takes over.
sequenceDiagram
participant R as Release pipeline
participant D as Deployment
participant O as Old pods
participant N as New pods
R->>D: New version declared
D->>N: Start a few new pods
N-->>D: Become ready
D->>O: Remove a few old pods
Note over N: Errors begin to rise
R->>D: Roll back to the previous version
D->>O: Start old pods again
D->>N: Remove new pods
The rollback steps
Confirm the link to the change
Compare the start of the problem with the time of the release. Check whether a release is still in progress.
Pause the rollout
Stop further pods from being replaced, to limit the damage while you decide.
Announce the rollback
Say in the incident channel what you are doing and which version you will return to.
Roll back
Use your normal pipeline to deploy the previous version if you use declarative delivery, or use the built-in rollback command if it is safe in your setup. Prefer one path, so the delivery tool and the cluster agree.
Watch the recovery
Confirm that the error rate and latency return to normal, and that old pods are fully ready.
Freeze releases
Block new deployments until the cause is understood, so a second change does not complicate the picture.
A rollback is easy when the change is only code. It is risky when the release also changed data, such as a database migration that old code does not understand. Good runbooks name which services have irreversible migrations, and the release process should keep changes backward-compatible so that rollback stays safe.
It is the “undo” button. If you changed a document and it broke the layout, you undo first and investigate later. The one case where undo is dangerous is when you have already deleted the original file, which is the equivalent of a one-way data migration.
Ways to make rollbacks fast
Gradual releases
Release to a small share of traffic first, watch, then widen. A bad version then harms few users.
Automatic rollback
Some delivery tools watch error rates and stop or reverse a release by themselves when a threshold is crossed.
Feature flags
Switch off a new feature without redeploying, which is the fastest rollback of all.
Keep old versions available
Retain the previous images and revision history so a return is one step.
Production example: roll back first
Reliability teams at large companies teach a simple rule: if a change happened recently and a problem followed, roll back without waiting for proof. A mistaken rollback costs a few minutes. A long investigation during an outage costs far more.
20Runbook: Expired Certificates
Certificates are the quiet time bombs of the platform. They work perfectly for a year and then, at an exact second, everything that relied on them stops.
Symptom and impact
Symptom: sudden errors mentioning “certificate has expired” or “x509”, across many components at once, or a public site showing a browser warning. Impact: can be total. Expired control plane certificates can stop the cluster from functioning. Expired ingress certificates make sites unreachable for users. Usual severity: one.
A certificate is like a passport with an expiry date. The traveler has not changed and the airline has not changed, yet at midnight on the expiry date the passport stops being accepted. Nothing broke. A date arrived.
Where certificates live in a cluster
| Place | What it protects | Who renews it |
|---|---|---|
| Control plane certificates | Communication between control plane parts and with node agents | Provider on managed services, cluster tooling or you on self-managed ones |
| Node agent certificates | Node identity toward the control plane | Usually rotated automatically if enabled |
| Ingress and public certificates | Traffic from users to your sites | A certificate manager tool, if configured, or a person |
| Service mesh certificates | Encrypted traffic between services | The mesh, with short lifetimes |
| Webhook certificates | The API server’s trust of admission webhooks | Often a certificate manager, or the webhook’s own logic |
Steps
Identify which certificate
Read the error carefully. It names the host or component. Inspect the certificate’s dates.
Renew it
Use the certificate manager or the cluster’s renewal procedure. For public certificates, trigger a new issue.
Reload the consumers
Many components read certificates only at startup, so restart or reload them in a safe order after renewal.
Verify from the outside
Check from a fresh client that the new certificate is served and trusted.
Find out why it was missed
Was renewal automatic and broken, or manual and forgotten? Fix the process so that it cannot happen again.
Prevention that works
- Automatic renewal with a certificate manager.
- An inventory of every certificate and its owner.
- Alerts at thirty, fourteen, and seven days before expiry.
- A yearly rehearsal of the control plane renewal.
Things that cause surprise
- Manually created certificates that nobody tracks.
- Renewal that succeeds but consumers are never reloaded.
- Clusters upgraded rarely, since upgrades often renew control plane certificates.
Production example: the anniversary outage
Many teams recall an outage that occurred exactly one year after the cluster was built, when certificates created at that time all expired together. The cure was a certificate inventory with expiry alerts, and a habit of upgrading clusters at least once a year, which renews many certificates on the way.
21Runbook: Storage and Volume Problems
Stateless pods are easy to replace. Pods with data are not. When a disk cannot attach, fills up, or sits in the wrong place, the pod waits, and so do your users.
Symptom and impact
Symptom: pods stuck in ContainerCreating or Pending with messages about volumes, claims stuck in Pending, applications failing to write, or “no space left on device”. Impact: stateful services such as databases, queues, and caches are down or read-only. Usual severity: one or two, because data is involved.
A pod is like a worker and a volume is like their locked filing cabinet. The worker can be replaced at any desk, but the cabinet must be wheeled to the new desk. If the cabinet is in another building, or still chained to the old desk, the new worker cannot start.
The pieces involved
Claim
A request for storage made by an application. It stays Pending until a matching disk is found or created.
Volume
The actual disk, usually created in the cloud on demand through a storage class.
Storage class
The recipe that says what kind of disk to create and how to treat it when deleted.
Attachment
The act of connecting a cloud disk to a particular node. Many disks attach to only one node at a time.
Diagnosis
flowchart TD
A["Pod waiting on storage"] --> B{"Is the claim bound?"}
B -->|"no"| C["Check storage class, provisioner health, cloud quota, and zone"]
B -->|"yes"| D{"Is the volume attached to a node?"}
D -->|"no"| E["Check attach errors, zone match, and whether the old node still holds it"]
D -->|"yes"| F{"Is the disk full or read-only?"}
F -->|"full"| G["Free space or expand the volume"]
F -->|"read-only"| H["Check filesystem errors and node health"]
F -->|"fine"| I["Check application and permissions"]
Common causes and fixes
| Finding | Cause | Fix |
|---|---|---|
| Claim stays Pending | No matching class, provisioner down, or cloud quota hit | Fix the class, repair the provisioner, raise the quota |
| Pod cannot be placed with its volume | Disk is in one zone, but available nodes are in another | Add capacity in that zone, and use delayed binding so disks are created where pods land |
| Disk will not attach to a new node | Still attached to a dead node | Wait for the cloud to detach, or force detach with care, after confirming the old node is truly gone |
| No space left on device | Data or logs filled the disk | Expand the volume if supported, clean old data, set retention |
| Filesystem read-only | Errors caused the system to protect the disk | Restart the pod on a healthy node, check disk health, restore if needed |
If two nodes write to the same disk, data can be corrupted. Before forcing a disk away from a node, confirm the node is really stopped. When in doubt, escalate to someone who owns the storage layer, and protect data first, availability second.
Backups are part of the runbook
Every stateful runbook should say where the latest backup is, how recent it is, and how to restore it. A storage incident that turns into data loss is much worse than an outage. Regular snapshots and restore tests are the real mitigation for the worst case.
Production example: the zone-bound disk
A commonly reported incident involves a database pod whose disk lives in one zone. When that zone’s nodes were drained for maintenance, the pod could not start in another zone, because its disk could not follow. Teams respond by keeping spare node capacity in every zone that holds a stateful workload and by using storage that replicates across zones where the application needs it.
22Runbook: Capacity Exhaustion and Autoscaler Failures
Sometimes there is simply too much demand for the capacity you have, or the machinery that adds capacity has stopped working. This runbook handles both.
Symptom and impact
Symptom: rising latency under load, pods pending, autoscalers at their maximum, CPU throttling, or queues growing. Impact: a gradual slide into an outage as demand exceeds supply. Usual severity: two, rising to one if load keeps growing.
Think of a supermarket on a holiday eve. The manager normally opens more checkout lanes as the line grows. If the staff are all busy, or the manager forgot to call extra staff, the line grows until customers leave. Autoscaling is the manager, and it has to be both awake and able to find staff.
The chain of scaling, and where it breaks
flowchart TD
L["Load rises"] --> M["Metrics collected"]
M --> H["Horizontal autoscaler decides more pods"]
H --> P["New pods created"]
P --> S["Scheduler finds room"]
S -->|"no room"| N["Node autoscaler adds machines"]
N --> C["Cloud provides machines"]
C --> R["Pods start and become ready"]
Check each link
| Link | Check | Typical fault |
|---|---|---|
| Metrics | Is the metrics system reporting current values? | Metrics gap makes the autoscaler blind, so it does nothing |
| Pod autoscaler | Is it at its maximum? Are its conditions healthy? | Maximum too low, or target set at the wrong signal |
| Pod creation | Are pods created and not blocked by quotas? | Namespace quota exhausted |
| Scheduling | Why are pods pending? | Requests too large, rules too strict |
| Node autoscaler | Is it running? Did it hit its maximum or an error? | Node pool maximum, permissions problem |
| Cloud capacity | Can machines of that type be created? | Quota reached, or machine type unavailable in the zone |
| Startup | How long until new pods are ready? | Slow image pulls or slow application start |
Mitigation while you diagnose
Add capacity manually
Raise the pod count and the node pool size by hand, within the cloud quota, to relieve pressure at once.
Reduce the load
Where possible, shed low-priority traffic, pause batch jobs, and enable caching or degraded modes to protect core features.
Protect important pods
Pod priorities let critical services keep their place when the cluster is full, by evicting lower priority work.
Open a quota request
If the cloud quota is the limit, request an increase immediately, since approval may take time.
A service that can turn off its less important features under pressure, such as recommendations on a shopping page, can keep the essential paths working. Write the list of what can be switched off, in order, into your capacity runbook.
Production example: the pre-event capacity review
Teams that run for large events, such as ticket sales or major sports matches, usually schedule a review before the event. They raise maximums, pre-scale key services, request cloud quota ahead of time, and rehearse the scaling chain under test load. Many describe this as the cheapest insurance they buy.
23Runbook: A Suspected Security Incident
Not every incident is an accident. Sometimes a container is compromised, a credential leaks, or a strange workload appears. Security runbooks have a different priority: contain first, preserve evidence, then clean up.
Symptom and impact
Symptom: unknown pods or workloads, unexpected outbound traffic, sudden high CPU from mining software, alerts from security tools, unfamiliar changes by a service account, or leaked credentials found in public places. Impact: potential data theft, further spread, and legal obligations. Usual severity: one or two, until proven harmless.
If you find that someone has broken into an office, you do not tidy up first. You secure the doors, keep the scene as it is for investigators, and then repair. In an outage you are in a hurry to restore. In a security incident you are in a hurry to contain without destroying evidence.
Containment without destruction
Call the security contact
Involve the people responsible for security and legal matters right away, per your policy. Do not handle it alone.
Isolate the workload
Apply a restrictive network policy or label that cuts the suspect pod from the network, without deleting it. This stops spread and data leaving, while keeping memory and disk state.
Preserve evidence
Capture logs, the pod’s description, running processes if possible, and a copy of the node’s relevant data, before anything is removed.
Revoke what may be stolen
Rotate credentials, tokens, and secrets that the workload could read. Remove the workload’s permissions.
Find the way in
Look for the entry point: a vulnerable image, an exposed service, a stolen credential, or an overly broad permission.
Rebuild cleanly
Replace affected workloads and nodes from trusted images, rather than trying to clean them in place.
flowchart LR
A["Suspicious signal"] --> B["Involve security"]
B --> C["Isolate: cut network, keep the workload"]
C --> D["Preserve logs and state"]
D --> E["Revoke credentials and permissions"]
E --> F["Find entry point and scope"]
F --> G["Rebuild from trusted sources"]
G --> H["Review and harden"]
Questions to answer
Scope questions
- Which workloads and nodes were touched?
- Which secrets and permissions could the attacker use?
- Did the attacker reach the cloud account or other clusters?
Common mistakes
- Deleting the pod and losing the evidence.
- Rotating only one secret and missing others.
- Cleaning in place instead of rebuilding.
- Discussing details in wide public channels.
Security runbooks depend on tools and permissions set up in advance: audit logging turned on, the ability to isolate by network policy, and a list of secrets per workload. If these are missing during the incident, you cannot create them in time.
Production example: the exposed dashboard
Industry reports on cloud attacks have repeatedly described clusters compromised through an exposed management interface or an over-permissive service account, followed by cryptocurrency mining software. Defenders emphasize least-privilege permissions, no public management endpoints, and alerts on unusual outbound traffic and CPU use.
24Communication During an Incident
Good technical work can be ruined by poor communication. Silence makes people anxious, and rumor fills the gap. A runbook for communication is as important as one for pods.
Who needs to hear what
| Audience | What they need | How often |
|---|---|---|
| Responders | Facts, current actions, and assignments | Continuously, in the incident channel |
| Internal stakeholders and leadership | Impact, current status, estimated next update | Per severity rhythm |
| Support and sales teams | What to tell customers, workarounds | On every material change |
| Customers | What is affected, that you are working on it, when the next update will come | On a steady rhythm, even if there is nothing new |
Think of a delayed flight. Passengers are most upset not by the delay, but by silence. An announcement every fifteen minutes saying “we are still waiting for the part, next update at three” keeps people calm, even though nothing has changed.
A good status update has five parts
What is happening
One plain sentence about the problem and who is affected.
Impact
What users cannot do, and any workaround.
What we are doing
The current action, without technical overload.
What we know and do not know
State facts, and mark unknowns as unknown. Do not guess the cause aloud.
Next update time
Promise a time and keep it, even if the news is “no change”.
Good communication
- Plain words, no blame, no guessing.
- Regular rhythm.
- One person owns outside messages.
- A final message that confirms recovery and promises a review.
Poor communication
- Silence until it is fixed.
- Technical jargon for customers.
- Promising a fix time that is only hope.
- Many voices giving conflicting facts.
Keep ready-made message templates for the first notice, the update, and the resolution. A communications lead who only has to fill in the blanks sends clear messages quickly, even while stressed.
Production example: the public status page
Software companies of all sizes maintain a public status page, updated by the communications lead during incidents. Customers value honest, timely updates, and many companies report that clear communication during an outage builds more trust than the outage costs.
25Alerts That Lead to Runbooks
A runbook nobody finds is useless. The link between an alert and its runbook is what turns documents into response. This chapter covers how to design alerts so that they help rather than overwhelm.
Alert on symptoms, not causes
The best alerts describe what users feel: high error rate, high latency, failed checkouts. Alerts on causes, such as “CPU is above eighty percent”, fire often without any harm and train people to ignore them. Cause-level signals are better kept as dashboards and as diagnostic steps inside runbooks. A few high-quality symptom alerts, each with a runbook, beat hundreds of noisy ones.
A smoke alarm that rings every time you make toast is soon switched off, and then it is useless in a real fire. An alert system is only as good as the trust people have in it. Every false alarm spends some of that trust.
What every alert should carry
A clear name
The name describes the symptom in plain words, so it matches the runbook title.
Severity
Whether to wake someone now or look in the morning.
A runbook link
Direct to the page, not to a general wiki.
Context
Which service, cluster, region, and a link to the right dashboard.
An owner
The team that responds, so the page goes to a person who can act.
Page only when action is needed
| Question | If yes | If no |
|---|---|---|
| Are users, or soon will be, harmed? | Page a human | Create a ticket or dashboard item |
| Can a person do something useful right now? | Page a human | Log it, or automate the response |
| Is it urgent, or can it wait until morning? | Page now | Notify in a channel for the next day |
Useful symptom alerts for a cluster
Worth paging for
- User-facing error rate or latency above target for several minutes.
- Service with zero ready endpoints.
- Pods pending for longer than a set time.
- Nodes not ready beyond a threshold share.
- Certificate expiry within days.
- Control plane unavailable.
Better as dashboards or tickets
- Single pod restart.
- High CPU without user impact.
- Disk at seventy percent.
- Minor, self-healing flaps.
Look at which alerts fired most, which led to action, and which were ignored. Delete or retune alerts that nobody acts on. Each removed noisy alert makes the remaining ones more believable.
Production example: service level objectives
Many reliability teams define service level objectives, such as the share of requests that must succeed, and alert on how fast the error budget is being consumed. This ties paging to user impact and avoids alerts on harmless fluctuations, and each alert maps naturally to one runbook.
26Automating Runbooks Safely
Once a runbook is stable and well understood, many of its steps can be done by machines. Automation is the natural next step, but it carries its own risks.
The automation ladder
| Level | Description | Example |
|---|---|---|
| 0. Document only | A person reads and acts | Written steps for a rare failure |
| 1. Automated diagnosis | A script gathers evidence and shows it to the responder | A button that collects pod descriptions, events, and logs into the incident channel |
| 2. One-click actions | A person approves, a machine performs the action | A chat command to restart a stuck component or scale a deployment |
| 3. Automatic remediation with limits | A machine acts on its own within strict bounds, and tells people | Replace a node that stays NotReady for a set time |
| 4. Self-healing by design | The system is built so the failure does not need action | Multiple replicas, disruption budgets, automatic rollbacks |
Think of driving. First you read a paper map yourself. Then a navigation app suggests turns. Then cruise control holds your speed while you watch. Finally a car can brake automatically in an emergency. At each step, trust is earned by proving the system behaves well in the cases you tested.
Start with diagnosis automation
The safest and most valuable first automation is gathering evidence. A responder who receives the pod states, recent events, recent deployments, and key graphs in one message saves several minutes and nothing can go wrong, because the automation only reads. Many teams build this as a chat command or as an enrichment attached to each alert.
Rules for automatic remediation
Automate only well-understood failures
If humans still debate the cause, the machine will act on a guess.
Set hard limits
Limit how many actions can happen in an hour, how many nodes can be replaced at once, and which namespaces are covered.
Make actions reversible or low-risk
Restarting a pod is low risk. Deleting data is not. Never automate irreversible actions without human approval.
Always notify
Post every automated action to a visible channel, with the reason, so humans see patterns and are never surprised.
Provide a kill switch
Anyone on call must be able to disable the automation quickly if it misbehaves.
Escalate when it does not work
If the automatic fix fails or the problem returns, page a human instead of retrying forever.
flowchart TD
A["Alert fires"] --> B["Automation gathers evidence"]
B --> C{"Known failure with safe fix?"}
C -->|"yes"| D{"Within rate limits and scope?"}
C -->|"no"| H["Page a human with the evidence attached"]
D -->|"yes"| E["Apply the fix and notify the channel"]
D -->|"no"| H
E --> F{"Did the signal recover?"}
F -->|"yes"| G["Close and record"]
F -->|"no"| H
A faulty automatic fix can spread across a whole fleet in seconds. Several well-known outages were made far worse by automation that kept repeating a harmful action. Rate limits and scope limits exist to keep a small bug small.
Production example: operators as automated runbooks
The Kubernetes Operator pattern is, in essence, a runbook turned into software. An operator for a database encodes steps such as failing over to a replica or taking a backup, and runs them continuously. Teams that adopt well-tested operators effectively delete whole sections of their manual runbooks, though they still need runbooks for when the operator itself misbehaves.
27Practice: Game Days, Drills, and Testing Runbooks
A runbook that has never been used is a theory. Practice turns it into a tool, and reveals the steps that no longer work.
Why untested runbooks fail
Commands change
Tools and versions change, so a command written last year may no longer work.
Access gaps
The responder may not have permission to do a step, and learns this only at three in the morning.
Hidden assumptions
The author knew things that the reader does not, and left them out.
Moved dashboards
Links break as tools are reorganized.
Ways to practice
| Method | What it is | Best for |
|---|---|---|
| Tabletop exercise | The team talks through a scenario around a table, with no real systems touched | Roles, communication, and decisions |
| Runbook walkthrough | A new engineer follows the steps in a safe environment while the author watches | Finding unclear or outdated steps |
| Game day | The team deliberately breaks something in a test or controlled production environment and responds | End-to-end readiness, including alerts |
| Chaos experiments | Small, automated faults such as terminating pods or adding network delay, run regularly | Proving the system tolerates known failures |
| Restore drill | Recover a backup into a clean environment and measure the time | The most dangerous runbooks |
It is a fire drill in a building. Everyone knows the plan in theory. Only the drill reveals that a door is locked, the assembly point is too small, or the alarm cannot be heard on the third floor. You want to learn this on a calm Tuesday, not during a real fire.
How to run a good game day
Pick one scenario
Choose a realistic failure with a matching runbook, such as a node pool going NotReady.
Define the safety limits
Decide in advance what would cause an immediate stop, and who can call it.
Inject the failure
A facilitator starts the failure without telling the responders exactly what it is.
Respond using only the runbook
Responders work as in a real incident. Observers note every moment where the runbook helped or failed.
Debrief and update
Immediately list fixes: wrong commands, missing steps, unclear alerts. Assign owners and dates.
What to measure
- Time from alert to the first correct action.
- Number of steps that needed correction.
- Whether alerts linked to the right runbook.
- Whether people felt confident.
What to avoid
- Surprising people with a real outage disguised as a test.
- Punishing mistakes made during the drill.
- Testing without a clear way to stop.
- Skipping the debrief.
Record the date the runbook was last tested and by whom. Any runbook not tested in a set period, such as six months, is marked as unverified. This honesty tells responders how far to trust it.
Production example: regular failure injection
Companies known for chaos engineering practice regularly terminate instances and inject delays in production, within strict limits, to verify that their systems and runbooks behave as expected. They report that frequent small failures prevent the rare large ones, because weaknesses are found while the stakes are low.
28After the Incident: Postmortems That Improve Runbooks
An incident that teaches nothing will repeat. The postmortem is the step that turns pain into improvement, and the runbook is where much of that improvement should land.
What a blameless postmortem is
A postmortem is a written review of what happened, why it happened, how it was handled, and what will change. Blameless means that it looks for weaknesses in the system and process, not for a person to punish. People make mistakes in every system. A good system makes mistakes hard to make, easy to spot, and cheap to undo.
Aviation investigates crashes to find what made the accident possible, such as confusing controls or unclear procedures, and then changes the design and checklists. Pilots are not simply told to “be more careful”. That approach, repeated for decades, is a big reason flying became so safe.
Parts of a useful postmortem
Summary and impact
What happened, how long, who was affected, and what it cost.
Timeline
A list of times and events from the scribe: when it began, was detected, was mitigated, and was resolved.
Root causes and contributing factors
Why it happened, usually several causes working together, such as a change, a missing check, and a gap in alerts.
What went well and what did not
Include good decisions and luck, since both are worth knowing.
Action items
Specific tasks, each with an owner and a date, ranked by value.
Feeding the runbooks
flowchart LR
I["Incident"] --> P["Postmortem"]
P --> RB["Update or create runbooks"]
P --> AL["Improve alerts and detection"]
P --> AU["Automate repeated steps"]
P --> DS["Fix the design weakness"]
RB --> G["Next incident is shorter"]
AL --> G
AU --> G
DS --> G
Questions that improve runbooks
Did the alert link to a runbook?
If not, add the link. If the runbook was wrong, correct it.
Which step cost the most time?
Find ways to make that step faster, clearer, or automatic.
What did responders wish they had known?
Add that knowledge to the runbook.
Could this have been prevented?
Prefer permanent fixes over longer checklists, where possible.
A runbook is a bridge. Over time, the best response to a frequent incident is to remove the cause or automate the cure. Track which runbooks are used most, and treat heavy use as a signal about where to invest in a permanent fix.
Production example: public postmortems
Several large cloud and technology companies publish postmortems of major outages, describing causes and corrective actions in plain language. Engineers across the industry study them, and many runbook ideas in this chapter, such as testing restores and guarding against webhook lockouts, come from lessons first shared this way.
29Anti-Patterns and Decision Records
An anti-pattern is a habit that looks sensible but leads to trouble. Each one below is written as a short decision record: why people choose it, what goes wrong, and what to do instead.
Why teams do it
Authors want to be complete, and explain every background detail in one page.
What goes wrong
Nobody reads it during an outage. The key step is buried on page six.
Better choice
Keep the main path short, and link the background reading separately. One action per step.
Why teams do it
After the effort of writing, the document feels finished.
What goes wrong
Commands rot, permissions change, and links break. The first real use reveals all the faults at the worst moment.
Better choice
Test with walkthroughs and game days, and record the last tested date.
Why teams do it
One expert always saves the day, so knowledge stays in their head.
What goes wrong
That person burns out or goes on holiday, and nobody else can respond.
Better choice
Ask experts to write down what they do, and let newer engineers lead incidents with the expert advising.
Why teams do it
Adding alerts is easy. Writing guidance takes thought.
What goes wrong
The responder gets a page with no idea what it means, and loses precious minutes.
Better choice
Do not create a paging alert until it has a linked runbook, even a short one.
Why teams do it
Restarting feels like action and sometimes hides the symptom.
What goes wrong
Evidence is destroyed, the cause is never found, and the problem returns.
Better choice
Capture the pod’s description, logs, and previous logs first, then act.
Why teams do it
Engineers like to understand a problem fully before touching anything.
What goes wrong
Users suffer for as long as the investigation takes, when a rollback would have ended the pain in minutes.
Better choice
Mitigate first with a rollback, scale-up, or traffic shift. Investigate after the service is healthy.
Why teams do it
A script that fixes a problem is celebrated and spread widely.
What goes wrong
When the script is wrong or the conditions change, it repeats a harmful action everywhere, quickly.
Better choice
Add rate limits, scope limits, notifications, and a kill switch, and escalate to humans on failure.
30A Quick Reference and Starter Plan
To finish the practical part, here is a one-page map from symptom to runbook, and a plan for building your own library from nothing.
Symptom to runbook
| You see | Start with | Chapter |
|---|---|---|
| Any alert, unsure where to start | Universal first five minutes | 8 |
| Pods restarting again and again | CrashLoopBackOff | 10 |
| Pods never get placed | Pending pods | 11 |
| Pods cannot download images | Image pull failures | 12 |
| Containers killed, nodes under pressure | Out of memory | 13 |
| Nodes marked NotReady | Node NotReady | 14 |
| Name lookup errors across services | DNS failures | 15 |
| Healthy pods but users cannot connect | Service unreachable | 16 |
| Commands hang, nothing changes | API server | 17 |
| API slow with a self-managed datastore | etcd health | 18 |
| Problems right after a release | Bad deployment and rollback | 19 |
| Sudden certificate errors | Expired certificates | 20 |
| Disks will not attach or are full | Storage problems | 21 |
| Rising load, pods pending | Capacity and autoscaler failures | 22 |
| Unknown workloads, odd traffic | Suspected security incident | 23 |
Build your library in this order
Week one: the universal triage page
Write and share the opening sequence. It helps with every alert from the first day.
Weeks two to four: your top five incidents
Look at the last year of pages. Write runbooks for the five most common, even short ones.
Month two: links and templates
Attach each runbook to its alert. Create a standard template and message templates.
Month three: practice
Run a tabletop and one game day. Fix what breaks.
Ongoing: learn and automate
After each incident, update runbooks. Automate the evidence gathering, then the safe fixes.
flowchart TD
A["Few or no runbooks today"] --> B["Write universal triage"]
B --> C["Write top five from real incidents"]
C --> D["Link every paging alert to a runbook"]
D --> E["Practice with drills and game days"]
E --> F["Improve after each incident"]
F --> G["Automate the safe parts"]
G --> F
Do not try to write fifty runbooks in advance. Write the ones your own incidents prove you need. A short, tested, linked runbook beats an exhaustive document that nobody trusts.
31Frequently Asked Questions
These are the questions people ask most often when they begin to build incident response runbooks for Kubernetes.
32Summary and Key Takeaways
We began with a pilot reaching for a checklist when an alarm sounds. An incident runbook is that same checklist, written calmly in advance so that a tired person can do the right thing in the right order.
What to remember
- A runbook starts at the symptom. It is short, numbered, tested, and linked from the alert, with decision points, warnings, a time limit, and a named escalation path.
- Mitigate before you resolve. Roll back, scale up, or move traffic to stop user pain first, and investigate the deeper cause once the service is healthy.
- Use the same first five minutes every time. Confirm impact, ask what changed, check the blast radius, read status, events, and logs, and preserve evidence before deleting anything.
- Think in layers. One service broken points to the application and pods. Many services broken points to nodes, networking, DNS, the control plane, or the cloud.
- Know the common failures. Restart loops, pending pods, image pulls, memory kills, node trouble, DNS, unreachable services, the API server, the datastore, bad releases, certificates, storage, capacity, and security each have a short, repeatable path.
- Roles and communication matter as much as commands. A commander, an operations lead, a communications lead, and a scribe, plus regular honest updates, keep an incident calm.
- Practice, learn, and automate carefully. Test with drills and game days, run blameless postmortems that feed the runbooks, and automate safe steps with limits, notifications, and a kill switch.