Containerising application - design pattern

9/23/2019

I am working on containerizing a bunch of applications that have the following structure at a high level:-

  1. Read from a DB/File system
  2. Extract the data or do some parsing (Business logic)
  3. Write back the crunched data to datastore.

Let name these 3 steps as s1, s2, and s3.

What is the best way to have a balance between code reuse and making the solution overly complexity? In other terms what is the best design pattern/practice to implement this kind of solutions that are industry-accepted?

Few approached that I could pen own are as follows:-

  1. Separate pods for each application with one container each, having s1, s2, and s3 as part of same code.
    • Benefits: Simple and compact code base. No interprocess/pod communication
    • Limitation: No Code reuse
  2. Separate pods for each application, with each pod having 3 container doing separate functionality as s1, s2, and s3.
    • Benefits: Code reuse.
    • Limitation: Interprocess communication may increase processing latency.
  3. Separate group of pods for s1, s2, and s3 says sg1, sg2, and sg3 respectively running independently. From an application perspective, we create a new pod that talks to the mentioned 3 pod groups to get work done.
    • Benefits: Code reuse.
    • Limitation: Interprocess communication may increase processing latency. Also, maintaining pod groups is an add-on overhead. Increase in complexity

Request to suggest any other alternative if suitable.

-- Edu Tracker
containers
design-patterns
docker
kubernetes

1 Answer

9/23/2019

If your applications are monolithic, the most obvious way is to package each application as a single process in a container image, and deploy the containers to Kubernetes as pods (one container per pod) managed by a Deployment resource (allows you to replicate the pods and do rolling updates). This corresponds to approach 1 of your list.

If the components of your applications are already loosely coupled, you could go for a microservices type of architecture. For example, you could extract the common logic of s1, s2, and s3 for all applications into separate microservices, package each of them as a container image, and run them on Kubernetes as pods (one container per pod, managed by a Deployment). The core of each application would then be its own "microservice", packaged as a container image and deployed to Kubernetes as pods managed by a Deployment. These "core" pods would then use the services provided by the s1, s2, and s3 pods as clients. This would correspond to approach 3 in your list.

Regarding approach 2, this isn't a best practice. In most cases, a pod contains only a single container. In some cases, there are multiple containers in a pod, but then one of them is the main container doing the main job and the other ones are tightly coupled sidecar containers that do auxiliary jobs.


Summary

If you have a lot of common logic across your applications, then approach 3 makes sense, to avoid code duplication. Also it provides the finest granularity for scaling. Groups of pods are managed by Deployment resources, which you will use anyway, even if you deploy each application as a single pod, so this is no overhead.

If the common logic is not so big, then approach 1 is the simplest solution.

-- weibeld
Source: StackOverflow