Microservices and Docker for geographically distributed projects

The HyVar project, as with most Horizon 2020 projects, has partners from several European countries. While this is good for enabling cooperation across borders and opening up for new international collaborations, geographically distributed projects come with several challenges. One of the key issues is pulling the R&D results from each partner into a cohesive deliverable where the whole is greater than the sum of its parts.

In HyVar, the partners represent both academia and industry. Travel budgets are finite and thus the opportunities to sit down together and make things work are limited. The main output is a hybrid variability toolchain, deployed on a scalable cloud infrastructure. Each partner is responsible for their piece of the toolchain puzzle, be it a DSVL cross compiler or hybrid product reconfiguration. It is a complex pipeline where each component is critical. When face-to-face time is scarce, how can we make sure that all the pieces fit together in the end? Moreover, we do not have one implementation partner but rather many. Different partners have different approaches to software engineering; this further complicates the task of final integration.

Microservices

One of our first design choices was to think of the HyVar toolchain as a collection of microservices. Microservices is an implementation strategy where a software system is constructed as a collection of independent services, each of them easily deployable, cohesive and without any coupling with other services. All services are accessed through a lightweight, open communication protocol; in our case through RESTful web APIs and JSON messages. Microservices can be considered as a specialisation of the classic service-oriented architecture (SOA) paradigm.

Why is formulating the toolchain as a collection of microservices a useful strategy? First of all, it forced us to think modularly about the whole pipeline: What are the tasks of the different components, what information do they need to perform their duty, and what are the minimum viable services. Moreover, we had to make sure that there was no shared state, which in general is a good thing. Once we had a common, agreed-upon specification, each partner could work independently without getting into discussions on implementation details. As long as each service is accessible through a web API, the toolkits and programming languages used do not matter much. This allowed each partner to use the tools and languages they felt most comfortable with to achieve their goals. As long as the specification and API is adhered to, the components should work together. Accordingly, the integration risk is greatly reduced.

Another benefit of a microservice architecture is that it provides more flexibility when it comes to scaling the system on the cloud. Different services have different resource needs; some may require more aggressive scaling approaches. As an example, we have already identified our final binary compilation service as being particularly resource-intensive, thus requiring extra scaling and caching attention. Also, the lack of shared state eases the scaling task and has benefits on both a theoretical (our work on modelling scalable cloud services) and practical (actually making it scale) level. Being able to scale the services independently of each other makes us a lot more confident that the final product can work in real-life scenarios and not just with our test cases.

Finally, the microservice approach makes the toolchain easier to extend and modify, not the least in comparison with a classic, monolithic software system. For non-automotive domains, customer requirements may be different. Being able to shuffle services around and easily add new services makes the toolchain a lot more flexible. For instance, some clients may be wary of running the entire toolchain on a public cloud infrastructure and may want to mix in legacy components running on their existing servers. With a service-oriented approach, this is a feasible task.

Did microservices solve all of our integration challenges? In practice, there were more hurdles to overcome, especially for deployment. Having a microservice work on your computer or in the test lab is a good start, but the HyVar toolchain is meant to be running on the cloud. The cloud is not a clearly defined entity: there are multiple public cloud providers with different platforms and also various private cloud architectures. What we gained by allowing each partner implementation flexibility could easily be lost by having to make each service, with their different dependencies, work on any given cloud infrastructure. For this we turned to Docker.

Docker

kudr42x_itxghjhsindzeknef0jlt3nevxtrye3tqco

Docker is a virtualization technology that recently has seen a lot of traction and usage. With Docker you bundle your software—in our case each individual microservice—with all the libraries, tools and dependencies it needs to function. This is known as a Docker container. Such containers are more lightweight than traditional virtual machines, and it is not uncommon to run several concurrent containers on e.g. the same Linux instance. Unlike virtual machines, a Docker container does not include an entire operating system.

A Docker container can be considered an instance of a Docker image. To build an image, you start with a base layer image. A Dockerfile is written; this file contains a set of instructions similar to a shell script that specifies how your image should be provisioned. Once the image is created it is used to launch a container. The image can freely be shared and is completely standalone.

While useful for scaling and encapsulation, for us the real utility in Docker lies in its “build once, run anywhere” philosophy: if your container works locally it is guaranteed to work just the same on any Docker-compatible system, be it on the cloud or anywhere else. When the operating environment is no longer a critical component, the tasks of integration and deployment become simpler. Returning to the challenges of HyVar being a geographically distributed project, this enabled each partner to work in isolation on their components and then distribute them to the rest of the project without having to worry about whether the other partners could use them or not. As long as the Dockerfile and the necessary supporting files are there, it will work on any system that supports Docker, such as e.g. Amazon Web Services, Microsoft Azure or your own laptop. Furthermore, it became possible to choose supporting technology freely without having to worry about whether it would work in production or not. As long as the Dockerfile compiles and the launched container fulfills the API specifications, this was as strong a guarantee as any that the delivered service would be deployable.

Conclusion

In conclusion, microservices and Docker have proved very useful when putting together the pieces of a complex project such as HyVar. Integration and deployment are critical parts of distributed projects which Docker has helped make more manageable. We have still had our share of integration issues but they have mostly been related to interface omissions or bugs in the services themselves. There are also downsides to service-oriented architectures and containerisation, one of the major being debugging when something goes wrong. Having to dig through multiple layers of virtualization does make bug finding more difficult, so putting some additional thought into logging and traceability is clearly beneficial. Nonetheless, so far our container-and-microservice approach has definitely helped keep the HyVar project on track.

The reconfiguration engine HyVarRec

HyVarRec is a tool developed within the HyVar project that allows to reconfigure an  existing configuration for a given Software Product Line when it is subject to contextual changes.

hyvar_ref_flow

HyVarRec requires different sources of input: the Hybrid Feature Model describing the software product, the current configuration Cof the software product, the values of the contextual information Ctx, and the user profile P . The primary function of the contextual reconfigurator is to provide a valid configurations Cnew for the context Ctx that maximize the preferences of user profile P. In case of two configurations of equal quality regarding the maximization of the user preferences, the one that minimizes the difference between the initial configuration C0 is provided. This means that HyVarRec first tries to minimize the number of feature removals needed to transform C0 into C new and, later, to maximize the
number of attributes which values could be kept the same. Finally, HyVarRec outputs the configuration Copt, which is the optimal configuration in the given context, satisfying as many preferences of P as possible.

HyVarRec could be installed using docker container technology available for the majority of the operating systems. It can therefore be used simply sending a post request to the server deployed by using docker.

HyVarRec is written in python, open source, and freely available from https://github.com/HyVar/hyvar-rec.

Workshop on Feature-Oriented Software Development (FOSD)

Part of the HyVar consortium is responsible for organizing the Workshop on Feature-Oriented Software Development (FOSD). Find it here: http://fosd.net/workshop2016

Abstract

Feature orientation is an emerging paradigm of software development. It supports the automatic generation of large-scale software systems from a set of units of functionality, called features. The key idea of feature-oriented software development (FOSD) is to explicitly represent similarities and differences of a family of software systems for a given application domain (e.g., database systems, banking software, text processing systems) with the goal of reusing software artifacts among the family members. Features distinguish different members of the family by their variable parts. A feature is a unit of functionality that satisfies a requirement, represents a design decision, and provides a potential configuration option. A challenge in FOSD is that a feature does not map cleanly to an isolated module of code. Rather, it may affect (“cut across”) many components/artifacts of a software system. Furthermore, the decomposition of a software system into its features gives rise to a combinatorial explosion of possible feature combinations and interactions. Research on FOSD has shown that the concept of features pervades all phases of the software life cycle and requires a proper treatment in terms of analysis, design, and programming techniques, methods, languages, and tools, as well as formalisms and theory.

 

Track on «Variability Modelling for Scalable Software Evolution» @ ISoLA 2016

The aim of this special track is to bring together researchers and practitioners to present and discuss cutting edge technology from software product lines, software upgrades and scalable cloud to support highly individualized and reconfigurable distributed applications. Topics of special interest within the track are a) frameworks, languages, and methodologies, b) cloud and mobile as well as c) context-awareness. The individual contributions are put into the context of variability modelling for scalable software evolution.

http://www.isola-conference.org/isola2016/

Track Organizers

  • Ferruccio Damiani, Univ. of Torino
  • Christoph Seidl, TU Braunschweig
  • Ingrid Chieh Yu, Univ. of Oslo

HyVar

horizon2020-300x88HyVar Architecture

HyVar addresses continuous software evolution in distributed systems by proposing a framework for hybrid variability. The framework combines:

  • Domain specific variability language to describe evolution as software product line.
  • Scalable cloud infrastructure for monitoring and individualized customization of software upgrades for the remote devices.
  • Over-the-air upgrade technologies.

For more details see the synopsis.