Kubernetes library
The last section has shown that using a library for creating Kubernetes objects can drastically simplify the code you need to write. However, there is a huge amount of different kinds of objects and the Kubernetes API is evolving (and thus changing) quite rapidly.
Writing and maintaining such a library could be a full-time job on it’s own. Luckily, it is possible to generate such a library from the Kubernetes OpenAPI specification! Even better, it has already been done for you.
k8s-libsonnet
The library is called k8s-libsonnet
(replacing the discontinued ksonnet-lib
),
currently available at https://github.com/jsonnet-libs/k8s-libsonnet.
As k8s-libsonnet
has broken compatibility in a few places with ksonnet-lib
(for good
reason), we have instrumented the widely used ksonnet-util
library with a
compatibility layer to improve the developer and user experience:
https://github.com/grafana/jsonnet-libs/tree/master/ksonnet-util
If you do not have any strong reasons against it, just adopt the wrapper as
well, it will ease your work. Many of the original ksonnet-util
enhancements
have already made their way into k8s-libsonnet
.
The docs for k8s-libsonnet
library can be found here:
https://jsonnet-libs.github.io/k8s-libsonnet/
Installation
Like every other external library, k8s-libsonnet
can be installed using
jsonnet-bundler
.
However, Tanka already did this for you during project
creation (tk init
):
This created the following structure in /vendor
:
Directoryvendor
Directorygithub.com
Directorygrafana
Directoryjsonnet-libs
Directoryksonnet-util
- kausal.libsonnet # Grafana’s wrapper
- …
Directoryjsonnet-libs
Directoryk8s-libsonnet
Directory1.21
- main.libsonnet # k8s-libsonnet entrypoint
- …
Directory1.21/ -> github.com/jsonnet-libs/k8s-libsonnet/1.21
- …
Directoryksonnet-util/ -> github.com/grafana/jsonnet-libs/ksonnet-util
- …
Aliasing
Because of how jb
works, the library can be imported as
github.com/jsonnet-libs/k8s-libsonnet/1.21/main.libsonnet
. Most external
libraries (including our wrapper) expect it as a simple k.libsonnet
(without
the package prefix).
To support both, Tanka automatically created an alias file for you:
/lib/k.libsonnet
that just imports the actual library, exposing it under this
alternative name as well.
Using it
First we need to import it in main.jsonnet
:
Now that we have installed the correct version, let’s use it in
/environments/default/grafana.libsonnet
instead of our own helper:
Full example
Now that creating the individual objects does not take more than 5 lines, we can
merge it all back into a single file (main.jsonnet
) and take a look at the
whole picture:
That’s a pretty big improvement, considering how verbose and error-prone it was before!
Bonus: Config object
While this is already a huge improvement, we can do a bit more. There is still some repetition in the main.jsonnet
file.
The most straightforward way to address this is by creating a hidden object that holds all actual values in a single place to be consumed by the actual resources.
Luckily, Jsonnet has the key:: "value"
stanza for private fields. Such are only available during compiling and will be removed from the actual output.
Such an object could look like this:
We can then replace hardcoded values with a reference to this object: