Using kubectl within the kubernetes cluster

Natan Bensoussan
Israeli Tech Radar
Published in
3 min readSep 3, 2022

--

TL;DR

The kubectl is used to run from outside of the kubernetes cluster.
This post will show how to use kubectl from within the cluster which can be run from a job, pod, deployment etc.

The solution includes the following requirements explained in the post:
1. Create a kubectl image with:
- Appropriate kubectl version
- User and UID with the permissions to use the kubeconfig on the host, by default located at ~/.kube/config.
- Provide the proper RBAC permissions to run the kubectl.

Note: The RBAC permissions may be of a security risk and should be handle with care.

This solution can be used for infinite scenarios.
The following is a demonstration of using a job running kubectl as an alternative to helm hooks (which caused in my scenario a race condition).
The solution solved the ability to wait for a resource without the race condition cause by the hook as explained bellow.

The Helm hooks issue

Helm hooks are mostly used to run a job / pod /deployment etc prior or after the installations. For example database migration prior to the pod upgrade or post installation database maintenance and the like. Of course there are many other use cases.

The Helm cli command would complete once all the resources are deployed, but before they are all available.

A post hook would not let helm to complete until all the resources are available to perform the post installation hook. This is fine and a normal behavior, unless you have a race condition conflict as it happened in my scenario described bellow.

My scenario

The following scenario is just an example of the implementation which eventually I found a way to solve with a hook, however I found the kubectl image solution very useful when there is a need to wait for a resource or perform any other action with kubectl from within the cluster.

In my case I had a kadalu storage implementation that creates the pv/pvc resources. The post installation hook created a race condition:
- The pod is pending for the pv/pvc to bond (waiting for helm to complete).
- The post hook waits for the pod to be available while it is stuck as pending.
- The post hook waits for all resources to be available and will not let helm to complete till then.
Hence a race condition.

The alternative - kubectl inside the cluster

Create a kubectl image:
Several kubectl images are available in GitHub and Docker Hub. I based my kubectl image from a simple Dockerfile which you can fine here:
My changes from the source:
- kubectl version
- User and UID same as the one running the helm / kubectl command on the host with permissions to use the kubeconfig file.

Dockerfile:

The kubectl was pushed to my private registry. You can push your Dockerfile to Docker Hub if needed.

Using a job with kubectl image to wait for my deployment has no race condition. The pod is created with the pv/pvc, the job uses kubectl to wait for the deployment to be available and once ready it runs the post installation. Voila!

The kubernetes Job

An initContainer is used to wait for the deployment.
A container is used for the post installation process.

post-install-job.yaml:

Ah one issue… You will get an RBAC error:

Error from server (Forbidden): deployments.apps "my-app-deployment" is forbidden: User "system:serviceaccount:your-ns:default" cannot list resource "deployments" in API group "apps" in the namespace "your-ns"

The RBAC permissions are required to provide kubectl to run within the cluster. A couple of manifests required: Role and RoleBinding:

kubectl-roles.yaml:

kubectl-rolebinding.yaml:

That’s it! Now the job waits in the initContainer for the deployment to available and ready and connected to the pv/pvc.
Once ready, a container is triggered to perform the post installation.

This was my scenario, there are unlimited use cases that can be solved with this solution.

Conclusion:

Creating a kubectl image and providing it with the proper RBAC permissions will allow you to run any kubectl command from within cluster.
My use case was to wait for a resource, however this solution opened a window to a whole world of infinite solutions to the day to day kubernetes and helm implementation.

--

--