With the inevitable onslaught of IoT (Internet of Things) devices, there will be increasing need to squeeze more complex software on a large array of low cost and low power devices. Our project wanted to examine what the next generation of IoT software would like to support this trend of increasing complexity and interconnectivity. We chose to look at an approach that enabled us to design multiple cooperating single purpose software services on a single multi-core CPU.. We call these this approach “nanoservice architecture”. Much like microservice architectures, but much smaller, faster and fine-grained than micro-services.
For this project we wanted to build a proof-of-concept nanoservice that uses the Predix Asset Performance Management API’s to submit time-series data for future analytics. To build this nanoservice we chose to design and build our own dedicated operating system using a Unikernel. Unikernels combine service/application software and only the operating system libraries that are needed to make the application work. The result of this approach is a nanoservice that is 10 to 100 times smaller, boots in milliseconds, and provides a very small attach service. Our nanoservice is essentially tiny dedicated operating systems whose sole purpose to submit time series data to the Predix APM.
Given the our nanoservice goal, we had several project objectives:
Determine if we could run a bare-metal hypervisor (i.e. Xen) directly on the Edison board Determine an appropriate Unikernel toolset to use for building our nanoservice / dedicated operating system Use the Go programming language to build our sample application to submit the time series data to the Predix APM system Build the nanoservice / operating system and deploy it
How We Built It
We wrote an application that mimics sending sensor data to the Predix APM Ingestion Endpoint. This application was written in Go compiled into a unikernel that pulled in just the minimal set of operation system libraries that are required by our application. The result of this build process creates Xen image that can be run on top of the bare metal hypervisor. The size of our nano service is about 6MB. We then created a bootable disk on AWS for an EC2 instance that allows us to deploy on top of Xen.
There were a number of problems we ran into. First, The Edison board has an older version of the kernel which did not let us deploy either a Xen or Linux KVM compiled unikernel. This hurdle caused us to switch to an AWS deployment, but with more time and sleep we believe we could have rebuilt a hypervisor for it. Second, all the Unikernel tools we found had a reliance on Liinux static libraries that needed to be rebuilt and linked into the nanoservice Unikernel image. To overcome this obstacle, we switched our development environment to Ubuntu. Third, we are new to the Go programming language, so we were learning the language on the fly.
Our things that we are most of proud of:
Getting a Unikernels to actually compile and build into a deployable format Building our first working Go programming Getting a running proof-of-concept
What We Learned
Unikernels are still bleeding edge, but we expect them to play a big role in the IoT space in the near future Xen hypervisors for IoT devices are going to need some work Go seems to be well suited for systems level programming
What’s Next for Predix Unikernel
Use the proof of concept to design a new IoT collection of composable nano-services that can support Predix and other cloud services Further development for Xen hypervisors for IoT platforms Build sample nanoservices
- Ubuntu tools
- Amazon Web Services