Extending kubectl Utility With Plugins
Tags: kubernetes, go, devops, beginners
Published: 2022-09-15 15:54:18

## Introduction
We can all agree on the fact that Kubernetes is quite expansive. It has become the de facto tool for cloud-native application deployment because of its flexibility. One often uses the kubectl CLI to interact with their Kubernetes cluster, and while kubectl is quite extensive in itself with regard to all the operations you can perform with it, its usability can be further extended using plugins.

kubectl plugins can extend the usability of the CLI tool by adding functional capabilities specific to a Kubernetes application or in general providing more features that can be accessed as kubectl sub-commands. The best part is it does not require editing kubectl’s source code or recompiling it, thereby making the plugins truly modular in the sense that they can be simply plugged in and used.

## Installing Plugins
Although there’s more than one way to distribute and install kubectl plugins, the simplest way is to use [**krew**](https://krew.sigs.k8s.io/). It is a package manager for kubectl and makes the installation and management of kubectl plugins a cakewalk. To get started, you would have to first install krew on your machine. You can refer to [this](https://krew.sigs.k8s.io/docs/user-guide/setup/install/) installation document to do so.

Once installed, you shall first index all the available krew plugins, a list of which can be accessed [here](https://krew.sigs.k8s.io/plugins/). To do so, run the following command:

```bash
kubectl krew update
```

Did you notice how krew itself is a kubectl plugin as well? A plugin to manage all other plugins! If you’re willing to, you can check its source code [here](https://github.com/kubernetes-sigs/krew).

Now, you can view the list of available plugins with the following command:

```bash
kubectl krew search
```

To install any plugin, say the [**whoami**](https://github.com/rajatjindal/kubectl-whoami) plugin, run the following command:

```bash
kubectl krew install whoami
```

Once installed, you can simply follow the usage guide to run the plugin commands as such:

```bash
kubectl whoami
```

You can also update, uninstall, and add a custom index for the plugins using krew among other things, for which you can refer to the [documentation](https://krew.sigs.k8s.io/docs/).

## Developing Plugins
Developing plugins for kubectl is a fairly simple process, if we abstract out the business logic of the plugin. The plugin itself is nothing but a standalone CLI application that uses appropriate commands to achieve its intended functionalities. So the question remains how do we add this standalone CLI as a kubectl plugin? Let’s find out.

I have made a demo plugin called kubectl-count, which we will be using for this small demo. The complete source code can be found here: [https://github.com/neelanjan00/kubectl-count](https://github.com/neelanjan00/kubectl-count). In a nutshell, this plugin allows you to count the instances of Kubernetes resources present in your cluster. So for example, you can count the number of pods in a namespace, the number of nodes in your cluster, or the total number of deployments in all the namespaces of your cluster.

The source code of the plugin is pretty straightforward, we use the [Cobra CLI](https://github.com/spf13/cobra) to create a boilerplate CLI project.

{% gist https://gist.github.com/neelanjan00/3425ea131cd7271c1627ab2a308d2416 %}

Then, we add the commands for each of the supported Kubernetes resources for which we will count the resources. We do so using the Kubernetes client-go library. For example, this is the logic for the command for counting the number of pods.

{% gist https://gist.github.com/neelanjan00/cfc1d6aa5b7ec57bb12a699bbd824f05 %}

We are using flags here for specifying the namespace, the label selector, and all-namespaces, just as you would do in kubectl. Also, the aliases for the `pods` command such as `po` and `pod` are also available to be used. Similarly, we have created definitions for other commands as well, corresponding to the resources that they represent.

Lastly, if you’re wondering how we’re obtaining the Kubernetes client here, we use the existing .kubeconfig file in the machine and use it to generate a client.

{% gist https://gist.github.com/neelanjan00/87b7e0eccf1c8326a8b6d8d05c5dabcf %}

We can simply run this CLI program as it is like the following:

```bash
go run kubectl-client.go po
```

The above command should give the number of pods in your default namespace, given that you have a valid Kubernetes cluster config file on your machine.

Now that we have our plugin ready, how shall we use it along with kubectl? To do so, first, we need to build a binary for this go program and then we need to rename the binary file (or an executable shell file, in case you want to make your plugins in bash) file such that the root sub-command of the plugin id preceded by `kubectl-`. For example, since the root sub-command for this plugin is `count`, the name of the binary will be `kubectl-count`. After this, we just need to move this file to the `/usr/local/bin` directory.

The naming convention we used here will allow kubectl to search for this plugin and any other plugin that you will be installing, given that the directory `/usr/local/bin` is in your system path. Now you can simply use this plugin to run the command that you had previously run to count the pods like so:

```bash
kubectl count po
```

## Conclusion
kubectl plugins are an excellent way to increase the usability of the CLI tool. While there’s an ever-soaring list of plugins that you can simply plug and play using krew, it’s also pretty feasible to develop your own plugins which can abridge the lack of any functionality in kubectl without complicating the developer experience or the end-user experience.