Organizations are slowly moving towards containerizing their existing software applications that are developed on varying platforms and technologies. But a few questions arise when we talk about containers: What exactly are they? Why should we choose new applications that can run on them or migrate existing applications to them? And, finally, what approach can we take when containerizing existing applications?
What is a container?
A container is a self-sufficient and independent software package bundled with application executable(s), its runtime, dependencies and configurations. It works despite differences between environments (eg. development, staging, production etc). This ensures that the developers focus only on the functionality and don’t need to worry about the hardware that hosts the application. There are many containerization platforms available in the market to support a variety of applications.
Why do we have to containerize applications?
Typically, applications contain multiple independent components, some of them independent of each other. Each component does a specified activity or has a specific capability. They also need varying hardware resources like CPU usage, memory requirements, storage sizes, IO, etc. to perform their tasks. Some components may require more hardware resources than others. There could also be an increase in the usage of certain components for certain periods, resulting in additional hardware resources required to cater to this increase.
Components with higher resource requirements or high usage may deprive other components of hardware resources if they are sharing infrastructure. This can cause applications to perform slower than normal as some of the components might be waiting for their share of hardware resources to complete a task.
One approach to managing the high hardware resource requirement of certain components is to deploy them on multiple servers and balance the load. Increasing the hardware capability of existing servers is another approach to make the required resources readily available to these components. In both cases, this comes at a cost of under-utilized hardware that will be idle during low demands. To avoid this issue, additional servers can be provisioned as needed whenever there is an increase in usage. The flip side of this is whether there are servers available when needed, the time it takes to bring a server online, and the high startup time to initialize components on the new servers.
Containers help in addressing the limitations of under-utilized hardware and lengthy startup times. Containers are small and lightweight, with all the required software and dependencies bundled within them. They can be launched quickly on any of the readily available hardware. As mentioned earlier, applications contain multiple components. These components are packaged into multiple containers along with the required libraries, runtime, configurations etc. and instantiated to run an application. Multiple instances of each container can also be launched. To start with, fewer instances of each container can be set up for normal usage. Additional container instances can be launched automatically in response to events like high usage, faulty instances, etc. These containers can be brought down automatically when the usage returns to normal.
How are applications containerized?
Applications can be containerized with three simple steps: componentize, package and migrate.
The first step towards containerizing an application is to break down the application into smaller independent components. Applications that have a greater degree of modularity, lesser dependencies and well-defined interfaces can be broken down easily into multiple components.
The second step is to package the application components. Components are packaged into their respective containers along with their dependencies, runtime, etc. Appropriate configurations are applied per environment (e.g. development, staging, production, etc.) to make these containers deployable and ready to use.
The final step is to migrate the application data, databases, storage, etc. These can also be containerized but only for non-production environments where there could be a need to go back to the previous state, for example, a development environment. In production scenarios, databases and storage are generally not containerized as containers are non-persistent while the databases need to be highly persistent. Migration of application data, databases and storage will have to be performed in a similar way to any non-containerized applications.
What approach do we take to componentize an application?
Let us look more into the first and the second steps – componentize and package. Typically, applications are built with multiple tiers or layers for example, UI or frontend, business logic or backend services, authentication and authorization, integration, etc. Each tier or layer can have multiple primary and secondary components. Containers can be created for each of these components along with its dependencies, (runtime, configurations, etc). The advantage with this approach is each component can have its own container, thereby providing the ability to scale only the required components. The disadvantage of this approach is that the number of containers created will be high. It also requires more effort to monitor and manage containers, and the orchestration will be complex.
There could be scenarios where the application cannot be broken into smaller components (componentized) due to various factors. An example could be an application lacking the modularity to componentize, or applications that are too small with no additional benefits when componentized. In these scenarios, the entire application can be packaged into a single container along with its runtime, dependencies, configurations, etc. The advantage being that it is simpler to manage a container, and the entire application can be instantiated in one go. The disadvantage with this approach is any small change to the application requires the entire container to be rebuilt. Redeploying these containers in production can cause frequent disruptions on application availability.
A more realistic approach would be to have dedicated core containers for primary components to make them independently scalable. Multiple secondary components can be bundled and packaged into separate non-core containers.
Careful analysis has to be made in identifying primary components, levels of componentization and the grouping of these components. The outcome of the analysis needs to ensure that the containers meet the application usage demands, make them easier to manage, and provide optimal utilization of hardware resources.
To learn more about containerization of OpenText products, please see our OpenText™ Cloud Editions (CE) website. If you would like to upgrade and migrate to a container version of your OpenText products, please connect with OpenText™ Professional Services.
OpenText was named a Leader in 2019 Gartner Magic Quadrant for Content Services Platforms – learn more or get a copy of the Gartner report here.
You can also learn more about OpenText Content Suite Cloud Edition (CE) 20.2 and OpenText Extended ECM Cloud Edition (CE) 20.2 here.
Author: Satish Rallabandi, Senior Principal Architect, Professional Services – Center of Excellence