Cleaning Up Orphaned Kubernetes Resources - Use KOR to Help
Running Kubernetes is great. But over time, your cluster can fill up with orphaned or unused resources. These are objects (ConfigMaps, Secrets, Services, etc.) that no longer serve a purpose, but haven’t been removed. They waste memory, add clutter, and sometimes cause confusion or even security risk.
In this post I’ll explain:
What “orphaned” resources are
Why it matters to clean them
How KOR helps
Examples & commands
Things to watch out for
What are orphaned / unused Kubernetes resources?
An orphaned (or unused) resource in Kubernetes is something that exists in the cluster but is no longer actively used or referenced. For example:
A ConfigMap that is no longer mounted in any Pod
A Secret that no longer has any workload referencing it
A Service that has no endpoints (no Pods behind it)
A PersistentVolume (PV) not bound to any claim
A Deployment with 0 replicas and no one will scale it back
A Job that has completed and is no longer needed
Over time, as you deploy, delete, and evolve your apps, these unused resources accumulate.
Why clean them?
Less clutter: Makes it easier to see what’s truly in use
Lower cost / resource usage: Some resources still occupy memory, storage, or quotas
Security / hygiene: Secrets lying around might be risk
Avoid surprise behavior: Sometimes stale resources block new ones
Meet KOR (Kubernetes Orphaned Resources Finder)
KOR is a tool written in Go that helps you find (and optionally delete) unused or orphaned resources in your cluster.
It supports a wide range of Kubernetes resource types.
Some of the resource types KOR can detect as unused:
ConfigMaps
Secrets
Services
ServiceAccounts
Deployments
StatefulSets
Roles, RoleBindings
ClusterRoles, ClusterRoleBindings
HPAs (Horizontal Pod Autoscalers)
Ingresses
Pods
Jobs
ReplicaSets
DaemonSets
PersistentVolumeClaims (PVCs) And more.
So KOR is not just for one type of resource—it can cover many.
How to use KOR — examples & commands
Below are some example commands and use cases.
Install / setup
You can download a binary, build from source, use kubectl krew, or run via Docker.
For example:
go install github.com/yonahd/kor@latest
# or with krew
kubectl krew install kor
Listing unused resources
To list all unused resources across all namespaces:
kor all
To check just ConfigMaps:
kor configmap
To scope to a namespace:
kor all --include-namespaces my-namespace
You can also output JSON or YAML formats instead of table:
kor all --output json
kor all --output yaml
If you want to see why a resource is considered unused, use --show-reason:
kor all --show-reason
Deleting unused resources
KOR supports deletion too. For example, to delete unused ConfigMaps in a namespace:
kor configmap --include-namespaces my-namespace --delete
You’ll be prompted to confirm each one (interactive mode).
If you want to force delete without prompt (be careful!):
kor configmap --include-namespaces my-namespace --delete --no-interactive
You can also exclude some namespaces or resources via flags like --exclude-namespaces, --exclude-labels, or by labeling resources you want to ignore.
Also, you can annotate or label resources with:
kor/used=true→ KOR will ignore them even if unusedkor/used=false→ KOR will always clean them
These give you control to protect or force-clean.
Running inside a cluster
You can run KOR as a cronjob inside your cluster, and send reports to Slack or other channels.
Using Helm charts provided by the project, you can deploy KOR to run periodically and notify of orphaned resources.
This way, you're continuously monitoring, not just doing one-off sweeps.
What KOR doesn’t cover / caveats
While KOR is powerful, it has limitations and things to watch out for.
False positives: Some resources may be considered unused but are used in ways KOR cannot detect (dynamic usage, indirect references).
KOR, by default, ignores resources with
ownerReferences(resources owned by others). That helps avoid accidentally deleting something managed by a controller.Some resources may not explicitly list their references (e.g. secrets used by external controllers)
Always review before deleting, especially with
--no-interactiveUse labels / annotations to protect resources you know should not be touched
In short: KOR helps you find candidates for cleanup — but always double-check what you delete.
A simple workflow you might adopt
Here’s a possible workflow using KOR:
Run
kor all --output yaml --show-reasonReview the list of unused resources
Mark any resources you want to protect (e.g. label them
kor/used=true)Run deletion in safe mode (interactive) on the ones you’re confident about
Automate via cronjob inside cluster to monitor over time
This keeps your cluster clean over its lifetime.
Conclusion
Orphaned and unused resources in Kubernetes are a real problem in long-lived clusters. They clutter things, consume resources, and can even mask issues.
KOR is a handy, open source tool to help you detect and optionally clean up those resources. It supports many resource types, has flexible filters, and can run as part of your cluster for continuous monitoring.