In a cloud native world, Containers play a pivot role and it’s important to understand the containers lifecycle, how they start, operate and terminate. Therefore a good understanding of the best practices in building the containers will go long way in building a successful application.
Containerise a Single App per Container
One of the important practise to follow in building containerised applications is to package a single application per container. The sole purpose and reason of existence of a container is to run the packaged application and for it to stay that way, its essential to containerise only a single application.
Often we will come across situations where packing two different applications in a single container might seem to be more logical and also ease the deployment and reduce overhead concerns like networking between the containers. But following this temptation would spoil the advantages of the container model.
When the container starts, the application should start and when the application stops, the container should terminate, both their lifecycle should be coupled with each other.
The container and an application are made for each other :pBest to follow One-to-One relationship
If multiple applications reside in the container, the above lifecycle principle will not be met successfully. This will lead to situations where Container Orchestration system like Kubernetes will not be able to ascertain the health of the containers if one of the applications in the container crashes or becomes unresponsive without additional checks like Liveness probe of Kubernetes.
The following multi-container design patterns try to address the concerns and find an efficient way in having multiple applications on a container
- Ambassador / Proxy pattern – This is a common pattern in layers like Service Mesh, in which Envoy or other proxy applications are containerised along with the primary application to facilitate seamless communication service
- Sidecar pattern – A secondary application to perform tasks which can be an extension of the primary application. Example, an application which collects the log events of primary and forwards to an aggregator
- Adaptor pattern – Can be used when primary application is unable to receive input or output in a standard way across all your applications. Example, may be, transform the XML output of the primary application into JSON.
These patterns can be used in cases when some helper applications might be needed to complement or aid the main application. But the helper application by itself doesn’t meet any business or engineering value.