This article was originally posted on the Kelda.io blog by CEO and Founder, Ethan J. Jackson. Kelda is Docker compose for Kubernetes. It allows you to quickly test your code changes in a remote environment that matches production, without the complexity of interacting with Kubernetes directly.
I recently had the pleasure of speaking about Kelda at ESCAPE/19 - the multi-cloud conference, in New York City. It was a fantastic event packed full of sharp folks with interesting perspectives. The talk, How Microservices Enable Multi-Cloud at the Expense of Developers, describes how microservices and CI/CD led to the development of Kubernetes which itself promises to make multi-cloud viable for the first time. However, these advantages are not without costs, particularly for developer productivity. The talk is summarized below.
While cloud providers typically aren’t explicit about this, multi-cloud isn’t in their interest. The more challenging a cloud provider makes it for customers to switch to one of their competitors, the less difficulty they will have retaining and growing those customers, and the more power they will have in pricing negotiations.
Cloud providers historically have encouraged vendor lock-in by diverging their APIs. Everything from trivial differences in the semantics of the commands required to create a VM, to major differences in features and functionality all serve to make it difficult for users to shift cloud providers once they’ve made their initial choice. And while there have been efforts with varying success to standardize the cloud API, true portability has never been achieved.
Finally, seemingly out of nowhere, two massive trends collided:
As a result, we now deploy more things to production more frequently, and while not necessarily evident at the time, this placed massive pressure on deployment artifacts and processes to standardize. A broken, non-standard, deployment process on a monolith application is an annoyance. On a microservice application with 30 parts changing five times a day, it’s a disaster.
As an almost inevitable result, containers emerged to standardize the packaging and life cycle of individual microservices. And then, soon after (and with a little help from Google), Kubernetes emerged to standardize the orchestration of containers. While this wasn’t the original motivating intention of these trends, for the first time since the beginning of the cloud, all cloud providers support a single completely standard, completely portable interface for booting and maintaining software – the Kubernetes API. Having a standard API finally makes it possible to move applications from one cloud to another without significant engineering effort, removing what I believe is one of the last hurdles to the realization of multi-cloud.
Despite its numerous advantages, this new status quo introduces significant complexity to the developer experience. There are many more moving parts, operating on a complex substrate, that developers have to understand to do basic testing. For those interested in DevOps, this may not seem like a heavy lift, but for those of us who specialize in other areas, these issues can add up into a real productivity drag.
At its core, the issue comes down to how dependencies are handled. With a monolith, dependencies are simply software libraries that are compiled into the binary, or linked in at runtime. Individual microservices, of course, also depend on software libraries, but in addition, they depend on other microservices. This vastly complicates the local testing process for numerous reasons:
The good news is the problem is solvable. We’ve found that large teams who have been working with microservices for a long time tend to build a custom tool based on three core principles:
At Kelda, we’re building a development environment with exactly these properties. With a proper developer experience, organizations can get all of the benefits that microservices promise, without the drag on developer productivity.