Detect Deprecated Kubernetes APIs Before Upgrading
Kubernetes moves fast, and it deprecates just as fast. One release you’re fine, the next you’re staring at a broken CI pipeline or a failed Helm upgrade wondering what changed.
If you’ve ever seen this and panicked:
Error: UPGRADE FAILED: [unable to recognize "": no matches for kind "PodDisruptionBudget" in version "policy/v1beta1"]
You know what I’m talking about.
I faced this during an upgrade to Kubernetes v1.25. Our Helm deployment crashed because policy/v1beta1
was removed, not just deprecated. It had been deprecated for several releases, but because Kubernetes auto-converts deprecated resources when queried, we missed it entirely in our pre-upgrade checks. I documented the full breakdown here: Helm Upgrade Failed After v1.25 Due to PDB API.
That incident led me to Pluto, a utility that now sits at the front of all my upgrade workflows.
What Is Pluto?¶
Pluto is a command-line tool developed by Fairwinds that scans your Kubernetes manifests, Helm charts, and live cluster resources to detect deprecated and removed apiVersion
s.
Think of it as a linter, but for your cluster’s long-term health. Instead of warning you about indentation or typos, it warns you about objects that will break silently once you cross a certain Kubernetes version.
Why Pluto Matters¶
Kubernetes is too helpful for its own good¶
The Kubernetes API server is designed to be backward-compatible. When you kubectl get
or inspect objects, it quietly translates older APIs into their latest supported versions. That means even if you deployed a resource using extensions/v1beta1
, you’ll likely see it returned as apps/v1
.
That’s great for smooth operation, but it makes it extremely hard to audit for upcoming breakage.
Helm doesn’t catch everything¶
Helm doesn’t throw warnings for deprecated APIs. If your template renders fine, it assumes it’s valid. But that rendered manifest might use an API that’s already been removed in your target version. The deploy will fail, and you’ll only find out after rollout starts.
CI pipelines are blind to deprecation¶
Unless you explicitly add tools like Pluto to your CI, your pipeline won’t catch these issues until they’re too late.
How Pluto Actually Works¶
Pluto works in three major modes:
- Static detection: Scans YAML manifests and Helm templates in your codebase.
- Helm detection (live): Scans existing Helm releases in a running cluster.
- API resource detection: Scans live cluster resources (CRDs, PSPs, Ingress, etc.).
It tells you:
- Whether the
apiVersion
is deprecated or removed - Since which Kubernetes version the deprecation/removal applies
- If a replacement exists
- If that replacement is available in the current version
Live Example: Pluto on an Older Cluster¶
To test Pluto’s effectiveness, I spun up an older Kubernetes cluster and scanned it using Pluto v5.21.4.
Here’s what I found with live resource detection:
$ ./pluto detect-api-resources
W0525 01:23:19.448885 warnings.go:70] v1 ComponentStatus is deprecated in v1.19+
W0525 01:23:29.541324 warnings.go:70] extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+
W0525 01:23:30.167640 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
NAME KIND VERSION REPLACEMENT REMOVED DEPRECATED REPL AVAIL
calico-kube-controllers PodDisruptionBudget policy/v1beta1 policy/v1 true true true
And then I scanned a Helm release, targeting Kubernetes v1.32.0:
$ ./pluto detect-helm --target-versions k8s=v1.32.0
NAME KIND VERSION REPLACEMENT REMOVED DEPRECATED REPL AVAIL
kube-state-metrics/kube-state-metrics-kube-system PodSecurityPolicy policy/v1beta1 true true false
In both cases, Pluto detected deprecated resources, showed whether a replacement was available, and indicated the version where the removal occurs.
This is exactly the sort of signal I wish I had before my Helm upgrade failed.
How to Integrate Pluto into CI¶
Here’s the real value: Pluto isn’t just a manual tool. You can wire it into your CI/CD pipelines to block pull requests or Helm deployments that introduce deprecated APIs.
GitHub Actions Example¶
name: Check Deprecated Kubernetes APIs
on:
pull_request:
paths:
- '**/*.yaml'
- 'charts/**'
jobs:
deprecations:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install Pluto
run: |
curl -sLO https://github.com/FairwindsOps/pluto/releases/download/v5.21.4/pluto_5.21.4_linux_amd64.tar.gz
tar -xzf pluto_5.21.4_linux_amd64.tar.gz
sudo mv pluto /usr/local/bin/
- name: Run Pluto on Helm charts
run: |
helm template ./charts | pluto detect --target-versions k8s=v1.32.0 || exit_code=$?
if [[ "$exit_code" -eq 2 || "$exit_code" -eq 3 ]]; then
echo "::error ::Deprecated or removed APIs found. Fix before merge."
exit 1
fi
Customize It¶
- Use
--only-show-removed
if you only care about breakage. - Use
--output json
to generate reports that can be uploaded to artifact storage or dashboards. - Use
--ignore-deprecations
in lower environments but block removals in staging and prod.
Final Thoughts¶
Cluster upgrades are risky not because of the upgrade itself, but because of the hidden deprecations that lie in wait.
Pluto is the upgrade audit tool Kubernetes never gave us.
Add it to your workflow if:
- You deploy Helm charts regularly
- You manage more than one cluster
- You want to simulate upgrade readiness before touching
kubeadm upgrade
I run it before every major version bump, and now I never go in blind.
FAQs
What problem does Pluto solve in Kubernetes upgrades?
Pluto detects deprecated or removed apiVersions
in Kubernetes manifests, Helm charts, and live clusters, issues the API server masks by auto-converting versions.
Why can’t I rely on the Kubernetes API server to find deprecated resources?
Because the API server auto-converts older versions (e.g., extensions/v1beta1
) to newer ones (e.g., apps/v1
) on read, hiding deprecated usage during inspection.
How does Pluto help prevent Helm upgrade failures?
Pluto flags deprecated or removed APIs used in Helm charts before deployment, preventing runtime failures caused by missing or outdated apiVersion
s.
Can Pluto be used in CI/CD pipelines?
Yes. Pluto supports non-zero exit codes for deprecated or removed APIs, making it easy to fail CI jobs and enforce compatibility checks before merging or deploying.
What are the different ways Pluto can scan for deprecated APIs?
Pluto can scan static YAML files, rendered Helm charts, live Helm releases in clusters, and active API resources like PodDisruptionBudgets or Ingress objects.