Going Serverless on Kubernetes With Kubeless
Going Serverless on Kubernetes With Kubeless
Kubeless is a serverless platform on top of Kubernetes, an open source solution to mirror capabilities of AWS Lambda, Azure functions, and Google cloud functions.
Join the DZone community and get the full member experience.Join For Free
Kubernetes is a terrific platform to build systems on. Currently everyone focuses on deploying containerized applications, and migrating existing workloads to containers and k8s. But there is much more to Kubernetes, as all the API primitives are there to build new systems!
When we look at the Serverless movement, this is very much about shortening the time it takes to get from source to deployment and production. I sometimes joke about it being MTTP (Mean Time To Production). It is crucial because the faster you get to production, the faster you innovate and get to market.
Serverless is all about building new applications extremely quickly. Link cloud services together and be charged at a very fine granular level: Function request. This even brings to bare a concept of developing software while optimizing for cost/revenue (financial based development).
The question then is, if Kubernetes is a great platform to deploy and operate other distributed systems on, and that serverless is yet a new PaaS-like approach, shouldn't we be able to develop a serverless platform on top of Kubernetes?
The answer is yes. Kubernetes is the perfect system to build a serverless solution on top of. Enters kubeless, what I call a Kubernetes-native serverless solution. Kubeless builds on top of all the great Kubernetes primitives and brings you an open source serverless solution that clones what you can find on AWS Lambda, Azure functions, and Google cloud functions.
Kubeless is open source and available on GitHub. To install it, you need to get the client `kubeless` and deploy what we call the controller inside your Kubernetes cluster. Let's first install the client. If you are on OSX and use brew, do:
$ brew install kubeless/tap/kubeless $ kubeless version Kubeless version: 0.0.18 (07dc141a)
Then, to deploy the controller, create a namespace to deploy it into, then get the released Kubernetes manifest for it from the GitHub release page and use `kubectl create` like so:
$ kubectl create ns kubeless $ curl -sL https://github.com/kubeless/kubeless/releases/download/0.0.18/kubeless-0.0.18.yaml | kubectl create -f -
That's it, kubeless is installed!
You will soon see three Kubernetes pods running. The kubeless controller, a Zookeeper pod, and a Kakfa pod. The controller can deal with functions that are triggered via HTTP calls but also via events. Being able to handle event triggers is key in serverless. To handle events, we chose to use Kafka, even though we could use any other event streaming system (e.g. nats). By default, we run a development Kafka installation, using Kubernetes stateful sets but single pods.
$ kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE ... kubeless kafka-0 1/1 Running 0 3m kubeless kubeless-controller-3241937899-8f5pm 1/1 Running 0 3m kubeless zoo-0 1/1 Running 0 3m
Deploying a Function
To deploy a function you use the `kubeless` CLI which is similar to the Google Functions CLI. You give a name to the function, specify its trigger, its runtime (e.g Python, Node.js) and which file stores the function, like so:
$ kubeless function deploy foobar --trigger-http --runtime python27 --handler foobar.handler --from-file foobar.py
Underneath, we use Kubernetes Third Party Resource Objects to store the function and create an API endpoint that the controller watches.
$ kubeless function ls +--------+-----------+----------------+----------+------+-------+--------------+ | NAME | NAMESPACE | HANDLER | RUNTIME | TYPE | TOPIC | DEPENDENCIES | +--------+-----------+----------------+----------+------+-------+--------------+ | foobar | default | foobar.handler | python27 | HTTP | | | +--------+-----------+----------------+----------+------+-------+--------------+
When the controller sees a new function, it starts a deployment and exposes it via a service. The function is injected into the Pod using a ConfigMap.
$ kubectl get pods NAME READY STATUS RESTARTS AGE foobar-3996720972-53zf5 0/1 ContainerCreating 0 8s
And of course, you can then call your functions:
$ kubeless function call get-python ... hello world
Note that by default, functions are exposed internally. To reach them from outside your Kubernetes cluster, kubeless provides a convenience wrapper to create what is a called an Ingress rule.
For folks who do not like the CLI, there is a graphical user interface (UI), that you can also run within your Kubernetes cluster. It will allow you to view all your existing functions, deploy new ones and also update existing functions. There is also some nice features like being able to view the logs and send test data to the functions. Check out the snapshot below for a quick sneak peek at this UI (built with react-redux FWIW).
kubeless also has a serverless framework plugin. It is being developed upstream within the serverless organization and is only the fifth such plugin after AWS Lambda, Azure functions, Google Cloud Functions and Apache OpenWhisk. I will show you how to use this plugin in a separate post, but needless to say, we are striving to make this plugin on-par with AWS lambda.
The bottom line is, if you are familiar with the serverless framework, the following will work with kubeless:
$ serverless create --template kubeless-nodejs --path foobar $ cd foobar $ serverless deploy $ serverless invoke -f hello $ serverless info $ serverless remove
So if you are into containers and Kubernetes, but want to try out serverless or deploy serverless based apps in your k8s cluster, check out kubeless and let us know what you think.
Opinions expressed by DZone contributors are their own.