kube-score score: Manifest Best-Practice Checks
kube-score score grades Kubernetes manifests against reliability and security best practices, printing OK, WARNING, and CRITICAL findings and failing on criticals.
Where kubeconform asks "is this valid?", kube-score asks "is this a good idea?". It flags missing resource limits, no readiness probe, running as root, and dozens of other patterns that pass schema validation but hurt in production.
What it does
kube-score score reads manifests (files, directories, or stdin) and runs a suite of checks, each returning OK, SKIPPED, WARNING, or CRITICAL with an explanation and the offending path. By default any CRITICAL yields a non-zero exit; --exit-one-on-warning also fails on warnings.
Common usage
# score a manifest
kube-score score deployment.yaml
# score rendered Helm output from stdin
helm template . | kube-score score -
# machine-readable output and skip a noisy test
kube-score score deployment.yaml \
--output-format ci \
--ignore-test pod-networkpolicyOptions
| Flag | What it does |
|---|---|
| -o, --output-format <fmt> | Output: human, ci, json, sarif |
| --ignore-test <id> | Disable a specific check by id; repeatable |
| --enable-optional-test <id> | Turn on an optional check |
| --exit-one-on-warning | Return non-zero on warnings, not just criticals |
| --threshold-ok / --threshold-warning | Adjust score thresholds |
In CI
Feed rendered manifests via stdin (helm template | kube-score score -) so you check what actually deploys. Use --output-format ci for grep-friendly one-line findings, and --ignore-test to silence checks that do not apply rather than lowering the bar globally. Fail the gate on CRITICAL; consider warnings advisory at first.
Common errors in CI
Findings print like "[CRITICAL] Container Resources ... The pod does not have resource limits set" with a non-zero exit. "[WARNING] Pod NetworkPolicy" is advisory unless you pass --exit-one-on-warning. "failed to parse ... yaml" means invalid input, often an un-rendered Helm template with {{ }} left in it; render first. "command not found: kube-score" means the binary is not installed on the runner.
Using this in CI
A runner has no kubeconfig, no cached context, and no interactive auth. Every kubectl invocation in CI needs the context supplied explicitly, and most confusing CI failures here are the command running against the wrong cluster or no cluster at all.
# never rely on the ambient context on a runner
kubectl --context "$KUBE_CONTEXT" -n "$NAMESPACE" get pods
# confirm what you are actually connected to before mutating anything
kubectl config current-context
kubectl cluster-info
# fail fast instead of hanging on an unreachable API server
kubectl --request-timeout=30s get nodes