Functions as a Service - deploying functions to Docker Swarm via a CLI
Finnian Anderson May 18, 2017
Functions as a Service or FaaS (by Alex Ellis) is a really neat way of implementing serverless functions with Docker. You can build out functions in any programming language and then deploy them to your existing Docker Swarm.
In this post we'll look at an experimental CLI for making this process even easier.
How it works
The diagram below gives an overview of how the FaaS function package, the Docker image, and the
faas-cli deploy command fit together.
To deploy a function onto a FaaS stack, you firstly must write the function itself. This is really easy and you can do it in any language which runs inside Docker (i.e. all of them). At the current time, the FaaS CLI supports Python and Node, so for this example we'll use Python.
My very simple fib function is written in Python:
def fib(n): if n <= 1: return n else: return fib(n-1) + fib(n-2) def handle(st): n = int(st) output =  for i in range(n): output.append(str(fib(i))) print(', '.join(output))
This code is saved in
sample/fib/handler.py. It's important to create a
requirements.txt file in the same directory (even if your Python code has no requirements from pip) because otherwise
pip install will throw an error.
Building the function package
The way FaaS runs the function is by running this inside Python:
from function import handler handler.handle(stdin)
When you build a function with the FaaS CLI, what it's doing is packaging up your function (
handler.py) and building out the parts for Docker to run the container.
The last step is to write the
stack.yml file which FaaS will use to build and deploy the function.
provider: name: faas gateway: http://localhost:8080 # your faas stack url functions: fib: lang: python handler: ./sample/fib image: developius/func_python-fib
To build the package, simply run:
$ ./faas-cli -action build -yaml ./stack.yml
Here is an example package for our
func_python-fib function, located inside
$ tree build/fib/ build/fib/ ├── Dockerfile ├── function │ ├── handler.py <-- called by index.py │ └── requirements.txt ├── index.py <-- Docker runs this └── requirements.txt 1 directory, 5 files
The package includes everything to allow Docker to run our function -
Deploying the function
Now that our function is built, we need to deploy it. Before we do this however, we must push our function to the hub so that all the nodes in the swarm can access it.
$ docker push developius/func_python-fib
Now for the deploy! This can be done with one command:
$ ./faas-cli -action deploy -yaml ./stack.yml
When you run this command, the function will be deployed to the remote Docker Swarm. How cool is that?
The final thing to do is to test your function deployed successfully. You can do this via the FaaS UI or via
Or, via curl:
$ curl -d "10" http://localhost:8080/function/fib 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
High Availability via autoscaling
FaaS supports Docker Swarm's replication feature, which allows auto scaling of functions directly inside Docker. FaaS makes use of this internally to make sure enough function replicas are available to deal with requests. It works by exporting metrics for Prometheus, which then generates alerts when thresholds are reached. The FaaS gateway will then scale up the functions when it receives these alerts.
This can be seen perfectly in the screenshot of my Grafana dashboard below.
In this post we've seen how to package and deploy a function using the FaaS framework. We've looked at how to write a function, how to build it into a function package and deploy it to a remote Docker Swarm. Pretty neat stuff.
I've built a number of other functions and hope to expand this to include more soon. I wrote a function to shorten URLs, using a service I built, which received a PR from Richard Gee to merge in an armhf Dockerfile for use on Raspberry Pies. This was a big milestone for me as I've never accepted a PR for one of my projects before!
You can find out more about the projects I've been doing with Docker on my blog at finnian.io/blog - including my DockerCon 2017 writeup! Feel free to get in touch on Twitter @developius and I'd love to hear your thoughts below.
Props to Alex Ellis for creating such an awesome tool, I look forward to participating in the development of FaaS in the future. It's worth noting that FaaS is currently considered experimental but you can expect more language templates amongst some other neat features. First... learn Go. 🙈