Kubernetes – Sidecar Container Pattern

We know that a pod is a basic building of a kubernetes application. Kubernetes manages pods instead of containers and pods encapsulate containers. A pod may contain one or more containers, storage, IP addresses, and, options that govern how containers should run inside the pod.

A pod that contains one container refers to a single container pod and it is the most common kubernetes use case. A pod that contains Multiple co-related containers refers to a multi-container pod.

Sidecar container pattern is one of the patterns to manage the multi-container pod. In this post, we will see this pattern in detail with an example project.

Sidecar pattern name is inspired by the sidecar attached to a motorcycle as below

Before going into further details of sidecar container pattern. It would like to discuss few of functionalities of sidecar in the above image. Sidecar is attached to the parent application and provide supporting features to the main bike. Sidecar will go wherever the main bike will go sidecar has the same lifecycle as the main bike.

Sidecar containers are the containers that should run along with the main container in the pod. This sidecar pattern extends and enhances the functionality of current containers without changing it.

Nowadays, We know that we use container technology to wrap all the dependencies for the application to run anywhere. A container does only one thing and does that thing very well.

Sidecar pattern also works on Single Responsibility Principle i.e a container should do one work and should do it well.

Problem context : Why do we need sidecar container ?

Application and services often require related functionality, such as monitoring, logging, configuration, and networking services. If we implement such functionalities in the same application we might face below problems:

  1. Both the application would be tightly integrated and would be using the same resources which means outage in side car application can make the entire application down.
  2. There is no separation of concerns result in ambiguity and make it difficult to understand as the application grows.
  3. Even the side application needs to be written in the same language as the parent application.

Keeping above problems in mind if we decompose our main application into multiple services or container then it becomes easy to manage the complexity and flexibility of the application, that is the reason sidecar pattern came into picture in Kuberenetes.

Advantages of using a sidecar pattern:

  1. A sidecar is independent from its primary application in terms of runtime environment and programming language, so you don’t need to develop one sidecar per language.
  2. The sidecar can access the same resources as the primary application. For example, a sidecar can monitor system resources used by both the sidecar and the primary application.
  3. Because of its proximity to the primary application, there’s no significant latency when communicating between them.
  4. Even for applications that don’t provide an extensibility mechanism, you can use a sidecar to extend functionality by attaching it as its own process in the same host or sub-container as the primary application.

Few Scenarios where we can use the Sidecar Pattern :

Scenario 1 :

Let say you have a very old legacy which only support HTTP request and now since it has become more popular, there is a need to provide for the HTTPS. So instead of making the change in the same file we can create side car HTTPS container such that all the request will route from this container to the legacy service container.

Scenario 2 :

In the cloud native applications, most of the time we need dynamic configurations for our microservices, microservice fetches the configuration from the filesystem. We can create the configuration manager as side car container which will fetch the file from some cloud config service and put the configuration file in filesystem on the same pod and the main application container will pick the file from the shared file system.

Example Application implementing SideCar Pattern :

Let’s implement a simple project to understand this pattern. Here is a simple pod that has main and sidecar containers. The main container is nginx serving on the port 80 that takes the index.html from the volume mount workdir location. The Sidecar container with the image debian creates logs in the same location with a timestamp. Since the Sidecar container and main container runs parallel Nginx will display the new log information every time you hit in the browser.

Note : I am using minikube on my local system to execute this mini project.

sidecar.yaml

apiVersion: v1
kind: Pod
metadata:
  name: sidecar-container-demo
spec:
  containers:
  - image: debian
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo echo $(date) >> /var/log/index.html; sleep 5;done"]
    name: sidecar-container
    resources: {}
    volumeMounts:
    - name: html-logs
      mountPath: /var/log
  - image: nginx
    name: main-container
    resources: {}
    ports:
      - containerPort: 80
    volumeMounts:
    - name: html-logs
      mountPath: /usr/share/nginx/html
  dnsPolicy: Default
  volumes:
  - name: html-logs
    emptyDir: {}

Execute the below command to create the pod from above yaml file.

kubectl create -f sidecar.yaml 

Now verify that the pod has been created using the below command :

kubectl get pod

Once our pod will be created, we will go inside the main-container in sidecar-conatiner-demo pod and will try to excess the localhost via curl command.

To go inside the main-container we will execute the below command :

kubectl exec -it sidecar-container-demo -c main-container -- /bin/sh

Now execute the curl command :

curl localhost

Once you execute the above commands, you will find the below logs generated and printed on the console.

You can download the source code from here :

https://github.com/Ishant14/Kubernetes-blog-example-code

When to Use this Pattern

Use this pattern when:

  • You want to extend the functionality of the existing single container pod without touching the existing one.
  • Your primary application uses a heterogeneous set of languages and frameworks. A component located in a sidecar service can be consumed by applications written in different languages using different frameworks.
  • You need a service that shares the overall lifecycle of your main application, but can be independently updated.
  • You need fine-grained control over resource limits for a particular resource or component. For example, you may want to restrict the amount of memory a specific component uses. You can deploy the component as a sidecar and manage memory usage independently of the main application.

Conclusion

It’s always to good to know already proven kubernetes patterns. Make sure all your sidecar containers are simple and small enough because you have to sum up all the resources/request limits while defining resource limits for the pod. You need to make sure Sidecar containers are also healthy by configuring health checks. So it’s important to know when to combine your functionality into the main container or have a separate container.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s