Skip to main content

Command Palette

Search for a command to run...

Cleaning Up Orphaned Kubernetes Resources - Use KOR to Help

Updated
4 min read

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 unused

  • kor/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-interactive

  • Use 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:

  1. Run kor all --output yaml --show-reason

  2. Review the list of unused resources

  3. Mark any resources you want to protect (e.g. label them kor/used=true)

  4. Run deletion in safe mode (interactive) on the ones you’re confident about

  5. 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.