Containers are a game changer in software development, the advantages are very well documented in multiple places including the docker site. Creating an application to leverage these advantages though needs some special attention, maybe it’s time that we start thinking about container native applications. I have seen a huge advantage of this approach in one of our SaaS products. The recent vmware blog also mentions this need to re-architect applications for containers.
Cloud native applications are certainly in vogue, in fact as early as 2009 varying workloads on different modules of one of our products forced us to move towards a cloud native architecture, some of these advantages were critical in the product’s acquisition by Autodesk in 2012. Containers further improve some of these advantages, for example.
Scaling: Time to create a new instance is one of the main factors in scaling. While cloud brings down this time to minutes, containers do it in seconds (less than a second in my experience).
Keep the application start time really low. Some of the obvious things that can be attempted to achieve this are doing all non primary tasks like warming up a cache later, using frameworks that have lazy initialization options.
Operational Optimization: Cloud allowed applications to share h/w, containers allow them to share instances. We can now change resource allocations at runtime e.g I start two 4gb services on a 8gb large instance, based on the load I may shrink one to 2gb and grow the other to 6gb, all of this without restarts or changing instance types or creating new instances.
Understand the impact of container resizing (especially memory). For example with java vms, reclaiming memory could be tricky. Using a cache/pool that grows but never shrinks could be an issue. OOM Killer is certainly lurking around when you try shrinking without care.
Deployment: Images and configuration deployment tools simplified cloud deployments greatly, now with containers since we have even better control on images, no golden images are needed and the application can be baked into the image without any second thought.
Keep application configuration information out of the images, leverage your service discovery solution like consul to discover these configurations.
Some other points which need to be considered are :
1. Troubleshooting: Given the distributed nature of the applications, cloud made troubleshooting tough, my personal favorite was this twitter status which compared troubleshooting the monolith migrated to microservice architecture with a murder mystery. With containers this can become even more complicated, so we should think about a solution like ELK from day one.
2. Metrics: Application specific metrics and tools to measure them became important with cloud. With containers as we can take scaling decisions at a much finer level, this has become even more important. Using codahale metrics or similar metrics which is exposed by the application must be considered while designing an application.
3. Container Size: In our experience container size matters, this experience is shared by others, so design with this in mind, especially as the stack used in applications have many common components so shrinking the container size can be very easy in such cases.