Container Services: Hello From the Outside!
If you're building a complex application, then using a lot of microservices doesn't automatically make it simple. The complexity goes into the outer architecture. So how do we manage the complexity in the context of containers?
Join the DZone community and get the full member experience.Join For Free
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?
Inner vs. Outer Services
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 Application 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.
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 application services outside of the container.
Some examples of where Container Services can help are:
- Container lifecycle management.
- Container scheduling and placement.
- Registration and discovery.
- Load balancing.
- Request routing.
- 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.
Choosing an Approach
So, circling back to Gary's point on pushing complexity outside of the microservice — we now have a couple of approaches to consider:
- The traditional approach of application frameworks, with language specific libraries and runtime components.
- 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.
While it is possible to design microservices applications that have compile-time integrations with platform frameworks and services, 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.Container Services help you reduce the application code you need to maintain and upgrade. 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!
Published at DZone with permission of Jim Bugwadia, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.