kuku renders kubernetes yaml manifests using python templates. It is similar to helm in usage (templates dir, value files, etc..).
pip3 install kuku
or using the docker image:
docker pull xarg/kuku
# Example usage (see more below):
docker run -v $(pwd)/:/tmp/ --rm xarg/kuku render -f /tmp/your-values.yaml /tmp/your-templates/ | kubectl apply -
Suppose you want to create a k8s service using a template where you define the service name
, internalPort
and externalPort
.
Given the following service.py
template:
from kubernetes import client
def template(context):
return client.V1Service(
api_version="v1",
kind="Service",
metadata=client.V1ObjectMeta(name=context["name"]),
spec=client.V1ServiceSpec(
type="NodePort",
ports=[
{"port": context["externalPort"], "targetPort": context["internalPort"]}
],
selector={"app": context["name"]},
),
)
You can now generate a yaml output from the above template using kuku
by running:
$ ls .
service.py
$ kuku render -s name=kuku-web,internalPort=80,externalPort=80 .
the above produces:
# Source: service.py
apiVersion: v1
kind: Service
metadata:
name: kuku-web
spec:
ports:
- port: 80
targetPort: 80
selector:
app: kuku-web
type: NodePort
You can also combine the above with kubectl apply -f -
to actually create your service on k8s:
kuku render -s name=kuku-web,internalPort=80,externalPort=80 . | kubectl apply -f -
Same as above, but let's make it shorter:
kuku apply -s name=kuku-web,internalPort=80,externalPort=80 .
Finally to delete it:
kuku delete -s name=kuku-web,internalPort=80,externalPort=80 .
# same as above
kuku render -s name=kuku-web,internalPort=80,externalPort=80 . | kubectl delete -f -
Templates are python files that are defining a function called template
that accepts a dict argument context
and
returns a k8s object or a list of k8s objects:
def template(context):
return V1Namespace(name=context['namespace']) # example k8s object
You can create multiple template files each defining their own template
function.
kuku
uses the k8s objects (aka models) from official kubernetes python client package.
You can find them all here
Similar to helm kuku
accepts defining it's context variables from the CLI:
kuku -s namespace=kuku .
-s namespace=kuku
will be passed to the context
argument in your template
function. Run kuku -h
to find out more.
Python is a very popular language with a huge ecosystem of devops packages. Most importantly it's easier to debug than some templating languages used today to generate k8s manifests.
k8s already has a database for it's current state (using etcd). We can connect directly to it from the client to do our operations instead of relying on an extra server side dependency.
Where possible do the validation locally using the official k8s python client.
Where possible use kubectl
to apply changes to the k8s cluster instead of implementing a specific protocol.
Again, this will make debugging easier for the end user.
At Gorgias we use helm to manage our infrastructure, but there are a few things that we found problematic with it:
- Poor templating language: requires constant referral to the docs, whitespace issues, yaml formatting is hard.
- Server side dependency: if you upgrade the server -> every user needs to update their client - waste of valuable time.
- Lack of local validation:
helm lint
does not really ensure the validity (i.e. required keys for a k8s object) of the manifest.
Chart names, releases and other helm specific features do not really fit with our current workflow.
Contributions (code, issues, docs, etc..) are welcome!
Once you have your python environment setup:
pip install -e .[dev] # will install dev dependencies
pre-commit install # will install pre-commit hooks for code quality checking
Publish a new version to pypi:
python setup.py upload