In the first software architecture article, Why Software Architecture Matters in Networking – Part 1: Containers, we talked about containers and the many joys for developers, QA, and customers when we package software into standardized units. In this article, let’s look at how containers and microservices work together and make 1 + 1 = 3.
A microservices architecture is a software design technique in which an application is broken down into small operating pieces with well-defined boundaries of functionality. The individual pieces (i.e. services) are integrated together via API interfaces in a loosely coupled environment.
I think of microservices a little bit like a car. The car is the application. But the car (“application”) is made up of component parts (“services”) that provide some function. Each part is optimized for its own specific function, each part has a well-defined interface to the rest of the car, and in most cases you can modify, upgrade, or replace parts in a modular fashion without messing with the rest of the car. Change headlights without thinking about exhaust; upgrade tires without mucking with the engine; enhance the audio while paying no mind to the alternator. One unified application. Many loosely coupled parts.
In software, a microservices design does the same, with tremendous benefits. By decoupling services into small manageable parts (by the way, those parts are usually containers), each service can be designed with a software stack that is ideal for its function. As application requirements change over time, the necessary services can be modified as needed in a modular fashion. Authentication frameworks can be modified without breaking control plane functionality. Reports can be added without modifying events code. License enhancements can be added while leaving compute engines alone.
It all seems pretty logical, so you might be wondering to yourself why it hasn’t always been this way. One answer is that most traditional networking applications were built for on-premises fixed-footprint servers. So they’re monolithic by design and bounded by scale constraints by necessity. They’re built as a single-tier program, which we call monolithic apps. Multiple unrelated features were built into the program with tight coupling, often reusing underlying layers of code and databases for footprint efficiencies. Management and control plane, admin RBAC and security, events and logging, reports and UI all become wed together in one complex piece of code. Over time, it becomes spaghetti, and every new addition or modification becomes increasingly complex to write and error-prone to test.
Below is a visual that might help. On the surface, a monolithic app can have roughly similar feature lists as a microservices-based application, but the SW architecture makes it difficult to maintain over time. And, it becomes impossible to scale features independently. Microservices, on the other hand, are segmented out into their own contained functional blocks with well-defined interfaces. Then services have linkage within the app to other services where necessary. And just as importantly, they DO NOT interface where it is not necessary.
Microservices have emerged as the de facto software architecture for cloud-based applications that are dynamic and complex, with many functions and moving parts—like scalable networking systems. But, the networking industry by and large hasn’t leveraged its many benefits, which we are enjoying in the Extreme IQ platform.
Microservices with Containers
Before we jump to the benefits, let’s make sense of microservices with containers. From the last article, we talked about how containers are a way to package together some code with all of its dependencies. Then microservices are a software architecture by which a complex application is delivered by means of many loosely coupled services working together. So you can probably see how the intersect. A microservices architecture is often comprised of many containers to deliver services. A given “service” could be a single container, a collection of containers, a distributed cluster of containers, or similar.
To control the dynamic deployment, operation, and scaling of containers, microservices often rely on an orchestration layer. Kubernetes is the best-known open-source system for container orchestration, but other cloud options and hosted Kubernetes services also exist. This layer provides the automation and easy operation that cloud providers and customers both want from the solution.
Combining microservices with containers and an orchestration layer, we end up with the following benefits.
By decoupling services into containers, we gain a massive benefit in scalability. That doesn’t just mean “we can support huge deployments,” it means we can dynamically adjust the application to right-size services based on the unique deployment of the customer, its data, and network changes over time. This is managed by the orchestration layer, but made possible by the service composition. For example, if control plane functionality (e.g. terminating AP/switch connections, decrypting tunnels, and packaging data into a queue/bus) is delivered as a dedicated service within the application, we can scale up and down the control plane functionality based on the number of unique nodes needing control services. Meanwhile, if the API (or any other unrelated service) is very lightly loaded, we can keep a lower-resource API service, which scales up if we see demand grow. All of this can be managed automatically with monitoring as part of an orchestration flow.
Microservices also provide an innate level of reliability because each service is maintained independently. Let’s pick on the API service for a moment. Let’s say there’s some problem with that service and it needs to restart for some reason, we can restart the API container/service individually without affecting the other services (authentication, admin login, licensing, control plane, reports, etc). Compare that to a heavily integrated monolithic hardware or VM appliance and it likely doesn’t work that way. You might (too often, perhaps) have to reboot the entire platform to fix one service.
Again, the microservices architecture often leverages containers, which means the service software is very modular. Each service can use a software stack that’s specific and optimized for the requirements of that unique service. If that software stack is different from the rest of the services in the application, fine. If it’s not, fine too. If it needs to change, then you don’t need to upend the entire application and rewrite a bunch of features in order to upgrade or replace a software component.
Honestly, when a customer asks for new functionality, there’s always a business equation that plays out. How much time will it take for engineering to enhance, and how much value does it bring. In monoliths, the “time to change” equation is commonly lopsided by this tight coupling problem. In microservices, the modularity benefit often (but not always, of course) plays to customer favor.
We talk about APIs often from a management automation perspective. As in, use APIs to build automations into your management flow. But, in this case, we’re talking about the internal workings of an application. Services rely on APIs to integrate together. Conveniently, microservices allow each service’s API to be well-defined and specific to its function. This creates integration within the application only where necessary, and avoids the spaghetti effect.
Bringing It Together
Back to the original problem statement at the beginning of the first article, suboptimal architectures lead to development and QA nightmares. Over time, it becomes very difficult for developers to efficiently build new features, and more difficult for QA to test all the unique combinations of features, scale, and possible deployment environments.
And of course it doesn’t mean that microservices and containers make everything perfect. Nor are monolithic and non-containerized software options doomed to fail. But, these modern software design principles are used across all industries in software-focused companies for a very good reason. Companies that embrace them are seeing success for the same reasons. The benefits are meaningful, and they will prove to be significant over time.
For more reading and resources about microservices, try these:
For more information about Extreme’s intelligent and modern public, private, and local cloud options, here’s a link to our wares: https://www.extremenetworks.com/products/.