A Brief overview of the Sidecar Container Pattern

Working, advantages & disadvantages of the sidecar container

Animesh Gaitonde
Geek Culture
7 min readOct 25, 2022

--

Photo by Drew Beamer on Unsplash

Introduction

In the past decade, tech companies have widely adopted microservices architecture. The adoption has dramatically improved the availability and reliability of the services. Containerization has further speeded up the development process and reduced the operational burden on developers.

It’s a challenging task to build distributed systems. Developers have identified a standard set of problems that repeat while building these systems. This led to the emergence of reusable and modular architectural patterns. These patterns are similar to the design patterns in object-oriented programming.

Architectural patterns help us to avoid reinventing the wheel during the development process. The practices act as abstractions and can be reused by any service.

In this article, we will understand one of the architectural patterns known as the Sidecar. We will understand the problem that this pattern tries to solve. Later, we will explore the working and the tradeoffs of this pattern.

Problem

In one of my previous companies, the architecture constituted a set of legacy services that used HTTPfor communication. The company witnessed a security incident & the company issued a mandate to adopt HTTPS.

At first glance, we felt that the problem was straightforward. A simple solution was to implement a module to perform the SSL handshake and then integrate it into the service. So, we started with our initial analysis before giving timelines to the relevant stakeholders.

We found out during the analysis that the problem wasn’t that simple. Here are the reasons that added to the problem’s complexity:-

  1. Legacy infra — The code was built using an old legacy infra. The legacy services were built two years back with no recent commits.
  2. Testing — Since a new module was being introduced, we would have to exhaustively test the service. The project also lacked sufficient test coverage.
  3. Programming Languages — There was one service implemented in C++ and the other in Ruby. So, we would have to implement the same module in two different languages.

We concluded that the time to ship the feature in all the legacy services would be more than a month. We wanted to release the feature fast and not get into the complexities of dealing with legacy services.

So, the developers and the architects decided to have a call to brainstorm possible solutions. While explored different possibilities, an architect came up with an elegant & simple solution to the problem.

Solution

The solution was to leverage existing nginx reverse proxy for the SSL handshake. The nginx would be deployed as a container and it would intercept all the https requests. The nginx container would run on the same machine as the web server.

The web server would listen to requests only from the local host. This would ensure that no other machine could send requests to this web server other than nginx. The below diagram illustrates the setup :-

NGINX handling SSL termination

The NGINX would terminate the SSL traffic. Further, it would send the unencrypted traffic to the legacy application.

With the above approach, we no longer have to modify the legacy application. So, it would save a lot of development efforts for us.

Sidecar container

The solution described in the previous section is one use case of the Sidecar container. The Sidecar container extends the functionality of an existing(main) container, without the existing container knowing about it.

The Sidecar container runs on the same machine as the main container. Hence, the pattern is also known as single node pattern. The pod constitutes main container & the Sidecar container. The main container handles actual business logic. The Sidecar performs peripheral tasks without impacting the performance of the main container.

Sidecar container pattern

The Sidecar shares most of the resources such as volume, network, CPU, memory etc with the main container. This makes the pattern capable of solving a wide array of common problems such as logging, monitoring, security, etc.

Analogy

A motorcycle’s sidecar is attached to the side of the vehicle. The sidecar only has a wheel and it adds an extra seat to carry passenger or goods. The sidecar doesn’t carry an engine and it goes wherever the primary vehicle goes.

You can think of the primary container as the main vehicle. The primary container has the business logic (engine) and takes appropriate decisions (controls speed, & direction).

Analogy with vehicle sidecar

The Sidecar container just adds an extra feature like SSL termination or reading the main container’s logs (similar to adding a seat for passenger or goods). On its own, the sidecar is not useful.

Common use cases of Sidecar container

Logging

Logging plays a pivotal role in debugging and troubleshooting issues in cloud native applications. Most of the distributed applications have a separate logging pipeline. The pipeline is responsible for collecting the logs, processing it and storing it in a data source. This is achieved with the help of message queues or directly uploading the logs to blob storage (S3).

Let’s consider an Order Management System(OMS) in e-commerce. If we want to collect the logs of this service, we can run a Logging Agent as a sidecar. The OMS will log the data to the file system. The Logging Agent will read the data from the file system periodically and upload the data to the blob storage. Below diagram explains the working of the Logging Agent.

Logging Agent as a sidecar container

The OMS business logic is a critical task as compared to logging. It’s fine if we don’t receive the logs for a few minutes. But we can’t tolerate customers unable to shop on the website. Hence, logging functionality can be offloaded to Sidecar container.

The Sidecar container only knows how to read the log file and manages the data upload. The logging functionality was been decoupled from the main container.

Configuration Management

Many services use a configuration file to read the properties. At times, we need to change certain properties such as connectionPoolSize or databaseUrl. A simple technique to do this is to login into the server change the properties and restart the service.

The above task becomes time consuming with large number of servers. Hence, there is a centralized configuration system which exposes APIs to add/modify the properties. Further, to automate the restart of the services, a sidecard can be added.

Sidecar for configuration management

The job of this sidecar is to sync the properties from the centralized service and compare it with the existing properties. In case of any difference, it stops the service and launches it. The service then reads the updated properties and restarts.

In the above case, we don’t have to implement the logic to sync config in the main container. Moreover, we can use the Configuration Manager Sidecar in other microservices as well.

Other use cases

The Sidecar container pattern can be used for other use cases such as authentication, continuous deployment, monitoring etc. The peripheral logic can be encapsulated in the Sidecar as an independent module.

Advantages

  • Reusability — Sidecars can be implemented once and reused anywhere. The primary container can be written in any language of choice. We don’t have to rewrite the sidecar logic every time we develop a new application
  • Decoupling — Sidecar achieves a separation of concerns. The primary container only needs to focus on business logic. Sidecar and the primary container can be deployed independently. The primary container wouldn’t become a single point of failure.
  • Modularity — The peripherial functionality can be developed into a independent sidecar module. This module does only one thing and it does it well. It’s similar to writing a reusable library like Gson and using it everywhere.

Disadvantages

  • Latency — Sidecar containers reside on the main container’s machine. So, latency isn’t impacted much. However, if latency is of primary concern and the jitters can’t be tolerated, then Sidecar shouldn’t be used. For eg:- It doesn’t make sense to use Sidecar in a low-latency application like High-frequency trading.
  • Cost — If the application is light weight and simple, then sidecar could be an overkill. There is an additional cost associated with a sidecar. The advantages of using a sidecar should outweigh the cost. In such cases, its better to use library for additional functionality.

Conclusion

In this article, we understood the working of Sidecar container pattern. The pattern is also known as decomposition pattern.

It’s commonly used to abstract common functionality such as logging, monitoring, SSL termination, etc. The sidecar implements the above functionality and is often used when services are written in multiple languages and frameworks.

Reusability, Modularity and Decoupling are the primary advantages offered by the pattern. It avoid code repetition and promotes code reuse. The pattern can’t be applied to simple light weight services.

References

  1. Handling cross cutting corners in Microservices
  2. Images
  3. Azure architecture centre — Sidecar pattern
  4. Designing Distributed Systems — Sidecar pattern

--

--

Animesh Gaitonde
Geek Culture

SDE-3/Tech Lead @ Amazon| ex-Airbnb | ex-Microsoft. Writes about Distributed Systems, Programming Languages & Tech Interviews