kubekutr was born out of my frustration of organising K8s resource manifests files/directories. For the uninitiated, K8s lets you hold the state of your cluster declaratively as "manifest" files. K8s does so by a lot of asynchronous control loops to check whether the desired state matches the real world state and in case of drifts, it resets back to the user desired state (I oversimplified this, but hope you get the drift ;)). These files are predominantly YAML
but there's support for JSON
as well.
Anyway, to create these manifest files for a production level project is quite a bit of manual labour. The API spec of every resource in Kubernetes is quite daunting and overwhelming. There are tools like Helm which abstract away the complexity of these YAML with it's own templating system. There are quite a lot of these charts available for 3rd party apps here. The idea is you populate the Chart with just your own config "values" and you've a deployment ready in no time. Admittedly this works quite well for something you want to take out for a quick spin but personally I am not quite a fan of hiding away the complexity with a magic layer. Also, the problem with Helm was the "Chart" (and templates) still had to be written by someone if you have a bespoke application. Helm is more geared towards common off the shelf apps like DBs, Key Value stores, web proxies etc.
I found out kustomize few months back and quite happy with it's approach towards managing manifests. The basic idea behind kustomize
is that you create a base and any kind of "customisations" must come as overlays. This is such a powerful technique over wrangling templates. kustomize
A common approach is to name these overlays based on the environment. For example, dev
deployment can have replicas: 1
for a pod, but prod
can apply a "patch" to update with repliacs: 3
. This way of separating two environments helps a lot when you follow GitOps approach of deployment. All fine and good, until I realised I spent way too much time on copy-pasting the bases for different projects and manually editing these files for the new project config.
Then I did what any other programmer would do, spend some more time to automate :P And that is how kubekutr
was born. (Quite an anticlimax I know!)
kubekutr
is a really simple tool to bootstrap a Kustomize base
. kubekutr
reads a config file, templates out different resources and produces them as YAML files. Now, I know a lot of you reading this would be going Another damn templating solution in your mind and while that reaction is warranted, given that we have 200+ tools in the community (everyone trying to solve similar problems in their own ways), I legit could not find a simple enough tool which would let the boring part of scaffolding a base out of my way and let me focus on what's more important: the actual deployment. Hence I just decided to roll out my own solution which is the best one according to IKEA effect (just kidding).
Workflow
So, let's say you need to create a Nginx deployment, the kubekutr
config.yml
would look something like this:
deployments:
- name: nginx
replicas: 1
labels:
- name: 'service: nginx'
containers:
- name: nginx
image: 'nginx:latest'
portInt: 80
portName: nginx-port
services:
- name: nginx
type: ClusterIP
port: 80
targetPort: 80
labels:
- name: 'service: nginx'
selectors:
- name: 'service: nginx'
To create the base
:
kubekutr -c config.yml scaffold -o nginx-deployment
nginx-deployment
folder is initialised and you can view deployments/nginx.yml
and service/nginx.yml
which kubekutr
created.
$ tree nginx-deployment
|-- base
| |-- deployments
| | `-- nginx.yml
| |-- ingresses
| |-- services
| | `-- nginx.yml
| `-- statefulsets
$ cat base/deployments/nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
service: nginx
spec:
replicas: 1
selector:
matchLabels:
service: nginx
template:
metadata:
labels:
service: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
name: nginx-port
$ cat base/services/nginx.yml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
service: nginx
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: ClusterIP
selector:
service: nginx
You can now use the generated folder as a Kustomize base
.
Non Goals
kubekutr
isn't meant to replace the existing tools, it's just a real simple cookie cutter approach to kustomize
bases and that's pretty much it. kustomize
is native to Kubernetes and exposes the full API spec to end users. I feel that is much more better approach than templating solutions, the users must be exposed to the standard conventions rather than a random tool's own config fields. The benefits are the same conventions can then be used across a wide variety of tools (like kubekutr
) and users are in better control of the underlying resources. Adding a layer of magic also makes it harder to debug when shit goes down. Hence kubekutr
chose kustomize
to do all the heavy lifting of managing manifests.
There's a lot of scope of improvements, but I wanted to just Ship It! and get some initial feedback. Let me know your thoughts on this :)
Fin!
Originally published at my blog
Top comments (0)