To extend the functionality of the application container in the Kubernetes pod
A Sidecar pattern can separate an application’s functionalities into different processes. With the help of the sidecar design pattern, we may expand the functionality of the main application without modifying its codebase.
From a software point of view, a sidecar is attached to a core application and extends or enhances its functionality, much like a sidecar is linked to a motorcycle. The main application is loosely connected with a sidecar.
In this hands-on lab, we will be learning about different multi-container pod design patterns and learning in deep about side car pattern.
Multi Container Pod Design Patterns
As mentioned below, multiple containers can run inside a single pod for different use cases, which gave rise to multi-container pod design patterns.
Init Containers
Init containers reduce the burden of the main container by preparing the setup. Init containers start and terminate before the main application starts and should be run to completion without fail.
Multiple init containers run in a sequence and have to be completed before the application container starts. If any init container crashes, the kubelet resumes again and again until it succeeds. If the restart fulfils backoff time limit and init container fails to succeed then the entire pod is declared as failed.
Sidecar Containers
Application Container is the main container from which the application is served, and sidecar containers provide additional features to the main container. Sidecar containers run along with the main container and follow the lifecycle of the application container.
They share the resources like storage, network with the main container. It communicates with the main container via localhost
to reduce latency between them. If developers need to add extra features to the main app, they can create sidecar containers in the same pod.
For example, the main application writes a log file
and sidecar reads the log file continuously and process it further.
Adapter Containers
It adjusts the output in the desired format
. They standardize the output and interface for all multi-containers. If a custom container needs output in a particular format required to serve, the adapter container converts and shares with it.
For example, monitoring services like prometheus
check if the application is working as expected or not. Data coming from the endpoints must be in a format as prometheus required, for that the adapter container plays a key role in translating the output.
Ambassador Containers
It is a way to connect the containers with the outside world. It gives a proxy
to connect with external services.
For example, providing different database access for local, production or test environments to the main application, ambassador container works as a proxy
. Please refer to multi container patterns in detail here.
Benefits of Using Sidecar Containers
Durability: Main container and sidecar container can be written in different programming languages.
If the application is modified, there is no need to write sidecar logic again to get the same service as before.
Independency: If Application deployed in main container and its working fine. After some time the user needs to add an extra feature using a sidecar container and can deploy
sidecar independently
as they are loosely coupled.
Module structure: If developers need to add multiple features to the application container they have to create sidecar containers for each feature
. Each container works as a different module.
Protect against failure: It is possible to configure sidecar features in the main container, but in that case, if one service fails, it affects the performance of the main application. In sidecar patterns, both containers are independent so if sidecar fails, at least custom services can survive with limited features.
Drawbacks of Using Sidecar Containers
Latency due to loopback interface: Avoid using sidecar containers in applications that require prompt response. Both containers are in the same pod, so latency does not impact much, but applications that can’t afford latency, such as trading, games
or live streaming
should not use a sidecar pattern.
Difficult to debug: Inter process communication becomes complex
with multiple sidecar containers. It is difficult to manage and debug them independently as they follow the main container lifecycle.
Cost: Application and sidecar containers run on the same pod. Half pod can not run so with multiple copies of applications, it creates multiple copies of sidecar also which may lead to more resource consumption.
Reading Logs of Application through Sidecar
In this part, we’ll build up a multi-container pod with the principal application running in one container and the sidecar application running in the other. The sidecar container will continuously read the log file from a shared volume which will be generated by the main application container.
multi-container pod
andservice
are defined inaayu-verse.yaml
configuratin file stored in lab environment.
# aayu-verse.yaml apiVersion: v1 kind: Pod metadata: name: aayu-verse labels: app: webpage spec: containers: - name: main-cont image: pratikshahp/aayuverse volumeMounts: - name: volume mountPath: /var/log/nginx - name: sidecar-cont image: busybox command: ["sh","-c","i=1; while true; do echo $i': read log from main-container!!!'; i=$((i+1)); cat /var/log/nginx/access.log; sleep 10; done"] volumeMounts: - name: volume mountPath: /var/log/nginx volumes: - name: volume emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: svc-aayuverse spec: type: NodePort ports: - port: 80 targetPort: 80 nodePort: 31001 selector: app: webpage
- Create a pod and service using
aayu-verse.yaml
manifest
kubectl create -f aayu-verse.yaml
- To get the pods and services and its status
kubectl get all
Make sure that pods are in running state
and retrieve the port of the node
from service.
- To verify the result, is sidecar container able to read log file?
kubectl logs aayu-verse -c sidecar-cont
As of now we are getting the content only from the side-car container, as no logs have been generated from the main application.
But once we access the main application, our sidecar
container would be able to read them. Let’s see that in the next few steps.
- To get node ip
kubectl get nodes -o wide
- To access the webpage use node ip and nodeport from service
curl <node_ip>:<node_port>
On the terminal we get a webpage in html
format.
OR
- Click on
port-31001
URLs
- To verify logs again
kubectl logs aayu-verse -c sidecar-cont
Here we go!!! Logs are generated by main container and read by sidecar container
- To stop the execution
Press ctrl+c
Other Use-cases of Side-car Containers
Authenticating legacy applications with a reverse proxy
A reverse proxy that handles authentication
is one application for this design pattern. The plan is to run a Flask application in a container inside a pod. One should construct an nginx container in the same Pod.
Using the internal pod network, this nginx server
will establish a connection with the Flask application and implement authentication.
Authentication in Microservices
Business logic
is defined in a custom application in the form of microservices, which is decoupled with a sidecar container where authentication logic
is defined. Although both containers are independent, sidecar follows the same lifecycle as their associated service. They are created and terminated with custom service. The main advantage is, there is no need to write authentication logic for each microservices. With a sidecar pattern it will be reusable.
Share a Volume or Network
Applications where users can upload images, audio, video
but containers require small size so one can attach sidecar with the compression
feature.
Contents added by user stores in a shared volume, used by sidecar, compressed without compromising in quality and sent back to the storage
which is used by the application.
Supports dynamic configuration
To upgrade the main container configuration regularly
, create a sidecar container that reads the URL for updated configuration at regular time intervals and stores it in a shared volume so every time the application reads the updated configuration and serves up to date
.
Conclusion
If we want to increase the capability of developing applications or already developed applications we can append sidecar as a secondary container. For which features sidecar containers will be deployed is up to the requirements and use case of a particular application. This article is just giving a brief overview of sidecar containers with examples. We would love to hear comments from more people for betterment.