Serverless computing is all the rage at the moment, and why wouldn’t it be? The idea of deploying code without having to worry about anything like servers, or that pesky infrastructure everyone complains about seems pretty appealing. If you’ve ever used AWS lamdba or one of its related cousins, you’ll be able to see the freedom that triggering functions on events brings you.
The increase in excitement around serverless frameworks means that naturally, there’s been an increase in providers in the Kubernetes world. A quick look at the CNCF Landscape page shows just how many options there are to Kubernetes cluster operators.
In this post I wanted to look at Kubeless, a serverless framework written by the awesome people at Bitnami.
Kubeless appealed to me specifically for a few reasons:
Native Kubernetes resources (CRDs) for functions, meaning that standard Kubernetes deployment constructs can be used
No external dependencies to get started
Support for PubSub functions without having to manually bind to messages queues etc
Lots of language support with the runtimes
Before you get started with this, you’ll probably want to follow the Quick Start as well as get an understanding of how the PubSub functions work.
To follow along here you’ll need:
A working kubeless deployment, including the kubeless cli
An easy way to do this is simply connect to the API using the in_cluster capabilities and then list all the pods, like so:
This simple script will log all the information for pods in all namespaces to stdout. It can be run on your local machine, give it a try!
The problem with this is that it’s just spitting information to stdout to test locally, so we need to publish this events to NATS. In order to do this, we’ll use the python aysncio-nats libarary
Now, your script has gotten much more complicated:
Okay, so now we have events being pushed to NATS. We need to fancy this up a bit, to allow for running in and out of cluster, as well as building a Docker image. The final script can be found here. The changes are to include a logger module, as well as argparse to allow for running in and out of the cluster, as well as make some options configurable.
You should now deploy this to your cluster using the provided deployment manifests, which also include the (rather permissive!) RBAC configuration needed for the deployment to be able to read pod information from the API.
This will install the built docker container to publish events to the NATS cluster configured earlier. If you need to, modify the environment variable NATS_CLUSTER if you deployed your NATS cluster to another address.
Consuming Events with Kubeless functions
So now the events are being published, we need to actually do something with them. Let’s first make sure the events are coming in.
You should have the kubeless cli downloaded by now, so let’s create a quick example function to make sure the events are being posted.
As you can probably tell, this function just dumps any event sent to it and returns. So let’s try it out. With kubeless, let’s deploy it:
What’s happening here, exactly?
runtime: specify a runtime for the function, in this case, python 3.6
from-file: path to your file containing your function
handler: this is the important part. A handler is the kubeless function to call when an event is received. It’s in the format <filename>.<functionname>. So in our case, our file was called test.py and our function was called dump, so we specify test.dump.
namespace: make sure you specify the namespace you deployed kubeless to!
So you should now have a function deployed:
So now, we need to have this function be triggered by the NATS messages. To do that, we add a trigger:
What’s going on here?
We create a trigger with name test
function-selector: use labels created by kubeless function to select the function to run
trigger-topic: specify a trigger topic of k8s_events (which is specified in the event publisher from earlier)
Okay, so now, let’s cycle the event publisher and test things out!
You should see something like this as an output log:
This is the modification event for the pod you just cycled. Awesome!
Publish the event to slack
Okay, so now you’ve got some events being shipped, it’s time to get a little bit more creative. Let’s publish some of these events to slack.
You can create a slack.py with your function in, like so:
You’ll need to deploy your function using the kubeless binary:
The only thing you might be confused about here is the --dependencies file. Kubeless uses this to determine which dependencies you need to install for the function runtime. In the python case, it’s a requirements.txt. You can find a working one in the related github repo linked to this post. This example better formats the slack responses into nice slack output, so it’s worth taking a look at.
You’ll obviously need a slack org to try this out, and need to generate a slack token to get API access. However, now, once you cycle the events pod again (or, run another pod of course!) - you’ll now see these events pushed to slack!
Obviously this is a trivial example of using these functions, but the power of the event pipeline with kubeless is there to be seen. Anything you might need to happy when certain events happen in your Kubernetes cluster can be automated using this Kubeless event pipeline.
You can check out all the code, deployment and manifests for this post in the github repo that accompanies this post. Pull requests and feedback on my awful Python code are also welcome!
Hello, I'm Lee Briggs, and this is my blog. I write mainly about DevOps, Cloud Infrastructure and modern technologies. Most of the site is just personal opinion. To learn more about who I am, visit the About page
You can contact me via: