This post gives a straight-forward introduction to Serverless computing, then covers my top 3 features introduced to FaaS over the last 500 commits and finishes on what's coming next and how to get involved.

From that first commit FaaS went on to gain momentum and over 2500 stars on GitHub along with a small community of developers and hackers who have been giving talks at meet-ups, writing their own cool functions and contributing code. The highlight for me was winning a place in Moby's Cool Hacks keynote session at Dockercon in Austin in April. The remit for entries was: to push the boundaries of what Docker was designed to do.

What is Serverless?

Architecture is evolving

"Serverless" is a misnomer - we're talking about a new architectural pattern for event-driven systems. For this reason serverless functions are often used as connective glue between other services or in an event-driven architecture. In the days of old we called this a service bus.

Serverless is an evolution

Serverless functions

A serverless function is a small, discrete and reusable chunk of code that:

is short-lived

is not a daemon (long-running)

does not publish TCP services

is not stateful

makes use of your existing services or third-party resources

executes in a few seconds (based upon AWS Lambda's default)

We also need to make a distinction between Serverless products from IaaS providers and Open Source Software projects.

On one hand we have Serverless products from IaaS providers such as Lambda, Google Cloud Functions and Azure functions and on the other frameworks such as FaaS which let an orchestration platform such as Docker Swarm or Kubernetes do the heavy lifting.

Cloud Native - bring your favourite cluster.

A Serverless product from an IaaS vendor is completely managed so it offers a high degree of convenience and per-second/minute billing. On the flip-side you are also very much tied into their release and support cycle. Open-source FaaS exists to promote diversity and offer choice.

What's the difference with FaaS?

FaaS builds upon industry-standard Cloud Native technology:

The FaaS stack

The difference with the FaaS project is that any process can become a serverless function through the watchdog component and a Docker container. That means three things:

You can run code in whatever language you want

For however long you need

Wherever you want to

Going Serverless shouldn't have to mean re-writing your code in another programming language. Just carry on using whatever your business and team need.

Example:

For example cat or sha512sum can be a function without any changes since functions communicate through stdin/stdout. Windows functions are also supported through Docker CE.

This is the primary difference between FaaS and the other open-source serverless frameworks which depend on bespoke runtimes for each supported language.

Let's look at three of the big features that have come along since Dockercon including - CLI and function templating, Kubernetes support and asynchronous processing.

1. The new CLI

Easy deployments

I added a CLI to the FaaS project to making deploying functions easier and scriptable. Prior to this you could use the API Gateway's UI or curl. The CLI allows functions to be defined in a YAML file and then to be deployed to the API Gateway.

There is an installation script available and John McCabe helped the project get a recipe on brew.

$ brew install faas-cli

or

$ curl -sL https://cli.get-faas.com/ | sudo sh

Templating

Templating in the CLI is where you only need to write a handler in your chosen programming language and the CLI will use a template to bundle it into a Docker container with FaaS magic handled for you.

There are two templates provided for Python and Node.js, but you can create your own easily.

2. Kubernetes support

As a Docker Captain I focus primarily on learning and writing about Docker Swarm, but I have always been curious about Kubernetes. I started learning how to setup Kubernetes up on Linux and Mac and wrote three tutorials on it which were well-received in the community.

Architecting Kubernetes support

Once I had a good understanding of how to map Docker Swarm concepts over to Kubernetes I wrote a technical prototype and managed to port all the code over in a few days. I opted to create a new microservice daemon to speak to Kubernetes rather than introducing additional dependencies to the main FaaS codebase.

FaaS proxies the calls to the new daemon via a standard RESTful interface for operations such as: Deploy/List/Delete/Invoke and Scale.

Using this approach meant that the UI, the CLI and auto-scaling all worked out the box without changes. The resulting microservice is being maintained in a new GitHub repository called FaaS-netes and is available on the Docker Hub. You can set it up on your cluster in around 60 seconds.

Watch a demo of Kubernetes support

In this demo I deploy FaaS to an empty cluster, then run through how to use the UI, Prometheus and trigger auto-scaling too.

But wait.. aren't there other frameworks that work on Kubernetes?

There are probably two categories of Serverless frameworks for Kubernetes - those which rely on a highly specific runtime for each supported programming language and ones like FaaS which let any container become a function.

FaaS has bindings to the native API of Docker Swarm and Kubernetes meaning it uses first-class objects that you are already used to managing such as Deployments and Services. This means there is less magic and code to decipher when you get into the nitty gritty of writing your new applications.

A consideration when picking a framework is whether you want to contribute features or fixes. OpenWhisk for instance is written in Scala most of the others are written in Golang.

3. Asynchronous processing

One of the traits of a serverless function is that it's small and fast, typically completing synchronously within a few seconds. There are several reasons why you may want to process your function asynchronously:

it's an event and the caller doesn't need a result

it takes a long time to execute or initialize - i.e. TensorFlow / Machine Learning

you're ingesting a large amount of requests as a batch job

you want to apply rate limiting

I started a prototype for asynchronous processing via a distributed queue. The implementation uses the NATS Streaming project but could be extended to use Kafka or any other abstraction that looks like a queue.