DevOps & Infrastructure

Kubernetes Manifest Auditor

Check a Kubernetes manifest for the defaults that quietly cause outages -- missing resource limits, no readiness probe, and running as root.

When to use this

  • A new or changed Deployment/StatefulSet/Pod manifest needs review before applying.
  • A workload gets OOM-killed or evicted unexpectedly and the manifest's resource config needs checking.
  • Not for application-level code review -- scope to the manifest/deployment configuration.

The skill file

Copy this verbatim. It's written in the SKILL.md format (YAML frontmatter + markdown instructions) that Claude Code, and increasingly other agent tools, read directly.

SKILL.md
---
name: k8s-manifest-auditor
description: Review a Kubernetes manifest (Deployment, StatefulSet, Pod spec) for missing resource requests/limits, missing or misconfigured health probes, and baseline security settings. Use before applying a new or changed manifest.
---

# Kubernetes Manifest Auditor

## Resource management

- **Requests and limits set** for CPU and memory on every container --
  missing requests make scheduling unpredictable; missing memory limits
  risk one container starving/OOM-affecting its node's other workloads.
- **Limits not wildly higher than requests** without reason -- a huge gap
  invites overcommit issues; a limit equal to request removes burst
  capacity entirely, which may or may not be intended.

## Health probes

- **Readiness probe** present and checking something meaningful (not just
  "process is running" if the app has a real health/dependency check
  available) -- without one, traffic can route to a pod that's up but not
  actually ready (e.g. still connecting to its database).
- **Liveness probe**, if present, shouldn't be so aggressive it restarts a
  pod that's just slow under load rather than actually stuck.

## Security basics

- **`runAsNonRoot` / non-root user** set, unless there's a specific
  documented reason the container needs root.
- **No `privileged: true`** and no unnecessary added Linux capabilities,
  unless the workload genuinely requires them.
- **Read-only root filesystem** where the application doesn't need to
  write to its own container filesystem.

## Other common gaps

- **`imagePullPolicy`** appropriate for the tag strategy (avoid
  `:latest` with `Always` silently pulling unexpected versions in
  production).
- **PodDisruptionBudget** for anything that needs to stay available
  during voluntary node drains, if the cluster does rolling maintenance.

## Output

Findings grouped by category above, each with the specific manifest
field and the recommended value/fix.

Installing it elsewhere

The frontmatter/body split above is Claude Code's convention. Here's how to carry the same instructions into other tools:

Claude Code
.claude/skills/k8s-manifest-auditor/SKILL.md

Save the file below verbatim (frontmatter included) at that path, project-local or in ~/.claude/skills/ for a user-level skill. Claude Code loads the name/description pair to decide when to pull it in, or you invoke it directly as /k8s-manifest-auditor.

Cursor
.cursor/rules/k8s-manifest-auditor.mdc

Convert the YAML frontmatter to Cursor's rule format (description, globs, alwaysApply: false) and keep the markdown body as the rule content. Cursor surfaces it by description match, same idea as Claude Code's auto-load.

Codex CLI / Copilot
AGENTS.md

Codex CLI (and increasingly other agentic CLIs) read AGENTS.md at the repo root as always-on instructions. Paste the markdown body under a heading like ## {title}; for GitHub Copilot's coding agent, the equivalent file is .github/copilot-instructions.md.

Windsurf
.windsurfrules

Append the markdown body to .windsurfrules at the repo root. Windsurf treats the whole file as always-on context, so keep only the instructions you want applied on every request.

Where this goes wrong
  • Missing that a Deployment has no memory limit at all, which risks starving other pods on the same node during a leak.
  • Accepting a liveness probe copied from another service without checking it fits this service's actual startup/response time.
  • Not checking for `:latest` tags with an `Always` pull policy in a production manifest.