Containerless Microservices Architecture

The transition from monolithic software structures to microservices is often conflated with the adoption of containerization. However, a critical architectural realization is that microservices are a software architecture pattern, not a deployment technology. This pattern involves the decomposition of a monolithic application into smaller, independent services that can be developed, deployed, and scaled independently of one another. While containers have emerged as a popular vehicle for this delivery due to their portability and scalability, they are not the only viable option. In fact, the reliance on containers often introduces a secondary layer of operational complexity, requiring the mastery of orchestration tools, continuous server maintenance, and the implementation of strict networking rules.

The shift toward containerless microservices is primarily driven by the desire to eliminate the management burden associated with the underlying infrastructure. In a traditional container-based approach, engineering teams must still consider the environment in which the container runs, often leading to a situation where the operational overhead of managing the containers rivals the complexity of the original monolith. By utilizing serverless components and cloud functions, organizations can architect pure serverless systems that remove the need for traditional software containers entirely. This allows software engineering teams to build highly scalable distributed systems with zero underlying hardware maintenance, shifting the focus from infrastructure management to the development of core business logic.

The Monolithic Burden and the Microservices Pivot

Software applications typically originate as single, unified codebases. This monolithic structure is often efficient during the initial phases of development, but as the application grows, it becomes massive and increasingly difficult to maintain. One of the most significant risks associated with this structure is the high probability of catastrophic failure; a minor code change in one specific area of the codebase can inadvertently crash the entire system. To mitigate these risks and ensure stability, engineering teams often duplicate the application across multiple hardware servers.

However, this duplication introduces a massive operational burden. Managing a fleet of servers requires constant patching, configuration management, and scaling efforts that slow down the overall development velocity. Transitioning to a microservices architecture solves the codebase size problem by dividing the massive application into smaller, independent programs. When this transition is executed without containers, it removes the requirement for complex orchestration tools and the associated networking rules, effectively decoupling the service logic from the environment in which it executes.

Serverless Compute and the Ephemeral Paradigm

The foundational building block of containerless microservices is serverless computing. While the term serverless is slightly confusing for beginners—since physical servers still exist in remote data centers—the key distinction is that the cloud provider manages those physical servers completely. Developers no longer see the operating system, nor do they manually configure network load balancers. Instead of managing servers, developers upload raw programming code to the cloud provider, and the platform handles everything required to run that code securely.

Within this ecosystem, the primary engine is the cloud function. A cloud function is a highly specialized script designed to execute a single, focused task. Unlike traditional services, these functions do not run continuously in the background waiting for network traffic. Instead, they utilize ephemeral compute, meaning they are triggered by specific events and exist only for the duration of their execution.

AWS Lambda as a Implementation Model

AWS Lambda serves as a primary example of a serverless compute service that enables the implementation of microservices without containers. Lambda allows users to run code without provisioning or managing servers, creating workload-aware cluster scaling logic, maintaining event integrations, or managing runtimes.

The impact of using AWS Lambda for microservices is reflected in its scaling and cost efficiency:

  • Scaling capabilities: Lambda runs functions only when needed and scales automatically from a few requests per day to thousands per second.
  • Cost structure: Users pay only for the compute time they consume, meaning there is no charge when the code is not running.
  • Operational impact: This removes the need for the developer to maintain the runtime environment or manage the scaling of the cluster.

Implementation Strategies and Use Cases

Implementing microservices without containers requires a strategic approach to refactoring. A monolithic application is broken down into smaller services, where each service serves a single purpose. The decision to use a serverless function versus a container depends on the execution pattern of the service. If a service is not required to run constantly, it can be implemented as a Lambda function. If the service requires constant execution, a container may still be the appropriate choice.

Ideal Migration Scenarios

The migration to a containerless microservices architecture is particularly effective in the following scenarios:

  • Monolithic Decomposition: When an organization specifically wants to break a monolithic system into microservices to improve maintainability.
  • Resource Availability: When the organization has the necessary resources and time available for the refactoring process.
  • Dependency Resolution: When the team can resolve all .NET Framework dependencies to ensure compatibility with serverless runtimes.
  • Execution Patterns: When applications do not run constantly but instead run for very short periods of time.

Comparative Analysis of Migration Benefits and Drawbacks

The transition from on-premises .NET applications to a serverless microservices architecture provides several strategic advantages, though it is not without challenges.

Advantage Description Real-World Impact
Faster Innovation Easier to add new features in a microservices architecture Reduced time-to-market for new product capabilities
High Availability Built-in reliability through cloud provider infrastructure Reduced system downtime and improved user experience
On-Demand Scalability Increased agility through automatic scaling Ability to handle traffic spikes without manual intervention
Independent Deployment Support for modern CI/CD pipelines Teams can deploy updates to single services without affecting the whole system
Technical Diversity Strong module boundaries Ability to use different programming languages for different services
Cost Savings Pay-per-execution model Reduced overhead compared to maintaining always-on servers
Reduced Provisioning Elimination of infrastructure setup efforts Developers spend less time on Ops and more time on Feature work

Despite these advantages, certain disadvantages must be considered:

  • Refactoring Costs: There is a significant effort and financial cost associated with the initial refactoring of a monolith.
  • Operational Complexity: While server management is removed, the overall operational complexity of managing many distributed functions can increase.
  • Runtime Limitations: There is no support for long-running applications in an ephemeral function model.

Tooling for Container-Like Workflows without Docker

While the goal may be to avoid the Docker CLI, the industry still relies on OCI (Open Container Initiative) format images for many workloads. This has led to the development of tools that can build images from a Dockerfile without requiring the Docker engine itself.

OpenFaaS and CaaS Integration

OpenFaaS serves as a case study for this approach. It functions as a CaaS (Container as a Service) platform for Kubernetes that can run microservices while adding FaaS (Function as a Service) and event-driven tooling. OpenFaaS uses OCI-format container images but allows for builds that bypass the standard Docker CLI.

Alternatives to the Docker CLI

Several tools have emerged to strip Docker back to its component pieces, focusing on the build, ship, and run cycle without the baggage of Docker Swarm or Enterprise Edition features.

  • Buildkit: Used by Docker itself to perform highly efficient, caching builds. It can also be used as a stand-alone tool.
  • Podman and Buildah: A RedHat/IBM effort that utilizes an open-source toolchain to generate OCI images without relying on the Docker daemon.
  • Kaniko: A tool designed to build container images from a Dockerfile inside a container or Kubernetes cluster without needing a Docker daemon.

Practical Implementation Example: Golang Middleware

To illustrate the versatility of this approach, a Golang HTTP middleware can be created as a hybrid between a function and a microservice using the OpenFaaS CLI.

The process begins by pulling the required template:

faas-cli template store pull golang-middleware

Then, a new function is created using the following command:

faas-cli new --lang golang-middleware build-test --prefix=alexellis2

In this command:

  • --lang specifies the build template.
  • build-test defines the name of the function.
  • --prefix indicates the Docker Hub username used for pushing the OCI image.

This process results in a structured directory containing a handler.go file and a build-test.yml configuration file. The handler is easily modifiable, allowing the developer to define the specific business logic of the microservice without managing the underlying server infrastructure.

Architecture Components for Containerless Ecosystems

To build a fully functional microservices ecosystem without containers, several architectural components must be integrated to ensure the decoupled services can communicate and scale.

Cloud Functions

These are the execution units. They are ephemeral, event-driven, and focused. They eliminate the need for the developer to configure the runtime environment.

API Gateways

Since containerless microservices are often distributed and triggered by events, an API Gateway is required to act as the single entry point. This gateway handles request routing, authentication, and rate limiting, ensuring that external requests are directed to the correct cloud function.

Centralized Event Routers

In a decoupled backend, services often need to communicate without being tightly coupled. Centralized event routers allow one function to trigger another by emitting an event. This ensures that the failure of one service does not cause a cascading failure across the entire system, a common problem in monolithic architectures.

Analysis of the Architectural Shift

The transition toward microservices without containers represents a fundamental shift in how software is conceived and deployed. The traditional container model, while an improvement over the monolith, still treats the "unit of deployment" as a virtualized operating system environment. This requires the developer to remain cognizant of the OS, the libraries installed within the image, and the orchestration layer (such as Kubernetes) that manages the pods.

In contrast, the serverless, containerless approach treats the "unit of deployment" as the code itself. By abstracting the environment entirely, the industry is moving toward a model where the infrastructure is truly invisible. This allows for a higher degree of agility, as the overhead of creating a new service is reduced to writing a function and defining its trigger.

However, the total elimination of containers is not a universal solution. The "no support for long-running applications" limitation is a critical boundary. Applications that require constant state, long-lived TCP connections, or heavy background processing are ill-suited for the ephemeral nature of cloud functions. Therefore, the most effective modern architectures are often hybrid, utilizing serverless functions for event-driven tasks and containers for persistent, high-load services.

The true value of mastering containerless microservices lies in the ability to choose the right tool for the specific workload. By reducing the reliance on the Docker CLI and embracing OCI-compliant builders like Buildah or Kaniko, and leveraging the compute efficiency of AWS Lambda and OpenFaaS, organizations can achieve a level of scalability and cost-efficiency that was previously impossible. The result is a system that is not only easier to maintain but is also fundamentally more resilient to the failures that plague monolithic architectures.

Sources

  1. DesignGurus Substack
  2. Alex Ellis Blog
  3. LinkedIn - Gyanamaya Mangaraj
  4. AWS Prescriptive Guidance

Related Posts