Container services: Hello from the outside!

Container services are changing how applications are deployed and managed. But what exactly are they and how do they compare with other ways of delivering platforms?

container technology cloud
Thinkstock

Gary Olliffe, a research director at Gartner, published an insightful post titled "Microservices : Building Services with the Guts on the Outside"  that nails how the microservices architectural pattern deals with system complexity. In his post, Gary describes how in a microservices-style application, each service is designed to be as simple as possible to maximize developer productivity. However, the complexity has to go somewhere, and with the microservices approach, this complexity is pushed outside of individual microservices into a common layer of services.

Gary calls the (simpler) implementation of microservices the "inner architecture", and the layer where the complexity is pushed the "outer architecture." This classification gives us a nice model to work with to define Container Services.

Managing complexity

So if the complexity is pushed outside of the application, who deals with it? Obviously there needs to be some layer that handles the common services i.e. "the plumbing" required for microservices.

There are a two emerging trends in how this new layer of platform services is delivered:

  • Application frameworks: Microservices frameworks are being developed for every major language. Java has NetflixOSS, Spring Boot and Spring Cloud (which abstracts some of the NetflixOSS components). Go has Go-kit, Micro, etc. Typically these frameworks are delivered as a set of language-specific libraries and runtime services.

  • Container services: These are built on open container standards and are language or system agnostic.

Container services

In mid-2015, several vendors in the container space launched the OCI (Open Container Initiative) under the Linux foundation. The goal was to address separation of vendor orchestration stacks and constructs, as well as OS specific constructs, from container primitives.

Application containers are both an image packaging mechanism that describes what goes in an application component, and an application runtime which specifies how the application component is launched and executed. Not surprisingly, the OCI is working on two specifications: the OCI Runtime Spec, which deals with the application runtime, and the recently announced OCI Image Format Spec which covers the application definition and packaging.

The OCI standards now let us leverage the container as a standard unit of operations and management, and build common application services around the container.

Container Services build on open container standards and provide common services outside of the container

containerservices 1

Some examples of Container Services are:

  • Container lifecycle management

  • Container scheduling and placement

  • Logging

  • Monitoring

  • Auto-recovery

  • Auto-scaling

  • Registration and discovery

  • Load balancing

  • Request routing

  • Networking

  • Storage and data management

  • Application security

Not all of these are directly related to Microservices. Others like service discovery and version-aware request routing are necessary for building microservices-style applications. In fact in the journey to cloud-native a best practice is to decouple the application from the underlying infrastructure, and even traditional applications that are deployed in containers can greatly benefit from these services.

How to choose?

So, circling back to Gary's point on pushing complexity outside of the microservice -- we now have a couple of approaches to consider:

  1. The traditional approach of application frameworks, with language specific libraries and runtime components.

  2. Container Services that build on open container initiatives.

While there is no right or wrong approach, it is important to understand the tradeoffs between the two approaches. Also, container orchestration and management tools, as well as application frameworks, will provide varying degrees of support for platform services. In fact, in many cases you may end up with a mix of application frameworks and container services to cover everything that is needed to deploy and operate microservices-style applications in production.

Here is a quick comparison of the two approaches:

containerservices 3

Application Frameworks

Container Services

Compile-time coupling with the application

Run-time coupling with the application

Language specific libraries

Language agnostic

Can be easier for developers to try via APIs

Requires a container runtime

Executes in the application (at least partially)

Executes outside of the application

Can be highly optimized for specific use cases (e.g. NetflixOSS)

Broader usage - less scope for optimization of certain use cases.

Fewer architectural layers

More architectural layers

Harder to enable polygot microservices (once a mass of libraries are built for a language)

Easier to enable polygot microservices

Changes to the "outer layer" will likely requires changes in the application

Changes to the "outer layer" do not require application changes.

Upgrades to the "outer layer" will likely requires an application upgrade.

Upgrades to the "outer layer" do not require an application upgrade.

Summary 

While it is possible to design microservices applications that have compile-time integrations with platform tools and run directly on host instances, using containers provide several benefits. In addition to the agility and runtime portability, containers also make it possible to leveraging a standard layer of  platform services that cleanly address several challenges in building, deploying, and operating for cloud-native applications.

What's even better, is that a number of these Container Services are themselves deployed and orchestrated as a set of system containers, allowing for additional ease of management and true multi-cloud application delivery and management.

Adding dependencies to an application should be done with care. In a few cases, it makes sense to compile-in common services and manage dependencies, versioning and upgrades. However in general my recommendation would be to push as much as possible to the "outer" architectural layer -- outside your application and outside of the application container!

Copyright © 2016 IDG Communications, Inc.