The smallest deployable units that you can create and manage in Kubernetes are pods. A pod encapsulates one or more containerized applications. Configuring a single container in a pod is a common use case, but there are scenarios where encapsulating multiple containers in a pod is necessary. This usually occurs when there are two or more containers that are tightly coupled to each other and need to share the same resources.
In this article, you’ll be learning about Kubernetes sidecar containers, including how to implement them, and the best practices to follow when deploying a sidecar container.
What Are Sidecar Containers?
Sidecar containers are containers that are needed to run alongside the main container. The two containers share resources like pod storage and network interfaces. The sidecar containers can also share storage volumes with the main containers, allowing the main containers to access the data in the sidecars. The main and sidecar containers also share the pod network, and the pod containers can communicate with each other on the same network using <terminal inline>localhost<terminal inline> or the pod’s IP, reducing latency between them.
Sidecar containers allow you to enhance and extend the functionalities of the main container without having to modify its codebase. Additionally, the sidecar container application can be developed in a different language than that of the main container application, offering increased flexibility.
Use Cases of Sidecar Containers
Sidecar containers are a relatively advanced use case, and shouldn’t be deployed casually or without reason, as they increase the complexity of your cluster. That said, there are many ways that sidecar containers can enhance the functionality of the main container, and, in this section, we’ll discuss several of the most common uses.
Applications Designed to Share Storage or Networks
Sidecar containers come in handy when you need to write functionality that’s handled more efficiently in another programming language. For instance, say you developed an application with Laravel that allows users to upload images. When a user uploads a picture, you want to reduce the file size, but still maintain the image quality. You need to build this functionality into your application, but the container image you found for handling file compression was built in C.
Rather than reinventing the wheel, you can deploy the compression application as a sidecar container. When a user uploads an image file, the file is sent to the sidecar container, where it’s compressed, then saved in shared storage accessible to the main container.
Main Application and Logging Application
Logging and auditing are important aspects of Kubernetes monitoring and observability. In order to improve the security and performance of any application, you have to monitor the logs for potential security threats, errors, and other indications of problems. However, the raw logs are often difficult to understand, and many users choose to export their logs to another application for easier viewing.
Doing this manually is tedious and time consuming, but a sidecar container application can read logs from a shared volume and stream them to another application or a centralized server.
Keeping Application Configuration Up to Date
In Kubernetes, there is an option to mount your container configuration variables as volumes using ConfigMaps. This opens the possibility of updating your main container application configurations on the fly. You can create a sidecar container application that checks for updated configuration values from a URL at predetermined intervals, then update the configuration in the volume storage once there is an update. The next time the main container application reads configuration values from the volume storage, it will read the updated values.
Implementing Kubernetes Sidecar Container
For the purpose of understanding sidecar containers, you will create an example project. The project has two containers: the main container, which contains an nginx application that displays a simple HTML page, and a sidecar container, which is a dummy container that simulates an application that extracts logs from the main container and sends it to a centralized aggregator.
Before you can interact with your cluster, you need to install the kubectl client on your computer by following the installation guide in the Kubernetes official documentation. Once the installation is completed, you’re ready to start interacting with your Kubernetes cluster.
Create a file named <terminal inline>sidecar-container.yaml<terminal inline>, and paste the following yaml configuration into it.
The <terminal inline>sidecar-container.yaml<terminal inline> contains two configurations, one for a pod and one for a service. The pod configuration contains the main container and a sidecar container. The sidecar container is placed after the main container, so whenever you run the <terminal inline>kubectl exec<terminal inline> command on the simple-webapp pod without specifying a container, it targets the main container directly.
The service configuration is a NodePort service, which exposes the main application so that you can access it on your browser. The configuration contains a volume config with emptyDir that is mounted on the main and sidecar containers. This allows the sidecar container to read the main container’s logs and process it. By default, the main application container sends its logs to <terminal inline>/var/log/nginx<terminal inline>, which is why the main container volume is mounted to that directory.
In this example, the sidecar container reads the file and outputs it to the Kubernetes log every thirty seconds, rather than sending it to a central log service. You can see this in the <terminal inline>command<terminal inline> config of the sidecar container. Kubernetes logs capture the sidecar container outputs, which can be viewed via the <terminal inline>kubectl log<terminal inline> command.
Now that you understand the content of the <terminal inline>sidecar-container.yaml<terminal inline> file, run the following command to create the multi-container pods and services on your cluster:
You’ll need to test the sidecar container before continuing. In order to expose your service on minikube, you have to run the following command:
Before you visit the generated URL, open a separate terminal and run the following command to view the output of the sidecar container:
Currently, there are no logs to display because you haven’t visited the main application URL. Open your browser and visit the URL provided by minikube. Once the page has loaded, return to the terminal that’s watching the Kubernetes logs on the sidecar container, where there will now be output. The main application logged your visit to its URL, and the sidecar container is watching the log directory.
Sidecar Best Practices
It is crucial to follow sidecar best practices during implementation, both for security reasons and to maximize the sidecar’s efficiency and productivity. You’ll learn about some of those practices in this section.
Ensure There is a Reason for Separating the Containers
Managing sidecar containers can be complex, especially if you have many of them. They’ll need monitoring, updating, and resource management, just like a standard container. Failure to plan for this can make your cluster performance suffer.
Because of this complexity, it’s important to implement sidecar containers for specific reasons that will be beneficial to your overall application. One example is needing to extend the functionality of the main application with logging functionality or a file management system that was built in a different programming language. A rule of thumb in implementing sidecar containers is that they should be beneficial and not detrimental to the application.
Strive to Make Them Small, Modular Applications
Sidecar containers are meant to be compact containers with limited functionality. This makes it easier to maintain the sidecar containers, or to detect bugs quickly if issues arise in the pods. Keeping the sidecar container modular and compact can help prevent it from competing for resources with the main container.
Resource Limit Awareness
It’s important that the sidecar containers don’t consume more resources than the main container. Sidecars are containers configured to enhance or extend the functionalities of the main container, and their function is secondary to that of the main container. While keeping them compact can reduce the likelihood of resource overconsumption, they also need to be configured in such a way that their access to resources is limited. Allowing the sidecar to freely consume resources, especially the memory resource, will negatively affect the performance of your Kubernetes cluster.
One problem that may arise from this is a lack of sufficient pods to handle workloads. When a node in your cluster runs out of memory, the system kernel automatically terminates the container consuming the most memory with an out of memory (OOM) error, which often puts the pod in a terminated state. Appropriate sidecar configuration will allow you to assign resource limits to your sidecar containers, ensuring that this problem is avoided.
Kubernetes sidecar containers are useful in augmenting the main container functionalities. In this article, you were introduced to sidecar containers and their importance, as well as when sidecar containers are especially useful. You also learned how to deploy sidecar containers with main containers, and the best practices for creating and deploying them.
ContainIQ is a tool for monitoring Kubernetes deployments and observing Kubernetes events, logs, and core metrics that can provide insights into your cluster. Color-coded, user friendly dashboards make it easy to check the metrics of your cluster at a glance. Book a demo to learn more about how ContainIQ can help you fine-tune your deployments and better understand what’s happening in your cluster.