Contents
Software was once delivered as monolithic, fear-inducing, complex forklift upgrades, with database schema migrations, application updates, library updates, configuration updates and plenty of downtime. Sometimes, there was a gut-wrenching irrevocable critical step in the process (often a schema update). Today, this is largely a relic and bad memory now, thanks, in part, to Virtualization and Containerization technologies, Network APIs and the move to microservices.
Death of the Monolith
The word monolithic in software authorship circles is (now) usually received as a derogatory remark. Approximately a decade ago, much software was still written and deployed in large, fraught, forklift updates.
These updates often required many software installation, data migration and reconfiguration steps. Usually, large libraries or packages, and sometimes wholesale system upgrade were part of the update process. The logic was to undertake updates infrequently, but take plenty of time in the preparation and testing. Though these updates purported to fix many bugs, introduce features and change behaviour, they could be quite risky and invariably introduced unexpected performance or behaviour changes.
(Anecdotally, I can report experiencing these sorts of releases as a consumer. I often elected to wait until the first or second point release of a piece of software, for example, RedHat-5.2, rather than 5.0 or 5.1. And, RedHat had comparably decent, quality control too; my point is that first releases were often buggy.)
Yes, the industry has improved! Not only are there more and better tools, but the process has also improved. Below, I'll examine some of the long-term trends, many of which converge in our hyper-networked world to support microservices.
At some point during their brief lifetimes, most software experiences teething problems, misses the intended goal, or omits an important feature. Many of the quality problems with software release have been addressed by a move away from monolithic delivery. This post covers trends in open source software delivery and tools for delivering software to infrastructure and distributed systems.
(I.e. this post doesn't treat software intended for installation on an end-user node, like an MacBook, Windows system or Android; though many of the trends affected these target devices and platforms, as well.)
Long-term Trends
An unfortunate feature of software (and potentially any human endeavor) is our ability to conceive far beyond our capability.
In the same way that our first (non-cave) houses probably collapsed and our first carts (and cars) broke down regularly, our first software infrastructures were brittle. While it was already clear in the 1980s and 1990s that monolithic software updates were tricky and dangerous, they continued to be a somewhat common experience because of a lack of tools to enable our vision.
Below, I identify several long-term trends that converged to enable the adoption of what are now called microservices.
Three distinct trends in networking, software development and operational deployment encouraged systems architects, operations teams and developers to create this microservices model. It is very nearly the opposite of a monolithic model, allowing frequent and small updates.
The transition began with the increasing prominence and availability of networked systems and the decreasing need to send CDs or disks with shrink-wrapped software. Even for end-user software, it is becoming quite rare to find companies offering physical media in 2016!
Networking and Network-Delivered Software Updates
The first long-term trend to start to unravel the notion of monolithic software update was the always-on, always-available network. When shipping a shrink-wrapped piece of software, there were few alternatives to this monolithic release model. With the rise of near-ubiquitous connectivity, some organizations (e.g. browser vendors, Linux distributors) experimented with hybrid deliveries of software via CD/DVD and over the network. By the late 1990s, most Linux distributions already had online, network(able) update support.
Networking and The Cloud
Though some organizations manage their own data centers, integration and build systems, the move toward hosting services in third-party managed data centers (The Cloud) has largely replaced the model for greenfield infrastructure development.
FIXME: expand FIXME: expand FIXME: expand
With the rise of Virtualization over the last 15 years and the cloud over the last 7 years, operating system images (e.g. .qcow2 and .vmdk) and containers like Docker (built on lxc). Provisioning is often accomplished through an Application Programming Interface (API) or interactively through a web interface provided by outfits like AWS, Rackspace, or Azure.
These developments enable operational dynamism for small firms and decrease the amount of time required to deploy new compute and storage resources. Infrastructure has become commodified.
Network APIs
The second trend (dependent on the network, though) was the proliferation of networked APIs. Library APIs had became a well-understood and common feature of software systems decades earlier, but the increasing use of networked systems meant that the programming and business logic could exist on another computer, in another data center, or even at another firm [0].
The mid-aughts (2000s) brought an explosion of technical tools to support network APIs. XML-RPC, JSON-RPC, SOAP, and, particularly, REST(-ful) APIs all experienced success in the development world.
Internally, firms could take advantage of these new network APIs and break up their applications into smaller pieces, the first step toward microservices.
Virtualization
The third trend was widespread adoption of virtualization (and its many logical offshoots, like Containerization below). Tools like VMWare, Xen, and VirtualBox offered the possibility to run multiple complete operating systems inside a single physical box. Initially, the benefit accrued to operations teams as they could consolidate a large number of small services on different computers into a single physical node, but retain the management flexibility.
Containerization
One of the developments broadly subsumed under Virtualization, but deserving separate mention is the rise of containerization. It is a slightly different application of the concepts of virtualization. In short, a container can consume less of a shared resource (e.g. memory, disk/filesystem space) than a fully virtualized operating system image.
Both Kubernetes and Docker are popular examples of toolkits making use of Linux Containers (LXC). The clever combination of a union filesystem (layered filesystems) and rich development and administrative tooling have brought a good deal of fame to Docker in particular.
[Correction 2016-04-22: An attentive reader pointed out my misapprehension of Kubernetes, which is a container system management tool, rather unlike LXC and Docker themselves. Apologies to my readers and thank you for the feedback!]
The critical piece, however, is the management tooling.
Most of the Infrastructure as a Service (IaaS) firms in The Cloud offer direct support for deploying Docker images.
Many firms (and software projects) have chosen Docker as an operational deployment strategy for their software, for two reasons. First, the barrier to creating Docker images is quite low for developers and second, the operational management of the Docker images themselves is not hard.
Therefore, the organization can focus effort on the business goals, for example, the application or service itself!
Delivering applications as microservices
The combination of these three long-term trends eliminated need for complex, whole-application-replacing, fear-inducing, forklift upgrades. The emergence of the convenient tooling of containerization has enabled architects, system designers and developers to create discrete sets of network APIs that are intended to be deployed together on a single, independently-managed (container or) node. The general term adopted by the industry for this model is microservices.
Definition of microservices
The choice of the prefix micro simply means small in this context. Nothing fancier. (This prefix gained popularity with the rise of microformats among others.) In short a microservice is
- a self-contained service providing a clear, versioned API (or multiple versions simultaneously to support migrations and/or older client software)
- as logical unit of software performing one task; as simple as possible, but as complex as necessary
- often, horizontally scalable, i.e. many instances can be deployed to handle increased traffic or usage
- easy to replace with an update package/image
- often accessible via the network
- often dependent on another microservice
Here's a good article on microservices. by the fairly well-known Martin Fowler. His discussion also spends more time describing, defining and mapping microservices as an organizational capability, and alludes to the inescapable and well-known Conway's Law.
Containerization is not microservices
Because containerization and microservices have come of age in recent years, many conflate the two, but they are distinct. It is possible to build small, self-contained, individually-scalable services without taking advantage of virtualization and containerization.
Most of us, who have run any Linux system for any appreciable time have had the desire to add a service. How does one accomplish this? I will give a short command-line snippet of how I could do this on a node grabbed somewhat at random:
# apt-cache search jabberd jabberd2 - Jabber instant messenger server # apt-get install jabberd2
Now, I have a jabber server running.
Good packaging hygiene has enabled this. This may seem a terribly obvious point; but I stress the benefits of good packaging here.
Ever present needs
Essentially, a microservices model offers operational flexibility for moving software components around and can offer more freedom to the development team supporting a specific service, because everything behind the service is up to the team. Of course, there are the omnipresent needs:
- each service should support rollbacks, a.k.a. software reversion if something goes wrong in an update, roll it back
- a practice of decommissioning old, or no longer necessary services
- monitoring of availability, performance and behaviour an update to service A might tickle a latent bug in B; without monitoring, how would you know
- strong diagnostic tooling and experience
- a mechanism to keep the entire stack underneath the microservice up to date
[0] | It is precisely this part of the trend that led to the rise of Software as a Service (SaaS) organizations. One good and lasting example is SalesForce. |