Multi-OS Serverless functions with Docker
In this post I'll show how you can build and deploy multi-OS containers with Docker and the OpenFaaS Serverless functions and why multi-OS clusters are important.
OpenFaaS is a serverless functions framework for Docker and Kubernetes which is experiencing viral growth and interest.
Windows and Linux play well together with Docker
Why do we need multi-OS?
In the container world Linux dominates, but as of last year Windows Containers support became GA and that meant running ad-hoc Docker containers with Windows executables was possible on Windows 2016 Server Core and Windows 2016 Nano Server.
See also: Windows Containers on Windows Server
Companies which have a skill-set based around the Windows operating system or legacy products to support can still benefit from using containers for packaging and running their code. Some companies make use Windows technology like .NET 4.5 alongside back-end services running on Linux such as: Redis, MongoDB or RabbitMQ.
Having a multi-OS or hybrid cluster means you can chose how to architect a solution - picking the right OS for each application or back-end.
Use-case: a hybrid serverless cluster
With Docker Swarm it's now possible to bootstrap a mixed-OS cluster and deploy services to the correct nodes through "placement constraints".
I'm going to list everything you need to do to deploy OpenFaaS on a multi-OS Linux and Windows cluster including a tester function for Windows.
Definitions
What is a placement constraint?
A placement constraint specifies things which must be true about a node for Swarm to place your container there.
- Linux only:
docker service create --publish 80:80 --constraint "node.platform.os == linux" nginx
- Windows only
docker service create --publish 80:80 --constraint "node.platform.os == windows" microsoft/sample-nginx
There are other properties of nodes we can use for placement constraints including node labels such as a label for nodes with "SSD" storage, or high network bandwidth.
Constraints are also available in Kubernetes - Assigning Pods to Nodes
Build your cluster
- Get Linux
You can provision your Linux host on any developer cloud or via a VM. We'll be using the Linux hosts to run the core OpenFaaS services.
Get Windows
The easiest way to get a Windows 2016 server is to pick the Windows 2016 Datacenter edition from the Azure marketplace.
There is also a free alternative in the Play With Docker project which will give you a temporary Linux host for up to 5 hours.
I tested a preview of Windows support in Play With Docker in this blog post - so keep an eye out for when that goes public.
Once you have setup two VMs or two hosts on the cloud you can connect them together with two commands:
On the Linux host:
$ docker swarm init --advertise-addr=<linux_public_ip_here>
On the Windows host:
$ docker swarm join <join-token> <linux_public_ip_here> --advertise-addr=<windows_public_ip_here>
Use the join-token from the command above, or type in
docker swarm join-token worker
.
An important step is to include the flag --advertise-addr
which is not part of the default output you receive from the Docker CLI.
- Now verify the hosts are connected:
ID HOSTNAME STATUS AVAILABILITY
k9ailx1aj9rrr9l0fb6zlk6bd * lin-01 Ready Active
tnnccnfrhc296r88ou1q0cuxu win-01 Ready Active
In this example I provisioned both hosts in the same region to reduce latency and data transfer fees.
- Deploy OpenFaaS
Functions as a Service (OpenFaaS) - a serverless framework for Docker & Kubernetes is available on GitHub.
On the Linux master deploy OpenFaaS - this should take less than 60 seconds.
$ git clone https://github.com/alexellis/faas
$ cd faas
$ ./deploy_stack.sh
A full deployment guide is available here for Docker and Kubernetes
- Build a Windows Dockerfile
When I asked a fellow Docker Captain Stefan Scherer what I could run in a Windows Container that wouldn't also run easily in a Linux container he suggested ipconfig.exe
- which gives the available IP addresses and adapters on a host or container.
This is what your Dockerfile looks like for OpenFaaS:
FROM microsoft/nanoserver:latest
ADD https://github.com/alexellis/faas/releases/download/0.6.4/fwatchdog.exe fwatchdog.exe
ENV fprocess="ipconfig.exe"
CMD ["./fwatchdog.exe"]
Dockerfile
I've already built and pushed a Docker image called alexellis/windows-ipconfig:nano
.
- Get the FaaS CLI
Grab the FaaS-CLI from the GitHub releases pages. Download the "faas-cli.exe" and save it within your C:\Windows directory or somewhere in the %PATH% variable.
https://github.com/alexellis/faas-cli/releases
Let's create a YAML stack file for the OpenFaaS CLI:
provider:
name: faas
gateway: http://localhost:8080
functions:
ipconfig:
image: alexellis/windows-ipconfig:nano
skip_build: true
environment:
suppress_lock: true
constraints:
- "node.platform.os == windows"
./ipconfig/stack.yml
Since we already have an image built out we can now go ahead and deploy the function:
> faas-cli.exe deploy -f stack.yml
Deploying: ipconfig.
Removing old service.
Deployed.
200 OK
URL: http://remote_ip:8080/function/ipconfig
You can now navigate to the OpenFaaS UI Portal on your Linux host via port 8080 and invoke the function or do it via the CLI with faas-cli invoke --help
.
The IPv4 address of the container is highlighted in blue.
For an experiment you can scale up the ipconfig
function to 5 replicas then hit "Invoke" over and over until you see all the IPv4 addresses shown in the command output.
Wrapping up
So we've taken a look at placement constraints and node OS properties which are built into Docker Swarm. We prepared a hybrid cluster and then deployed a Linux application OpenFaaS and create a Serverless function for a native Windows binary, then scaled it up.
Please show support for the Open Source project and Star the GitHub repo.
Find out more about OpenFaaS and Serverless
New to Docker? Get started with Docker here