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
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).
So, let's say you need to create a Nginx deployment, the
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
kubekutr -c config.yml scaffold -o nginx-deployment
nginx-deployment folder is initialised and you can view
$ 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
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
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 :)
Originally published at my blog