A Simple script to hunt unused Kubernetes resources.

Overview

K8SPurger

A Simple script to hunt unused Kubernetes resources.

Release History

Release 0.3

  • Added Ingress
  • Added Services Account
  • Adding RoleBindding
  • Removed deletion capability. Refer issue 3

Release 0.2

  • Added services in the mix.

NAQ (Nobody asked Question).

  1. What this script do?

This will find all unused resources and show them in a nice format.

  1. Why you need this?

When we add a new application or Microservices it is simple as installing a chart or kubectl -f on a big manifest but when we want to remove we don't know what are resources it created. Many times we can't remove them fully because we have 10's or 100's such resources and don’t have enough time to hunt and kill or many times we just inherited a cluster. Having an unused item in the cluster is not good practice as the Etcd DB size grows the performance starts degrading. Also many times it possed a security risk(unknown SA and rolebinding).

Lastly most dear to us saving cost in case of PVC we are paying for them to cloud provider.

  1. Is this cause any effect on my cluster?

This will just list the unused resources according to predefined criteria which are mentioned after NAQ. This will just give the list of resources that are Potentially unused so you can focus on them an only instant of looking for a needle in the haystack.

Note:- You should not trust strangers' words on the internet so browse the script as it is under apache 2 License and try on dummy cluster.

  1. How this work? Can I just use the kubectl command to do the same?

The kubectl does not directly give these details you have to invest a lot of time. If you know a short way, Please let me know via raising the issue (sharing is caring). This script will get all pods in all namespaces and scan them for these resources and make a list and then get the resource in Kubernetes and just give you the difference.

  1. So if I understood correctly it will scan the pod only. what if I have deployment/StatefullSet which has zero replica set?

Yes, in that case, the resource will be shown as unused. If you have zero replicas means you are not using that resource.

  1. Why PVC why not PV?

Normally we use PVC to manage PV and when we delete claims, PV will be deleted or retained as per storage-class configuration. To avoid any potential data loss I choose to work with PVC only.

  1. What if I hit a bug or required any feature?

You can raise an issue. I will try to fix the bug. The feature has to look into how much time is required.

Selection Criteria

  • Secret -> If the secret is not mounted on any running pod via env variable or as volume
  • ConfigMap -> If ConfigMap is not mounted on any running pod via env variable or as volume
  • PVC -> Is PVC is not mounted on any running pod
  • Services -> If services do not any endpoint
  • ServiceAccount -> If no running pod use that service account
  • Ingress -> If ingress pointing to any services which either do not exist or do not have any endpoint
  • RoleBinding -> If RoleBindding to any Services account which does not exist or that Services account is not used by any running pod.

Exclusion:- All objects in kube-system and kube-system are excluded also all secrets which are token or type TLS are excluded to avoid the high list of false positive.

Installation and Configuration

This script use Python client for Kuberntes. We need to install that first


pip install kubernetes

python K8sPurger.py

Make sure you have kubeconfig in ~/.kube/conf or in KUBECONFIG env variable before runing script.


yogesh$ ~/p/K8sPurger> python K8sPurger.py

This script is created to find unused resource in Kubernetes.

Getting unused secret it may take couple of minute..

Extra Secrets are 6 which are as below

--------------------------------
| Secrets         | Namespace   |
--------------------------------
| app1-secret     | my-apps     |
| app2-secret     | my-apps     |
| app2-new-secret | my-apps     |
| postgresql      | default     |
| dex-b94455424g  | kube-addons |
| dex-dbh8fmk699  | kube-addons |
--------------------------------

Getting unused ConfigMap it may take couple of minute..

Extra ConfigMap are 6 which are as below

-------------------------------------------
| ConfigMap                 | Namespace   |
-------------------------------------------
| app1-configmap            | my-apps     |
| app2-configmap            | my-apps     |
| app2-new-configmap        | my-apps     |
| ss-cm                     | default     |
| cluster-autoscaler-status | kube-addons |
| fluent-bit-config         | logging     |
-------------------------------------------

Getting unused PVC it may take couple of minute..

Extra PV Claim are 5 which are as below
---------------------------------
| PV Claim          | Namespace |
---------------------------------
| data-postgresql-0 | default   |
| data-0            | default   |
| redis-master-0    | default   |
| redis-slave-0     | default   |
| redis-slave-1     | default   |
--------------------------------

Getting unused services it may take couple of minute..

Extra Services are 3 which are as below

-----------------------------
| Services      | Namespace |
-----------------------------
| app1-services | my-apps   |
| app2-services | my-apps   |
| app2-headless | my-apps   |
-----------------------------

Getting unused Ingress it may take couple of minute..

Extra Ingress are 4 which are as below

----------------------------------------
| Ingress                  | Namespace |
----------------------------------------
| app1-ingress             | my-apps   |
| app2-ingress             | my-apps   |
| app2-ingress-api-gateway | my-apps   |
| router                   |default    |
----------------------------------------

Getting unused service account it may take couple of minute..

Extra Service Account are 6 which are as below
----------------------------------
| Service Account | Namespace    |
----------------------------------
| app1-svc        | my-apps      |
| cert-svc        | cert-manager |
| log-svc         | logging      |
| monitor-svc     | monitoring   |
| default         | my-registry  |
| default         | tools        |
----------------------------------

Getting unused Roles Binding it may take couple of minute..

Extra Role Binding are 1 which are as below

---------------------------
| Role Binding |Namespace |
---------------------------
| app1-rb      |my-apps   |
---------------------------

NOTE:- You can browse code and if like idea provides star for encouragement or provide feedback to me one below social networks.

Twitter https://twitter.com/yogeshkunjir LinkedIn https://www.linkedin.com/in/yogeshkunjir/

Comments
  • CrashLoopBackOff

    CrashLoopBackOff

    Awesome stuff, but I have the below issue. So the pod is in crash loop.

    kubectl apply -f deploy/manifest.yaml deployment.apps/k8spurger created service/k8spurger-svc created serviceaccount/k8spurger-sa created Warning: rbac.authorization.k8s.io/v1beta1 ClusterRole is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRole clusterrole.rbac.authorization.k8s.io/k8spurger-cluster-role created Warning: rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding is deprecated in v 1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRoleBindin g clusterrolebinding.rbac.authorization.k8s.io/k8spurger-rb created

    The error:

    Getting unused secret it may take couple of minute.. Traceback (most recent call last): File "K8sPurger.py", line 324, in main("svc") File "K8sPurger.py", line 32, in main GetUsedResources(v1) File "K8sPurger.py", line 125, in GetUsedResources UsedConfigMap.append([volume.config_map_ref.name, i.metadata.namespace])

    opened by filipdadgar 10
  • Failed to run

    Failed to run

    python K8sPurger.py

    This script is created to find unused resource in Kubernetes

    Not able to read Kubernetes cluster check Kubeconfig Traceback (most recent call last): File "/Users/Shariq.Mustquim/DevOps/poc/k8s-misc/K8sPurger/K8sPurger.py", line 25, in main v1beta1Api = client.ExtensionsV1beta1Api() AttributeError: module 'kubernetes.client' has no attribute 'ExtensionsV1beta1Api'

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last): File "/Users/Shariq.Mustquim/DevOps/poc/k8s-misc/K8sPurger/K8sPurger.py", line 332, in main("standalone") File "/Users/Shariq.Mustquim/DevOps/poc/k8s-misc/K8sPurger/K8sPurger.py", line 30, in main raise RuntimeError(e) RuntimeError: module 'kubernetes.client' has no attribute 'ExtensionsV1beta1Api'

    opened by shariqmus 7
  • If you know a short way

    If you know a short way

    @yogeshkk We're using a combination of ArgoCD and kube-janitor to achieve this.

    The ArgoCD application resource gets a timestamp through CI/CD:

    ---
    apiVersion: argoproj.io/v1alpha1
    metadata:
      name: 'foobar-{{ getenv "GIT_BRANCH" | strings.Slug }}'
      annotations:
        janitor/expires: '{{ ((time.Now).Add (time.Hour 24)).UTC.Format "2006-01-02" }}T12:00:00Z'
      finalizers:
        - resources-finalizer.argocd.argoproj.io
    spec:
    

    Janitor will then clean up resources after 24h.

    opened by estahn 5
  • Replace with list comprehension

    Replace with list comprehension

    https://github.com/yogeshkk/K8sPurger/blob/f91e1d7d8da2f56078529e756223ee4738a5fe51/K8sPurger.py#L77-L82

    Could be:

    def Diffrance(listA, listB):
        return [i for i in listA if i not in listB]
    
    opened by gregwhorley 3
  • Add option for json output

    Add option for json output

    Cool tool!!

    This will enable running K8Spurger as a Cronjob (or Jenkins a job) periodically and do some additional processing of the output. E.g. Send notifications to namespace owners about unused resources in their namespace.

    opened by shrinandj 3
  • Add container environment variables use case

    Add container environment variables use case

    https://kubernetes.io/docs/concepts/configuration/secret/#use-cases

    Need to take into account below scenario and have it append to UsedSecret/UsedConfigMap function.

        spec:
          containers:
          - env:
            envFrom:
            - configMapRef:
                name: configmap-test
            - secretRef:
                name: secrets-test
    

    below is the block that will get you all the names of those secrets

                    if item.env_from is not None:
                        for envfrom in item.env_from:
                            if envfrom.secret_ref is not None:
                                UsedSecret.append(
                                        [envfrom.secret_ref.name, i.metadata.namespace])
    
    opened by kk2526 3
  • showing default service accounts

    showing default service accounts

    We use Openshift clusters. Every project in Openshift has 4 default service accounts. More importantly, default service account is being used at run time. The script is showing they are used or not referred to. This showing large output although they are used by PODS at run time. It is better to filter these default service accounts

    Example

    for service accounts | builder |velero | | default |velero | | deployer |velero

    for secretes | builder-dockercfg-f875f |velero | | default-dockercfg-f6bzm |velero | | deployer-dockercfg-qjwc7 |velero | | Even in a small cluster, the output is too verbose and showing lot of objects

    opened by kotarusv 2
  • Unused Services Bug

    Unused Services Bug

    All of my services are returned as unused, as well as ingresses. The issue is this:

    When the GetUsedServices(v1) function is run, it updates the local variable UsedEP, not the global variable of UsedEP. The global variable remains an empty list and so when the difference is calculated between EP and UsedEP, the entire EP list is returned.

    A simple fix to this is to set UsedEP when GetUsedServices(v1) is called here: https://github.com/yogeshkk/K8sPurger/blob/main/K8sPurger.py#L44

    As in, update it to this: UsedEP = GetUsedServices(v1)

    I can create a PR if you want, but because the change is so small, you might want to just fix this yourself.

    Great project btw

    opened by efossas 2
  • Removing ability to delete resources

    Removing ability to delete resources

    Hello All,

    I have created this script to find clean old unused config map. Then I started adding feature to it and now it can find and clean up secret, PVC and recently added service.

    I am thinking about removing deleting ability as this is not much used feature also this help us to improve script further. Also in case of newly added service it might be marked as unused because of wrong selector or any miss-configuration. I will just comment the deletion part after 7 days so if anyone want to use it they can but if any new resources added won't have delete enabled (I am thinking about adding ingress next).

    I know this is not popular that I receive reply but as this is in opensource it is my obligation to you all to share my view on upcoming development.

    Finally, I never thought this will receive this much appreciation. Thanks for that. Let me know your thoughts on above.

    Thanks, Yogesh(Yogi)

    opened by yogeshkk 2
  • Handaling false positive resources

    Handaling false positive resources

    Need to think about false positive resources.

    There are many resources which will be marked as unused but not necessary unused. It might be ok for ad-hoc script run but it might be problem when running in K8S as services and specially when alerts are configured. One might get alert which are not genuine.

    In order to tackle above a user can provide a list of resources which getting marked as false positive and before sending output we can remove such resources.

    opened by yogeshkk 1
  • Need to get just one type resource

    Need to get just one type resource

    This script is very useful. I been looking for quite some to list unused PVC, not being used in any pods. I don't find any solution so far. I found this script is super helpful in what am looking for. However, It would be nice if script takes 1 or more arguments to print just a specific type of resource. For example, I want to just print unused PVC, not interested in other resources. This helps

    1. Script doesn't have to fetch every resource which is not interested. fewer API calls to cluster
    2. Easy to get information rather than searching in big list of all the resources

    Srinivas Kotaru

    opened by kotarusv 1
  • Add unused Dep and unused STS cases

    Add unused Dep and unused STS cases

    Look at the status for the Deployment and Statefulset, we can find that the available_replicas/ ready_replicas can be a good factor to decide if the component is used.

    opened by callmefish 0
Releases(V.40)
Owner
Yogesh Kunjir
Just another IT guy
Yogesh Kunjir
Docker Container wallstreetbets-sentiment-analysis

Docker Container wallstreetbets-sentiment-analysis A docker container using restful endpoints exposed on port 5000 "/analyze" to gather sentiment anal

145 Nov 22, 2022
Visual disk-usage analyser for docker images

whaler What? A command-line tool for visually investigating the disk usage of docker images Why? Large images are slow to move and expensive to store.

Treebeard Technologies 194 Sep 01, 2022
Micro Data Lake based on Docker Compose

Micro Data Lake based on Docker Compose This is the implementation of a Minimum Data Lake

Abel Coronado 15 Jan 07, 2023
Rancher Kubernetes API compatible with RKE, RKE2 and maybe others?

kctl Rancher Kubernetes API compatible with RKE, RKE2 and maybe others? Documentation is WIP. Quickstart pip install --upgrade kctl Usage from lazycls

1 Dec 02, 2021
DAMPP (gui) is a Python based program to run simple webservers using MySQL, Php, Apache and PhpMyAdmin inside of Docker containers.

DAMPP (gui) is a Python based program to run simple webservers using MySQL, Php, Apache and PhpMyAdmin inside of Docker containers.

Sehan Weerasekara 1 Feb 19, 2022
strava-offline is a tool to keep a local mirror of Strava activities for further analysis/processing:

strava-offline Overview strava-offline is a tool to keep a local mirror of Strava activities for further analysis/processing: synchronizes metadata ab

Tomáš Janoušek 29 Dec 14, 2022
Honcho: a python clone of Foreman. For managing Procfile-based applications.

___ ___ ___ ___ ___ ___ /\__\ /\ \ /\__\ /\ \ /\__\ /\

Nick Stenning 1.5k Jan 03, 2023
Travis CI testing a Dockerfile based on Palantir's remix of Apache Cassandra, testing IaC, and testing integration health of Debian

Testing Palantir's remix of Apache Cassandra with Snyk & Travis CI This repository is to show Travis CI testing a Dockerfile based on Palantir's remix

Montana Mendy 1 Dec 20, 2021
Ajenti Core and stock plugins

Ajenti is a Linux & BSD modular server admin panel. Ajenti 2 provides a new interface and a better architecture, developed with Python3 and AngularJS.

Ajenti Project 7k Jan 03, 2023
Blazingly-fast :rocket:, rock-solid, local application development :arrow_right: with Kubernetes.

Gefyra Gefyra gives Kubernetes-("cloud-native")-developers a completely new way of writing and testing their applications. Over are the times of custo

Michael Schilonka 352 Dec 26, 2022
Universal Command Line Interface for Amazon Web Services

aws-cli This package provides a unified command line interface to Amazon Web Services. Jump to: Getting Started Getting Help More Resources Getting St

Amazon Web Services 13.3k Jan 01, 2023
Hatch plugin for Docker containers

hatch-containers CI/CD Package Meta This provides a plugin for Hatch that allows

Ofek Lev 11 Dec 30, 2022
🐳 Docker templates for various languages.

Docker Deployment Templates One Stop repository for Docker Compose and Docker Templates for Deployment. Features Python (FastAPI, Flask) Screenshots D

CodeChef-VIT 6 Aug 28, 2022
Ganeti is a virtual machine cluster management tool built on top of existing virtualization technologies such as Xen or KVM and other open source software.

Ganeti 3.0 =========== For installation instructions, read the INSTALL and the doc/install.rst files. For a brief introduction, read the ganeti(7) m

395 Jan 04, 2023
Deploy a simple Multi-Node Clickhouse Cluster with docker-compose in minutes.

Simple Multi Node Clickhouse Cluster I hate those single-node clickhouse clusters and manually installation, I mean, why should we: Running multiple c

Nova Kwok 11 Nov 18, 2022
🐳 RAUDI: Regularly and Automatically Updated Docker Images

🐳 RAUDI: Regularly and Automatically Updated Docker Images RAUDI (Regularly and Automatically Updated Docker Images) automatically generates and keep

SecSI 534 Dec 29, 2022
Chartreuse: Automated Alembic migrations within kubernetes

Chartreuse: Automated Alembic SQL schema migrations within kubernetes "How to automate management of Alembic database schema migration at scale using

Wiremind 8 Oct 25, 2022
RMRK spy bot for RMRK hackathon

rmrk_spy_bot RMRK spy bot https://t.me/RMRKspyBot for rmrk hacktoberfest https://rmrk.devpost.com/ Birds and items price and rarity estimation Reports

Victor Ryabinin 2 Sep 06, 2022
Python IMDB Docker - A docker tutorial to containerize a python script.

Python_IMDB_Docker A docker tutorial to containerize a python script. Build the docker in the current directory: docker build -t python-imdb . Run the

Sarthak Babbar 1 Dec 30, 2021
IP address management (IPAM) and data center infrastructure management (DCIM) tool.

NetBox is an IP address management (IPAM) and data center infrastructure management (DCIM) tool. Initially conceived by the network engineering team a

NetBox Community 11.8k Jan 07, 2023