The Sidecar pattern enables the extension and enhancement - of an existing process or an application container - without affecting/modifying it and thus ensuring the single-responsibility of the existing process / container. The problem context, solution, considerations and use cases for this pattern are comprehensively documented here.
Exploring the usage and reviewing the implementation of this pattern, in a real-world project, is an effective way to gain a practical perspective as you start putting the pattern into practice. I have chosen two such open source projects that implement the sidecar pattern as part of their core architecture. The first one is - Dapr - Distributed Application Runtime and the other project we will look into is the Open Service Mesh .
Dapr is an event driven, portable runtime for building microservices on cloud and edge.
Dapr facilitates the development of microservices by providing independent building blocks like - State Management, Pub-Sub, Observability, Secrets and more - which are encapsulated as the Dapr API - in a platform-agnostic and language-agnostic manner. The independent nature of the building blocks lets you cherry-pick the set of features you want for your application and the platform-agnostic aspect gives you a wide spectrum of platforms to operate in ranging - from lean and resource-starved devices on the edge - to - power-packed , full fledged Azure Kubernetes Service clusters in the cloud. Sidecar implementation in Dapr architecture
The key advantage of using Dapr is that the application utilizing it need not include any Dapr runtime code. This advantage is achieved by utilizing the - sidecar pattern. The core Dapr API itself is exposed as a sidecar - either a sidecar process or a sidecar container. If it is a sidecar process - the service code calls the Dapr API via HTTP/gRPC. In the world of containers orchestrated by Kubernetes, the Dapr API is a side car container itself - which is utilized by the application container within the same pod.
Diagrams from the the Dapr project's documentation as follows -
Image 1 - Self hosted
Image 2 - Kubernetes hosted
So, the use case in - Dapr's case - is where a primary application uses a heterogeneous set of languages and frameworks and the component (Dapr API) located in a sidecar service /container can be consumed by applications written in different languages using different frameworks.
Open Service Mesh (OSM)
OSM is a lightweight and extensible cloud native service mesh that runs on Kubernetes. This was a project initiated by Microsoft that has been now donated to the Cloud Native Computing Foundation (CNCF) where it is a Sandbox project - at the time of this writing.
Sidecar implementation in OSM architecture
OSM onboards applications to the mesh by enabling the automatic sidecar injection of the Envoy proxy. A look at Image 3 below (source: OSM design doc) - shows the Envoy proxy already existing as sidecar container within the Kubernetes (k8s) pod.
Image 3 - OSM Components
Sidecar Container Injection
To elaborate on the sidecar injection part - OSM utilizes a feature of Kubernetes called MutatingAdmissionWebhook admission controller to intercept the k8s API server request after the pod creation is initiated but before the actual persistence/creation of the pod - to augment the request to include a Envoy proxy sidecar. This injection is done by the [Webhook+Injector] in the OSM Controller Pod. Refer Image 3 above. Now the created pod has the Envoy proxy sidecar automatically.
This means the powerful features of Envoy like - advanced load balancing, observability, rate limiting et.al. - are readily available to be utilized by each instance of the application and allowing the services in the mesh to communicate with each other. The separation of concerns between application's core functionality and Envoy's functionality + the ability of Envoy features to still be in proximity of the application is achieved via the sidecar pattern in the case of Open Service Mesh.
On a similar note - in Dapr's case - subsequent to installation of Dapr in a Kubernetes environment - it deploys a set of pods to the Default namespace.
Image 4 - Running Dapr on Kubernetes
A couple of such pods - relevant to the premise of this article - are tabulated below -
Watches for workload pods with Dapr annotations i.e. [dapr.io/enabled: true]
Augments, patches and injects the sidecar container to each annotated workload pod.
So, when you have your application workload's Kubernetes Deployment annotated with the requisite Dapr annotations - like [dapr.io/enabled: "true"] - the Dapr side car injector pod [dapr-sidecar-injector] as tabulated above - kicks in and injects the container. Now, every app container has a companion Dapr sidecar container within the same pod - realizing the desired intent.
I hope this has given you a bit more insight into the Sidecar pattern and has also piqued your interest in both the Dapr and Open Service Mesh projects!