kubent: Detect Deprecated APIs in a Cluster
kubent (kube-no-trouble) scans a running cluster (or files/Helm releases) for deprecated and removed Kubernetes APIs against a target version, so upgrades do not break workloads.
Where Pluto typically scans repo files, kubent shines at scanning what is actually deployed: it collects live resources, Helm releases, and manifests, then flags APIs that will not survive the next upgrade. It fits a pre-upgrade CI or cron check against a cluster.
What it does
kubent gathers resources from configured collectors (the cluster via kubeconfig, local manifest files, and Helm releases), compares their apiVersions to a ruleset for the target Kubernetes version, and lists deprecated and removed APIs with the version they are gone in and the replacement. With --exit-error it returns non-zero when findings exist.
Common usage
# scan the current cluster context
kubent
# target a specific version and fail the job on findings
kubent --target-version 1.29.0 --exit-error
# scan local manifest files instead of a cluster
kubent -f ./manifests -o jsonOptions
| Flag | What it does |
|---|---|
| -t, --target-version <v> | Kubernetes version to check deprecations against |
| -c, --cluster | Enable the cluster collector (on by default) |
| -f, --filename <path> | Scan local manifest files instead of the cluster |
| -e, --exit-error | Exit non-zero when deprecated APIs are detected |
| -o, --output <fmt> | Output format: text, json, csv |
| --helm3 | Toggle the Helm 3 release collector |
In CI
Run kubent --target-version <next> --exit-error in a job with cluster credentials before an upgrade, or on a schedule to catch drift. Without --exit-error it always exits 0 and only prints, so the gate needs that flag. To keep it hermetic, use -f against rendered manifests instead of a live cluster.
Common errors in CI
Findings print rows with KIND, NAMESPACE, NAME, API_VERSION, and a REPLACE_WITH column; with --exit-error the process then exits non-zero. "unable to fetch cluster resources" or "the server could not find the requested resource" means kubeconfig or RBAC is missing for the cluster collector; scope the credentials or switch to -f. No output plus exit 0 means nothing is deprecated for that target.
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