Serverless Edge-to-Cloud computing: the open source way

Alex Glikson
Apache OpenWhisk
Published in
6 min readMar 18, 2017

Proliferation of the Internet of Things drastically increases the amount of data generated at the edge of the network. Examples include sensor data, events generated by devices and gateways, multimedia files such as camera images. While there are many ways to build a custom solution for data processing spanning the cloud and the edge, it would be beneficial to standardize on a programmable platform that would make it easy to develop, deploy and operate custom data pipelines, preferably taking advantage of the emerging ‘serverless’ event-driven paradigm, and preferably open source.

In this post we introduce LEON — a research prototype built with Apache OpenWhisk, Node-RED and Docker, making it possible to use the same processing elements (OpenWhisk actions) in the cloud and at the edge, wired between them and with the data sources using Node-RED.

LEON: Local Execution of OpenWhisk actions with Docker and Node-RED

We demonstrate LEON in action on an example of face detection, offloading the bulk of the processing — finding face rectangles in incoming images — to the edge, while keeping in the cloud the knowledge base of faces used to determine identity of people captured in the images.

Face detection with OpenWhisk flow spanning the cloud and the edge, orchestrated with Node-RED

Let’s explore this in more detail.

Face detection with OpenWhisk and Node-RED

Node-RED is capable of incorporating invocation of OpenWhisk actions into a flow, by running the action in the cloud (e.g., in Bluemix) and passing JSON inputs and outputs from/to other nodes in the flow. In the face detection example, the flow could look like this:

Node-RED flow for face detection implemented as a sequence of OpenWhisk actions

The flow is triggered by Node-RED watching for new files in the “images” directory. Then we detect face rectangles leveraging the popular opencv library, and determine identity of people using the Watson Visual Recognition service in Bluemix. Finally, we visualize the outcome by keeping just the faces, plus the name labels (as shown in the figure above). The results (both the original image and the augmented one) are displayed on a custom Node-RED dashboard page.

The 3 actions are implemented in nodejs, with roughly 50 lines of code each.

OpenWhisk actions comprising the face detection flow (CLICK TO ZOOM IN)

Notice that since the final recognition and identification happens in the cloud, the logic at the edge doesn’t have to be 100% accurate, so using the popular opencv library with a standard faces classifier (with some false-positives) should be sufficient.

Until now we haven’t done anything new. You can run Node-RED on your Raspberry pi, and make the above flow work across your IoT environment and Bluemix. However, this means that every new image has to be sent to the cloud — even if the face occupies a small portion of the raw image, or even if there are no faces at all (think of a fixed or mobile camera used to monitor people in a building or a parking lot). The solution is, of course, to run the first action on the IoT gateway, and then send the face rectangles to the cloud.

LEON: Local Execution of OpenWhisk actions with Docker and Node-RED

In previous blogs we explored the building blocks to run OpenWhisk actions at the edge, and to manage their life cycle at scale (1, 2). Now we add one more piece to the puzzle. Here comes LEON — the technology enabling seamless orchestration of OpenWhisk action containers locally with Docker and Node-RED. From the user perspective, it is just an extended version of the Node-RED node allowing to run OpenWhisk actions. But now the user has an extra option in the action node configuration — Runtime. It could be the regular OpenWhisk service in the cloud, or a Local Runtime, pointing to a Docker engine (currently, due to network connectivity reasons, it has to be the same one that hosts the Node-RED container itself). In both cases, the OpenWhisk service in the cloud is used as a centralized repository of actions.

LEON adds the option to configure an OpenWhisk action node in Node-RED to run locally

Under the hood, when this node is deployed, several things are happening. First — the metadata and the code of the action are retrieved from the centralized OpenWhisk service. Second — a container is provisioned on the local Docker host, using the image specified in the metadata. Third — the action code is injected into the container, using the standard OpenWhisk internal interfaces. And lastly — the incoming and the outgoing links are automatically routed to the action container, passing the JSON inputs and the JSON outputs according to the Node-RED flow.

Face detection action metadata and code (base64-encoded zip package)

Notice that in order to mitigate potential differences between the cloud and the local environment (e.g., x86 vs ARM-based HW), LEON assumes that the ‘base’ images exist locally on the Docker engine, leaving this up to the deployer to decide whether just to pull standard OpenWhisk images from Docker hub, or to build/use equivalent images suitable for the local deployment (e.g., taking advantage of resin.io images). Simple setup of base images would look like this:

$ docker pull openwhisk/nodejs6action
$ docker tag openwhisk/nodejs6action nodejs6action
$ docker pull openwhisk/pythonaction
$ docker tag openwhisk/pythonaction pythonaction

Secondly, in order to separate architecture-dependent libraries (such as opencv) from the action code itself, we need to create the action specifying both the image (including the necessary libraries, following the ‘blackbox’ notation) and the action code (native NodeJS). This is currently not supported by the WSK CLI, so meanwhile we can use the REST API directly:

#!/bin/sh
ACTION=facedet
ZIP=$ACTION.zip
IMAGE=glikson/nodejs6opencvaction
base64 $ZIP --wrap=0 | echo "\"$(cat)\"" | jq "{namespace:\"_\", name:\"$ACTION\", exec:{kind:\"blackbox\", image:\"$IMAGE\", code:., binary:true, main:\"main\"}}" | curl -X PUT -H "Content-Type:application/json" -H Authorization:Basic\ $(wsk property get --auth | awk '{print $3}' | base64 --wrap=0) -d @- https://openwhisk.ng.bluemix.net/api/v1/namespaces/_/actions/$ACTION?overwrite=true

And here is the Dockerfile for the image:

FROM openwhisk/nodejs6action
RUN apt-get update && apt-get install -y libopencv-dev
RUN npm install -g opencv --unsafe

Furthermore, notice that action containers are essentially long-running, serving /run REST requests on each incoming event (this is handled by the action proxy). Unlike OpenWhisk in the cloud, at the moment LEON does not preempt local action containers, preferring simplicity and low execution latency over elasticity. This approach makes sense in relatively small and static environments such as an IoT gateway performing a particular set of tasks. However, we plan to explore different approaches in the future.

Lastly, although such pipelines are quite powerful, the fact that the state between actions in a sequence can be passed only via the JSON payload is somewhat restrictive. In ‘native’ Node-RED function nodes it is possible to maintain global variables, accessible from several function nodes and persistent across invocations. A similar mechanism could be implemented with OpenWhisk actions too.

That’s it! Following this methodology and using LEON, one can easily build applications spanning the cloud and the edge, taking advantage of OpenWhisk, Docker and Node-RED — all open source.

Feel free to try it out at http://github.com/kpavel/leon-openwhisk-local/ and share your impressions and thoughts.

You can watch a short video summarizing this post (and the face detection example) at https://youtu.be/jS6pyvDg_sU

P.S. If you happen to be at the IBM InterConnect conference this week (March 19–23, 2017), the following sessions are going to touch on aspects related to this post:

https://myibm.ibm.com/events/interconnect/all-sessions/session/7367A

https://myibm.ibm.com/events/interconnect/all-sessions/session/7122A

--

--