Using ksonnet

A review on using the YAML generator for Kubernetes

Update: The ksonnet project is no longer active

If you've been around the block with Kubernetes, you'll soon realize that managing resources across different clusters can be less than ideal. Heck, since even writing valid YAML on the first try can be seen as an art, handling resource manifests for a single cluster can be time-consuming. A few solutions have popped up to handle this problem: Helm (popular one), Koki, and, the one I'm currently trying out, ksonnet. Here are some pros & cons I've noticed while using ksonnet:

Pros

Productivity

I tend to have a cluster per environment (dev, qa, staging, production, etc.) and because of that I share a lot, if not most, of my manifest details across clusters. Ksonnet allows me to specify which k8s context I want to apply my changes towards: ks apply cluster-dev. I can add the --dry-run flag if I'm scared. I can also preview the YAML that's about to be applied with ks show cluster-dev. The cli is helpful when it comes to error messaging and because of that, I'm faster at updating my clusters and feel safer when I do update them.

Configuration as code

To some, this could be a con. I'm not a fan of YAML. I haven't had great experiences writing it by hand (the objects-in-arrays syntax threw me off). When you write ksonnet files, it uses the jsonnet language to create the manifests. With jsonnet, I now have imports, variables, and modularity, yahoo! I feel back at home in turing-complete land. Now, because it is a new language, there's a learning curve (which I get into later).

Here's an example of service creation in ksonnet:

local targetPort = params.containerPort;
local labels = {app: params.name};

local appService = service
  .new(
    params.name,
    labels,
    servicePort.new(params.servicePort, targetPort))
  .withAnnotations(params.serviceAnnotations)
  .withType(params.type)

Deps are in the same repo

All of my ksonnet code lives in the same private git repo and since the dependencies/libraries ksonnet needs are saved locally and pushed, I don't have to worry about a coworker/colleague using different versions of ksonnet and generating weird manifests. Relief.

Nothing to install on kubernetes

Nothing has to live on my clusters. I don't have to apply (and therefore manage) anything to k8s. All the management is local with ksonnet and it then applies YAML to my cluster. Theoretically, this means that if I join a team that wants to stick to writing pure YAML resources, I can use ksonnet without interfering with them. Currently, the tricky part for me is making sure that whatever I have committed is in sync with whatever is applied on the cluster.

Community

It's obvious from the site, the mailing list and the channel (#ksonnet) in the Kubernetes Slack group, that the contributors of ksonnet have been trying to decrease the friction in adoption. They're active and willing to help out if you have any questions. Knowing that gave me the confidence that I could always ask questions if I ran into any issues.

Cons

Have to learn another language

Jsonnet has its quirks. I sometimes feel like I am writing JavaScript, when I'm definitely not writing JavaScript. I would read up on the language before going full throttle with ksonnet. Know where your semicolons go. Figure out how imports work. Play around with variable scope. And if you give up, know that pure JSON is a subset of jsonnet so any valid JSON is valid jsonnet. It can take a while before you get used to writing in jsonnet.

Lack of advanced examples

The introduction to ksonnet is killer. The ksonnet site is easy to get around, they have a tour to get your feet wet, and their concept overview is well written. If the fundamentals of using ksonnet weren't this clear, I might've not convinced myself to use it. With that being said, there were times when I wished the documentation went passed the beginner steps and showed me how they were solving some advanced needs (i.e. sealed secrets, creating prototypes, private registries). Some of this documentation is already out there on github, but hasn't been fully fleshed out or integrated/documented. I'm positive that as more of the community gets involved a lot of these more intricate solutions will be available.

Good luck on using another editor besides VS Code

Having a good editor for your ksonnet files is a magnitude of difference. I was stubborn on this for a while, not wanting to switch from IntelliJ, but it was a fresh breath of air when I decided to try out their Visual Studio Code extension. If you already use VS Code, then this is probably not a con for you. Atom has a jsonnet plugin in as well, but when I tried it did not have autocomplete (yes do you want autocomplete) or preview. I also still have to constantly look up the k8s.libsonnet file to figure out where things live, but this might not be an extension concern.

I can't use my YAML files

If you want to use ksonnet, then you'll have to write your manifests in jsonnet to use it fully. There is a bit of migration effort to go 100% ksonnet if you've been using YAML manifests before. There are a few cli tools that help convert YAML to JSON, but you'll eventually want to have cleaner jsonnet files that can use your fancy imports and modules in.

Conclusion

After using ksonnet, I don't think I can go back to writing YAML. It's been a great addition to my k8s tool belt. It would be neat to experiment with using ksonnet as part of the CI/CD pipelines. I do wish there was a variety of IDE integration, but using VS Code isn't the worst. The great community behind ksonnet is a great benefit to using the tool. The only reason I would advise a team not to hop on ksonnet at its current state is if they already manage heaps of YAML files for their clusters.

Written by