Multi-Container Pod Design Patterns in Kubernetes
In Kubernetes, Pods are the single deployable units. If an application is to be deployed, it must be so in a Pod as a container. Learn how to use multi-container pods.
Join the DZone community and get the full member experience.Join For Free
In Kubernetes, Pods are the single deployable units. If an application is to be deployed it has to be deployed in a Pod as a container. Though applications run in containers, the containers must be part of the Pod. The Pod specification has attribute containers where container specifications are declared. The attribute is plural. That means we can declare more than one container in a Pod specification.
Multi-Container Design Consideration
But Kubernetes administrators always choose one container Pods over multi-container Pods. One Container Per Pod is an unwritten practice across the industry. Let’s see what advantage a multi-container pod has to offer.
The Pod has an IP. All containers in the Pod share the same IP. If any volume is created for the Pod all the containers that are part of the Pod could mount it. So, containers can share storage. They can also communicate with each other over localhost.
In that case why still One Container Pods are still preferred. Let’s take a use case of a web application having UI, backend, database, and messaging tiers. We will deploy all four tiers as four containers in a single Pod. The resource, configuration, operation requirements are different for all four containers. The backend and frontend are customer-facing. If there would be a requirement to scale these to tiers, that can’t be done separately, as we can’t scale containers but pods. So, if we will scale up the Pod, multiple instances of database and messaging tier will also be created though that is not required.
Therefore, it is better to deploy them separately as managing and scaling them as individual Pods would be better.
In what case then we could use multiple containers in the same Pod?
Case 1 – If the lifecycle of containers is the same.
Case 2 – If two containers are very highly coupled
Case 3 – If we need to make our application deployable to Kubernetes without any code change. It would be in such cases where the application code lacks something to take advantage of Kubernetes features. In that case, we can bring in a secondary container along with our application container which will break such a barrier.
Multi-Container Design Patterns
Our homes are supplied power in AC mode whereas the laptops we use consume power in DC mode. In that case, we use AC adapters that draw power from AC outlets, then convert it to DC and supplies to the laptop. Without changing the power supply mode at our home, we could charge our laptops with the help of an adapter.
How can we relate it to Kubernetes? For example, if we have installed a centralized monitoring tool in the Kubernetes cluster, which needs all application logs to be printed in “APP-NAME – HOSTNAME – DATE – SEVERITY” format. But the cluster could have many applications written in a variety of languages printing logs in a variety of formats. In that case, it would not be wise for all applications to change their logging format as if the tool changes in the future and the format may have to change again. To solve this issue, we can spawn a second container that reads logs of the main application container, processes it into the format desired by the monitoring tool. Problem solved.
An ambassador is an envoy who represents his country in the outside world. How he can help us in Kubernetes Pod?
Take an example. You have a legacy application where the DB URL is hardcoded inside the application as localhost. It is difficult to change legacy applications as it brings forward changes in a lot of other places. If you have to make it deployable in the Kubernetes cluster, you need to change the code. You can do so without code change by using an Ambassador pattern. An ambassador container co-locates an application container in the same Pod. It works as a proxy. It connects to the correct Database depending upon the Dev, QA, or Stage environment.
The main application can connect to such external URLs as localhost through the ambassador container. The ambassador pattern finds the correct URL and supplies it to the application container at localhost. The main application container doesn’t need to worry about the correct URL. That is assigned to the ambassador container.
A sidecar is attached with a motorbike. It adds a seat or two to the motorbike without any changes to it. It is not an integral part of the bike, but it enhances the capability of the bike. A sidecar container also behaves in the same way. It enhances the capability of the main container deployed with it, without making any changes to the main container. For example, if you have an application that generates log files in a certain folder.
If your application monitoring tool in the Kubernetes cluster needs the logs to be stored in some external storage for all the applications deployed to the cluster, it simply can’t be done at the application level. Rather we could employ a sidecar container that will store the log files in the required storage easily without making any code change at the main application level.
All these patterns are very useful for doing cross-cutting jobs without making the main application change. They provide support for the main container and must be deployed as secondary containers. These workloads must be written in such a way that they could be reusable in different Pods.
To explain this approach, the adapter pattern was used where we have to convert or process the output of the main container to some standard format. Ambassador pattern is used to provide network proxy. Sidecar pattern is used to provide helper/utility services to the main container.
Try using these patterns to get the best out of your Kubernetes cluster.
Published at DZone with permission of Aditya Bhuyan. See the original article here.
Opinions expressed by DZone contributors are their own.