"Serverless"? And on my own servers?!

This post will introduce Serverless, then showcase Functions as a Service - a serverless framework for Docker, winner in the Cool Hacks contest for Dockercon 2017, by Docker Captain @alexellisuk.

In this episode, we will:

  1. briefly touch on what Serverless is/means (to me)
  2. test drive FaaS for Docker
  3. test one of the already available functions (demo)
  4. create and deploy a new function

What is "Serverless"?

Serverless architectures are internet based systems where the application development does not use the usual server process. Instead they rely solely on a combination of third-party services, client-side logic, and service hosted remote procedure calls (FaaS). - You can read more on Martin Fowler's bliki

Internet based does not mean you cannot host this on your machine!

An easier definition

In laymen terms, you write the code, usually event driven, and someone else provision the servers, the running environment, and execute your code!
It promises to handle spikes in traffic, scheduling your code as necessary to serve requests. Requests are usually billed per execution rather than per execution time.

Why use it?

The real incentive to use a Serverless architecture are cost, (if you have non constant or bursty traffic) and the architectural style/programming model (one step closer to a functional world).

AWS Lambda, Google Cloud Functions, IBM OpenWhisk or Azure Functions are examples of implementation of today's cloud providers.

There is no free lunch though

Like most things, Serverless comes with it's set of concerns. but we won't talk about those for now. (I'll name just one: testing is harder)

A misnomer, really...

But wait, after all, there are servers! Then why do we call it Serverless?

should it be Server(less-ops)?

meme

It is just that:

  • we do not have to provision, or operate those servers
  • we do not have to do the capacity planning for the peak demand
  • we do not have to handle the autoscaling
  • we approach a pay as you go model

What can I use Serverless for, today?

Do you want to build some RESTful APIs to respond to an action, respond with data, or just serve static content, like images or gif?

Maybe you want to create a webhook for when your Github repo gets a star and you want to light up a bulb in your house?

Maybe even spin off your own IFTTT or Zapier?

Well, these kind of use cases hit Serverless sweet spot.

Where it doesn't really fit (yet)

  • HPC (due to loss of pricing benefits and/or latencies associated with the model)

How to get started today?

You might say to yourself, ok this seems like a thing to learn, but I don't want to spend hours paying while/learning/locked in/.. about consoles of AWS, Azure, GCP or any other.

This is one of the main drives behind FaaS - to make it easy to build and test Serverless architecture on your own hardware. (For the whole background story leading to FaaS, you can read this post by Alex Ellis)

Let's go already.

Hand's on FaaS

To test drive FaaS, Alex was nice enough to get you going in a one liner!

All you need to do first is install Docker:

curl -sSL get.docker.com | sh

(And if you are lazy, head over to http://play-with-docker.com/ and click "Add new Instance". - but this won't be on your server - unless you deployed play with docker on your machine as per my previous post)

docker swarm init && \
  git clone https://github.com/alexellis/faas && \
  cd faas && \
  ./deploy_stack.sh && \
  docker service ls

Once all services listed with docker service ls are up and running (all services have at least one replica) :

NAME                MODE                REPLICAS            IMAGE
func_echoit         replicated          1/1                 functions/alpine:health
func_base64         replicated          1/1                 functions/alpine:health
func_markdown       replicated          1/1                 alexellis2/faas-markdownrender:latest
func_nodeinfo       replicated          1/1                 alexellis2/faas-nodeinfo:latest
func_decodebase64   replicated          1/1                 functions/alpine:health
func_wordcount      replicated          1/1                 functions/alpine:health
func_gateway        replicated          1/1                 functions/gateway:0.5.3
func_webhookstash   replicated          1/1                 functions/webhookstash:latest
func_prometheus     replicated          1/1                 functions/prometheus:1.5.2
func_hubstats       replicated          1/1                 alexellis2/faas-dockerhubstats:latest
func_alertmanager   replicated          1/1                 quay.io/prometheus/alertmanager:latest

First encounter with FaaS

At this point you can start interacting with FaaS.

Navigate to: http://localhost:8080/ in order to see the UI portal of FaaS.

faas-ui

This UI reminds me a bit of Postman.

Here you will see a list of functions prepackaged with FaaS, already deployed by the above command, waiting for you to test!

There is more than meet the eyes in this simple deployment. For instance, here we already have a portable, easy to use, auto-scaling on demand with Prometheus metrics/alerting! and a Gateway... and the ability to add new functions...

Testing a prepackaged function

Let's test two prepackaged functions, one through the UI and the other through the REST interface.

Interacting through the UI

Let's test the wordcount function through the UI. This function expects a text in and will respond with the number of words/letters in that text.

For that, just click on the left func_wordcount:

Type anything you like (including the text, anything you like ;)) in the Request body then click INVOKE.
You should see the Response body adapt with the number of words/letters and the function's invocation count increment!

faas-testdrive-ui

Sweet.

Interacting via curl

Let's now test the markdown function through the command line. This function expects a markdown text, and will convert it to an html equivalent:

curl -X POST http://localhost:8080/function/func_markdown -d "> This is FaaS in action! - JM"

and get the html back:

<blockquote>
<p>This is FaaS in action! - JM</p>
</blockquote>

Packaging my own function

Ok that's really nice. But what about adding my own function?

Again, we can do this either through the UI or via the REST API.

Let's create a function to reverse text given as input...

To do that, I will use an Alpine base image and the rev command.

Click CREATE NEW FUNCTION link on the left

and fill the form as per the below:
add-function

The equivalent to this from the command line:

curl localhost:8080/system/functions -d '{"service": "esrever", "image": "functions/alpine", "envProcess": "rev", "network": "func_functions"}'

Or you can also use the new and shiny faas-cli to scaffold, build and deploy to FaaS. (comming in next post)

Now, check the UI to see the newly added function:

reverse-func

Test it by giving it the service name we used: esrever, so it become reverse.

You can also do that from the command line of course:

curl -X POST http://localhost:8080/function/esrever -d ".emosewA si SaaF###"

FaaS is Awesome.

Coming up soon

In a future post we will explore how FaaS will behave on my hybrid Swarm of Raspberry Pi, composed of one Zero, few Rpi2 and few Rpi3.

We will also be writing some code in Python, and deploying it to FaaS ... all this using the new and shiny faas-cli

We may wire an IFTTT webhook or do an image recognition using TensorFlow :)

Stay tuned.