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
A job launching library for docker, EC2, GCP, etc.

doodad A library for packaging dependencies and launching scripts (with a focus on python) on different platforms using Docker. Currently supported pl

Justin Fu 55 Aug 27, 2022
Ansible for DevOps examples.

Ansible for DevOps Examples This repository contains Ansible examples developed to support different sections of Ansible for DevOps, a book on Ansible

Jeff Geerling 6.6k Jan 08, 2023
Remote Desktop Protocol in Twisted Python

RDPY Remote Desktop Protocol in twisted python. RDPY is a pure Python implementation of the Microsoft RDP (Remote Desktop Protocol) protocol (client a

Sylvain Peyrefitte 1.6k Dec 30, 2022
Automatically capture your Ookla Speedtest metrics and display them in a Grafana dashboard

Speedtest All-In-One Automatically capture your Ookla Speedtest metrics and display them in a Grafana dashboard. Getting Started About This Code This

Aaron Melton 2 Feb 22, 2022
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
Daemon to ban hosts that cause multiple authentication errors

__ _ _ ___ _ / _|__ _(_) |_ ) |__ __ _ _ _ | _/ _` | | |/ /| '_ \/ _` | ' \

Fail2Ban 7.8k Jan 09, 2023
A colony of interacting processes

NColony Infrastructure for running "colonies" of processes. Hacking $ tox Should DTRT -- if it passes, it means unit tests are passing, and 100% cover

23 Apr 04, 2022
Rundeck / Grafana / Prometheus / Rundeck Exporter integration demo

Rundeck / Prometheus / Grafana integration demo via Rundeck Exporter This is a demo environment that shows how to monitor a Rundeck instance using Run

Reiner 4 Oct 14, 2022
Linux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, DNS, Elastic, Network, Virtualization. DevOps Interview Questions

Linux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, DNS, Elastic, Network, Virtualization. DevOps Interview Questions

Arie Bregman 35.1k Jan 02, 2023
This projects provides the documentation and the automation(code) for the Oracle EMEA WLA COA Demo UseCase.

COA DevOps Training UseCase This projects provides the documentation and the automation(code) for the Oracle EMEA WLA COA Demo UseCase. Demo environme

Cosmin Tudor 1 Jan 28, 2022
Apache Airflow - A platform to programmatically author, schedule, and monitor workflows

Apache Airflow Apache Airflow (or simply Airflow) is a platform to programmatically author, schedule, and monitor workflows. When workflows are define

The Apache Software Foundation 28.6k Jan 01, 2023
Glances an Eye on your system. A top/htop alternative for GNU/Linux, BSD, Mac OS and Windows operating systems.

Glances - An eye on your system Summary Glances is a cross-platform monitoring tool which aims to present a large amount of monitoring information thr

Nicolas Hennion 22k Jan 08, 2023
Python utility function to communicate with a subprocess using iterables: for when data is too big to fit in memory and has to be streamed

iterable-subprocess Python utility function to communicate with a subprocess using iterables: for when data is too big to fit in memory and has to be

Department for International Trade 5 Jul 10, 2022
Lima is an alternative to using Docker Desktop on your Mac.

lima-xbar-plugin Table of Contents Description Installation Dependencies Lima is an alternative to using Docker Desktop on your Mac. Description This

Joe Block 68 Dec 22, 2022
Cado Response Integration with Amazon GuardDuty using AWS Lambda

Cado Response Integration with Amazon GuardDuty using AWS Lambda This repository contains a simple example where: An alert is triggered by GuardDuty T

Cado Security 4 Mar 02, 2022
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
Oracle Cloud Infrastructure Object Storage fsspec implementation

Oracle Cloud Infrastructure Object Storage fsspec implementation The Oracle Cloud Infrastructure Object Storage service is an internet-scale, high-per

Oracle 9 Dec 18, 2022
Organizing ssh servers in one shell.

NeZha (ε“ͺ吒) NeZha is a famous chinese deity who can have three heads and six arms if he wants. And my NeZha tool is hoping to bring developer such mult

Zilin Zhu 8 Dec 20, 2021
Play Wordle from any Kubernetes cluster.

wordle-operator 🟩 ⬛ 🟩 🟨 ⬛ Play Wordle from any Kubernetes cluster. Using the power of CustomResourceDefinitions and Kubernetes Operators, now you c

Lucas Melin 1 Jan 15, 2022
Ralph is the CMDB / Asset Management system for data center and back office hardware.

Ralph Ralph is full-featured Asset Management, DCIM and CMDB system for data centers and back offices. Features: keep track of assets purchases and th

Allegro Tech 1.9k Jan 01, 2023