DevOps, Containers, Docker, Mesos, Kubernetes, microservices, 12-factor applications, 3rd platform, oh my! Modern application architecture and lifecycle is changing fast and that means even more demands on IT. While some have argued that this new application approach calls for a whole new infrastructure, actually these new business-driven demands head on, leveraging your existing investment while still delivering the highest SLAs – performance, availability, security, compliance, and disaster recovery. This emerging 3rd Platform Application stack not only fits into existing SDDC infrastructure investments but is actually the best place to run containers and emerging 3rd platform applications.
Application Development and Delivery
If we look at the Outcomes Delivered from a new model of IT, Businesses are increasing their focus on App and Infrastructure Delivery Automation throughout the datacenter.
3RD PLATFORM – MICROSERVICES
3rd Platform! Microservices! What the heck are they? Put simply, the 3rd platform is this is a new paradigm for architecting applications to operate in a distributed fashion. While the 1st platform was designed around mainframes and the 2nd platform was designed around client-server, the 3rd platform is designed around the cloud. In other words, applications are designed and built to live in the cloud. We can effectively think of this as pushing many of the core infrastructure concepts (like availability and scale) into the architecture of the application itself with containers being a large part of this; they can be thought of as lightweight runtimes for these applications. With proper application architecture and a rock solid foundation either on-premise or in the cloud, applications can scale on demand, new versions can be pushed quickly, components can be rebuilt and replaced easily, as well as many other benefits discussed below.
History of Platforms
1st Platform systems were based around mainframes and traditional servers without virtualization. Consolidation was a serious issue and it was normal to run one application per physical server.
2nd Platform architectures have been the standard mode for quite a while. This is the traditional Client/Server/Database model with which you are likely very familiar, leveraging the virtualization of x86 hardware to increase consolidation ratios, add high availability and extremely flexible and powerful management of workloads.
3rd Platform moves up the stack, standardizing on Linux Operating Systems primarily, which allows developers to focus on the application exclusively. Portability, scalability and highly dynamic environments are valued highly in this space. We will focus on this for the rest of the module.
Does this mean you should immediately move all of your applications to this model? Not so fast! While 3rd Platform architectures are exciting and extremely useful, they will not be the answer for everyone. A thorough understanding of the benefits and, more importantly the complexities in this new world are extraordinarily important. VMware’s Cloud-Native Apps group is dedicated to ensuring our customers are well informed in this space and can adopt this technology confidently and securely when the time is right.
Microservices are growing in popularity, due in no small part to companies like Netflix and Paypal that have embraced this relatively new model. When we consider microservices, we need to understand both the benefits and the limitations inherent in the model, as well as ensure we fully understand the business drivers.
At its heart, microservice architecture is about doing one thing and doing it well. Each microservice has one job. This is clearly in stark contrast to the monolithic applications many of us are used to; using microservices, we can update components of the application quickly without forcing a full recompile of the entire application. But it is not a “free ride” – this model poses new challenges to application developers and operations teams as many assumptions no longer hold true.
The recent rise of containerization has directly contributed to the uptake of microservices, as it is now very easy to quickly spin up a new, lightweight run-time environments for the application.
The ability to provide single-purpose components with clean APIs between them is an essential design requirement for microservices architecture. At their core, microservices have two main characteristics; they are stateless and distributed. To achieve this, let’s take a closer look at the Twelve-Factor App methodology in more detail to help explain microservices architecture as a whole.
THE TWELVE FACTOR APP
To allow the developer maximum flexibility in their choice of programming languages and back-end services, Software-as-a-Service web applications should be designed with the following characteristics:
- Use of a declarative format to attempt to minimize or eliminate side effects by describing what the program should accomplish, rather than describing how to go about it. At a high level it’s the variance between a section of code and a configuration file.
- Clean Contract with the underlying Operating Systems which enables portability to run and execute on any infrastructure. API’s are commonly used to achieve this functionality.
- Ability to be deployed into modern cloud platforms; removing the dependencies on underlying hardware and platform.
- Keep development, staging, and production as similar as possible. Minimize the deviation between the two environments for continuous development.
- Ability to scale up (and down) as the application requires without needing to change the tool sets, architecture or development practices.
At a high level, the 12 Factors that are used to achieve these characteristics are:
- Codebase – One codebase tracked in revision control, many deploys
- Dependencies – Explicitly declare and isolate dependencies
- Config – Store config in the environment
- Backing Services – Treat backing services as attached resources
- Build, release, run – Strictly separate build and run stages
- Process – Execute the app as one or more stateless processes
- Port Binding – Export services via port binding
- Concurrency – Scale out via the process model
- Disposability – Maximize robustness with fast startup and graceful shutdown
- Dev/Pro Parity – Keep development, staging, and production as similar as possible
- Logs – Treat logs as event streams
- Admin Process – Run admin/management tasks as one-off processes
For additional detailed information on these factors, check out 12factor.net.
BENEFIT OF MICROSERVICES
Microservice architecture has benefits and challenges. If the development and operating models in the company do not change, or only partially change, things could get muddled very quickly. Decomposing an existing app into hundreds of independent services requires some choreography and a well thought-out plan. So why are teams considering this move? Because there are considerable benefits!
With a properly architected microservice-based application, the individual services will function similarly to a bulkhead in a ship. Individual components can fail, but this does not mean the ship will sink. The following tenet is held closely by many development teams – “Fail fast, fail often.” The quicker a team is able to identify a malfunctioning module, the faster they can repair it and return to full operation.
Consider an online music player application – as a user, I might only care about playing artists in my library. The loss of the search functionality may not bother me at all. In the event that the Search service goes down, it would be nice if the rest of the application stays functional. The dev team is then able to fix the misbehaving feature independently of the rest of the application.
Defining “Service Boundaries” is important when architecting a microservice-based application!
If a particular service is causing latency in your application, it’s trivial to scale up instances of that specific service if the application is designed to take full advantage of microservices. This is a huge improvement over monolithic applications.
Similar to the Resilience topic, with a monolithic application, one poorly-performing component can slow down the entire application. With microservices, it is almost trivial to scale up the service that is causing the latency. Once again, this scalability must be built into the application’s DNA to function properly.
Once again, microservices allow components to be upgraded and even changed out for entirely new, heterogeneous pieces of technology without bringing down the entire application. Netflix pushes updates constantly to production code in exactly this manner.
Misbehaving code can be isolated and rolled back immediately. Upgrades can be pushed out, tested, and either rolled back or pushed out further if they have been successful.
“Organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations” –Melvin Conway
The underlying premise here is that the application should align to the business drivers, not to the fragmentation of the teams. Microservices allow for the creation of right-sized, more flexible teams that can more easily align to the business drivers behind the application. Hence, ideas like the “two pizza rule” in which teams should be limited to the number of people that can finish two pizzas in a sitting (conventional wisdom says this is eight or less…though my personal research has proved two pizzas do not feed more than four people.)
No Silver Bullet!
Microservices can be accompanied by additional operations overhead compared to the monolithic application provisioned to a application server cluster. When each service is separately built out, they could each potentially require clustering for fail over and high availability. When you add in load balancing, logging and messaging layers between these services, the real-estate starts to become sizable even in comparison to a large off the shelf application. Microservices also require a considerable amount of DevOps and Release Automation skills. The responsibility of ownership of the application does not end when the code is released into production, the Developer of the application essentially owns the application until it is retired. The natural evolution of the code and collaborative style in which it is developed can lend itself to challenges when making a major change to the components of the application. This can be partially solved with backwards compatibility but it is not the panacea that some in the industry may claim.
Microservices can only be utilized in certain use cases and even then, Microservices open up a world of new possibilities that come with new challenges and operational hurdles. How do we handle stateful services? What about orchestration? What is the best way to store data in this model? How do we guarantee a data persistence model? Precisely how do I scale an application properly? What about “simple” things like DNS and content management? Some of these questions do not have definitive solutions yet. A distributed system can also introduce a new level of complexity that may not have been such a large concern like network latency, fault tolerance, versioning, and unpredictable loads in the application. The operational cost of application developers needing to consider these potential issues in new scenarios can be high and should be expected throughout the development process.
When considering the adoption of a Microservices, ensure that the use case is sound, the team is aware of the potential challenges and above all, the benefits of this model outweigh the cost.
Recommended reading: If you would like to learn more about the operational and feasibility considerations of Microservices, look up Benjamin Wootton and read some of his publications on the topic, specifically ‘Microservices – Not A Free Lunch!’.