The decision to move from a monolithic software architecture to cloud-native microservices can be triggered by many needs — the need to quicken application development, optimize infrastructure costs, deal with technical debt, or all of these and more.
It’s clear that microservices are being proven in more and more scenarios to be superior to monoliths. Every month, there’s news about startups being funded in their efforts to help organizations transition from monolith to cloud-native.
Containers and the rise of Kubernetes
This mass migration is being made possible by the rise of open source tools — particularly Kubernetes. As a container orchestration tool, Kubernetes is built to run containers at scale. It brings a completely new approach to managing infrastructure, in a way that is distributed. The distributed underlying infrastructure is what enables applications to be architected in a distributed manner as well. Separation of concerns within the application stack is a challenge given the complexities of the cloud, and multiple clusters that aren’t co-located.
In a cloud-native microservices application, there is a separate service for data storage and processing, application logic, networking, logging and monitoring, and more. The larger the application is, the more distributed it becomes when decomposed from monolith to cloud-native microservice.
At the recent KubeCon 2018, Seattle, there were clear signs of the ecosystem organizing itself around key needs organizations have as they run applications in distributed cloud environments. Whether it’s supporting SQL, or enabling a modern service mesh for network communication using tools like Istio, it’s all about helping organizations find solutions to the challenges they face, rather than adopting a flashy new IT trend.
Data management is the hardest part of developing enterprise applications. Wrangling data in the backend takes more time than designing a clean frontend UI. This is why organizations need to give thought to how they create and manage APIs, and how they store and transfer data across an application. While NoSQL may seem attractive, containers support SQL just as well, and this may be the right route to take when migrating from a monolithic system. The best part is that containers don’t dictate which of these database types you adopt, but rather support both, and make the migration less painful.
GitOps for speed
The original goal of DevOps was always to ship high-quality software faster. Today, organizations like Weaveworks are pioneering the GitOps approach to software delivery. According to this model, Git repositories are the focus. A tool like Jenkins X or Weave Flux “watches” a repository constantly, looking for updates to its code. When it notices an update, it initiates an automated deployment without the developer having to type in a single command. This is powerful when seen live in action, but it can also be scary if testing and authentication aren’t in place to prevent bad code from making it to production.
As developers contribute new code to a master repository, it is critical to run automated tests on the code, and if the tests pass, to deploy the code automatically to a target cluster. This type of “dry run” should be quick and deliver feedback immediately for it to be effective. Sauce Labs’ upcoming headless testing solution is in the similar vein of making it easy to run lightweight tests that provide almost live feedback on code as it is being written.
Every deployment needs to be authenticated to ensure the code is free from vulnerable container images, data is encrypted in transit and at rest, and the right access controls are established. In the push for faster and fully automated deployments, security should not be compromised.
Fail fast, fail forward
The most difficult part of a migration from monolith to cloud-native microservices is the change of attitude towards failure. In a monolithic system, failure is penalized, and avoided at all costs. However, in a microservices system, there is a different mindset towards failure. Failure is expected as part of the migration process, and even as part of daily operations after the migration is complete. Companies like Netflix have embraced the idea of “chaos engineering” to build resilience into the system. The “fail fast, fail forward” approach is championed at every level, and failures are taken into account.
Cloud-native microservices allow for failure at a granular level. It does this by providing adequate isolation between each service. When one service fails or is prone to a security attack, the impact of the incident is isolated to just that service.
This also brings deeper visibility into incidents. In a monolith, a single incident can take down the entire system, but in a microservice system, a single service can be identified as the cause for an error, and fixed.
There are many aspects to be considered when moving from monolith to cloud-native microservices. The benefits are appealing, but things can go wrong easily. However, by avoiding following trends for the sake of trends, and sticking to your key objectives, you can make the migration process seamless.