kubernetes-production-readiness
Skill0 starsChanged 2 months agoApache-2.0View on GitHub
Review a Kubernetes workload before it carries production traffic - probes, resource requests and limits, replica count and spread, PodDisruptionBudgets, graceful shutdown, rollout strategy, security context, image pinning, and observability. Use when reviewing a manifest or Helm chart, onboarding a service to production, or answering whether a deployment is safe to ship.
In this repository26 other files it gives its agents.
- AGENTS.mdAGENTS.md
- aws-production-debuggingSkill
- github-actions-debuggingSkill
- postgresql-troubleshootingSkill
- container-image-reviewSkill
- docker-debuggingSkill
- incident-triageSkill
- postmortem-analysisSkill
- production-debuggingSkill
- kubernetes-networkingSkill
- kubernetes-resource-debuggingSkill
- kubernetes-troubleshootingSkill
- linux-network-debuggingSkill
- linux-performanceSkill
- linux-troubleshootingSkill
- dns-troubleshootingSkill
- http-debuggingSkill
- tls-debuggingSkill
- observability-debuggingSkill
- prometheus-troubleshootingSkill
- slo-designSkill
- secrets-management-reviewSkill
- technology-jobSkill
- terraform-reviewSkill
- terraform-safe-changesSkill
- terraform-troubleshootingSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 6 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 56
Rank findings by blast radius,: not by how easy they are to fix.
- Distinctive: line 59
Verify: after the change by exercising the failure the change was meant to survive.
- Distinctive: line 142
If it reports that a PDB blocks eviction, you have found a workload that will stall your next cluster upgrade — before the upgrade, rather …
- Distinctive: line 214
Verify by exercising the failure the change was meant to survive, not by re-reading the manifest.
- Very specific: line 227
Run a client-side request loop through the ingress during the rollout restart.
- Very specific: line 233
Bad: Add a liveness probe pointing at the same /healthz as readiness.
- Distinctive: line 239
Better: Check where they are. Three replicas on one node survive nothing.
- Distinctive: line 250
Bad: Treat this checklist as a gate to pass once.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Kubernetes Production Readiness
Review a workload against the failures that actually take services down: node loss, rollouts, restarts, and saturation.
Purpose
Use this when:
- Reviewing a Deployment, StatefulSet or Helm chart before it takes production traffic.
- A service exists in production and nobody has ever checked it against a baseline.
- A post-incident action item is "make this service more reliable" and you need a concrete list.
Do not use this when:
- The workload is currently broken — fix it first with
kubernetes-troubleshooting. Readiness review is for healthy services. - The question is about cluster or platform readiness (control plane HA, upgrade strategy, backup of etcd) rather than about a workload. That is a different review.
What this skill assumes: access to the manifests (Git, Helm values, or the live objects), and
a stated environment. A review of kubectl get -o yaml output misses defaults applied by admission
controllers, so prefer reviewing both the source manifest and the live object.
Operating Procedure
- Get the real manifest. Render Helm (
helm template) or fetch the live object. Review what is deployed, not what someone believes is deployed. - Classify the workload. Stateless request-serving, stateful, batch, and singleton workloads have different correct answers. Applying stateless advice to a StatefulSet causes data loss.
- Walk the checklist below in order. Record each item as pass, fail, or not-applicable with a reason — "not applicable" without a reason is a fail.
- Rank findings by blast radius, not by how easy they are to fix. A missing PodDisruptionBudget on a two-replica service is a real outage during the next node upgrade; a missing label is not.
- Propose changes as manifest diffs, with the rollout risk of each stated.
- Verify after the change by exercising the failure the change was meant to survive.
Everything not visible in the manifest — the actual startup time, the real memory peak, whether SIGTERM is handled — is an Assumption until measured. Say so.
Investigation
Step 1 - render what is actually deployed
helm template <release> <chart> -f <values.yaml> > /tmp/rendered.yaml
kubectl get deployment <name> -n <namespace> -o yaml > /tmp/live.yaml
diff <(yq -P 'sort_keys(..)' /tmp/rendered.yaml) <(yq -P 'sort_keys(..)' /tmp/live.yaml) | head -50Differences between rendered and live are the most interesting output of this entire review: they are either a mutating admission webhook (a sidecar injector, a policy engine) or drift from a manual change that the next deploy will silently erase.
Step 2 - the checklist
Availability
| Check | Why it matters | Failure it prevents |
replicas >= 2 for request-serving workloads | One replica means every restart is downtime | Node loss, rollout, eviction |
topologySpreadConstraints across nodes, ideally zones | Replicas on the same node die together | Node or zone loss |
PodDisruptionBudget with minAvailable < replicas | Without one, a drain evicts everything at once | Node upgrade, cluster autoscaler |
maxUnavailable and maxSurge deliberate, not default | Defaults are 25% each; on 2 replicas that is 1 | Capacity dip mid-rollout |
| Anti-affinity or spread for singleton-critical services | — | Correlated failure |
A PDB with minAvailable equal to replicas is worse than none: it makes the node undrainable and
blocks cluster upgrades forever. That is a common and expensive mistake.
Health
| Check | Why | Notes |
readinessProbe present | Without it, traffic is sent to a pod that is still starting | This is the single highest-value item on this list |
livenessProbe present but not the same endpoint as readiness | Liveness restarts the container; readiness only removes traffic | A liveness probe that checks a dependency causes cluster-wide restart storms |
startupProbe for slow-starting apps | Lets liveness be aggressive after start without killing during it | JVM, large caches, migrations |
| Readiness does not check shared dependencies | Otherwise one slow database removes every replica simultaneously | See kubernetes-networking example |
terminationGracePeriodSeconds >= the longest in-flight request | Otherwise SIGKILL drops live requests | Default is 30s |
preStop sleep of a few seconds | Endpoint removal and SIGTERM race; the sleep lets the proxy catch up | Standard fix for 502s during rollouts |
Resources
| Check | Why |
requests set for CPU and memory | Otherwise BestEffort, evicted first, and the scheduler cannot place it properly |
limits.memory set from a measured peak | Prevents one leak from taking down a node |
| CPU limit deliberate | A CPU limit throttles bursts; often the wrong default for latency-sensitive services |
| Requests derived from measurement, not from a template | See kubernetes-resource-debugging |
Configuration and supply chain
| Check | Why |
| Image pinned by digest or immutable tag | :latest means you cannot say what is running or roll back to it |
imagePullPolicy consistent with the tag strategy | IfNotPresent with a mutable tag serves stale images forever |
| Secrets from a Secret or external store, never env literals in the manifest | See secrets-management-review |
| ConfigMap changes trigger a rollout (checksum annotation) | Otherwise config changes apply only to pods that happen to restart |
securityContext: runAsNonRoot, readOnlyRootFilesystem, dropped capabilities | Blast radius of a container escape |
| ServiceAccount is dedicated and least-privilege | The default ServiceAccount is shared across the namespace |
automountServiceAccountToken: false when the app does not call the API | Removes a credential from the container entirely |
Observability
| Check | Why |
| Metrics endpoint exposed and scraped | You cannot verify a fix you cannot measure |
| Logs to stdout/stderr, structured | Anything written to a file inside the container is lost on restart |
| An SLO exists with an alert on burn rate | See slo-design |
| Dashboards show saturation, not just errors | Saturation is the leading indicator |
Step 3 - test the failure modes, not the happy path
kubectl get pdb -n <namespace>
kubectl drain <node> --dry-run=server --ignore-daemonsets --delete-emptydir-data--dry-run=server asks the API server whether the eviction would be allowed without performing it.
If it reports that a PDB blocks eviction, you have found a workload that will stall your next
cluster upgrade — before the upgrade, rather than during it.
kubectl get deployment <name> -n <namespace> \
-o jsonpath='{.spec.strategy}{"\n"}{.spec.template.spec.terminationGracePeriodSeconds}{"\n"}'Compare the grace period against your p99 request duration plus any shutdown work. A 30-second default with a 45-second batch handler means every rollout kills work in flight.
Decision Tree
Is this workload safe for production traffic?
├── Stateless request-serving
│ ├── replicas < 2 → not ready; every restart is downtime
│ ├── no readinessProbe → not ready; rollouts will drop traffic
│ ├── no PDB → not ready for a cluster upgrade
│ └── no requests set → BestEffort; will be evicted first under pressure
├── Stateful (databases, queues, anything with a PVC)
│ ├── Does a restore actually work? → untested backup is not a backup
│ ├── PDB minAvailable respects quorum → otherwise a drain can break quorum
│ └── OnDelete vs RollingUpdate chosen deliberately → surprise rollouts corrupt state
├── Batch / Job
│ ├── backoffLimit and activeDeadlineSeconds set → otherwise it retries forever
│ └── Idempotent? → retries will re-run it
└── Singleton (leader-elected, cron, migration)
├── Leader election implemented → otherwise two replicas both act
└── PDB and grace period aligned with the work unitCommon Causes
| Gap | Symptom in production | Fix | Risk |
| No readiness probe | 502s for the first seconds of every rollout | Add readiness | mutating |
| Liveness checks a dependency | Cluster-wide restart storm when that dependency slows | Make liveness self-only | mutating |
| No preStop hook | 502s at the end of every rollout | preStop: sleep 5 | mutating |
PDB minAvailable == replicas | Node drains hang indefinitely | Set below replica count | mutating |
| Mutable image tag | Cannot reproduce or roll back | Pin by digest | mutating |
| No topology spread | One node loss takes the service down | Add spread constraints | mutating |
| Grace period below p99 | Dropped requests every deploy | Raise it and handle SIGTERM | mutating |
Safety
Read-only
Rendering manifests, kubectl get, describe, and --dry-run=server on any command. Server-side
dry run is genuinely read-only: it runs admission and validation and discards the result.
Potentially disruptive
- Applying probe, resource or strategy changes — triggers a rolling restart of the whole workload.
Roll out during a change window; one workload at a time. Rollback:
kubectl rollout undo. - Adding a PodDisruptionBudget — takes effect immediately and can block an in-progress node drain
or cluster autoscaler scale-down. Check
minAvailableagainst the current replica count before applying, not after. - Tightening a
securityContext(readOnlyRootFilesystem,runAsNonRoot) — will crash-loop any application that writes to the filesystem or needs root. Test in a non-production environment first; this is the most common cause of a "hardening" change becoming an outage. kubectl drainfor a real spread test — evicts live workloads. Use--dry-run=serverinstead unless you are in a maintenance window.
Destructive
This skill proposes no destructive operations. Note that deleting and recreating a StatefulSet or its volume claims — sometimes suggested to "apply changes cleanly" — destroys data and is out of scope here.
Verification
Verify by exercising the failure the change was meant to survive, not by re-reading the manifest.
Before: rollout produced 340 x 502 over 90s; drain of node-3 evicted all 2 replicas at once
After: rollout produced 0 x 502; drain evicts 1 replica at a time and waits for Readykubectl rollout restart deployment/<name> -n <namespace>
kubectl rollout status deployment/<name> -n <namespace> --timeout=10m
kubectl drain <node> --dry-run=server --ignore-daemonsetsRun a client-side request loop through the ingress during the rollout restart. A rollout that
kubectl reports as successful can still have dropped every in-flight request; only the client
sees that.
Anti-Patterns
Bad: Add a liveness probe pointing at the same /healthz as readiness.
Better: Liveness answers "would a restart fix this?" and must only test the process itself.
Readiness answers "should traffic come here now?". Pointing liveness at a dependency check means a
slow database restarts every replica in the fleet at once — converting a degradation into an outage.
Bad: Three replicas, so it is highly available. Better: Check where they are. Three replicas on one node survive nothing. Availability is a property of the spread, not of the count.
Bad: Set minAvailable: 100% to protect the service.
Better: That makes the workload permanently undrainable and blocks every cluster upgrade. Use
minAvailable: N-1, or a percentage below 100.
Bad: Ship with :latest and a note to pin it later.
Better: Pin at the start. An unpinned tag means that during the next incident you cannot answer
"what changed?" or roll back to a known state.
Bad: Treat this checklist as a gate to pass once. Better: Re-run it when replica counts, dependencies or traffic change. A configuration that was right at 2 replicas and 100 rps is often wrong at 20 replicas and 10k rps.
Composition
kubernetes-resource-debugging— to derive requests and limits from measurement.kubernetes-networking— to validate Service, Ingress and policy configuration.container-image-review— image size, base image, non-root user, pinning.slo-design— to define what "healthy" means for this service in the first place.secrets-management-review— for how credentials reach the container.
References
references/readiness-checklist.md— the checklist in copy-pasteable form for a PR review.- Kubernetes: Configure Liveness, Readiness and Startup Probes
- Kubernetes: Pod Disruption Budgets
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

