When I first came to Robin over 2 years ago, stateless applications in containers wasn’t even on the majority of company’s minds. We would have conversations that went along the lines of we are still figuring out this micro-services thing and are not ready to touch the hard stuff. This is why Docker for years developed primarily for stateless (Read LxC vs. Docker for more information).
Well, today, if you are in financial services, healthcare, or manufacturing and are not developing your stateful strategy, I hate to tell you friend but you are falling behind the competition.
Higher Market Share – Container Technology
Container technology is rapidly gaining market share with “application containers see(ing) the fastest growth. with an estimated CAGR of 40%” (451 Research). The question is now what is the best way to transform stateful applications to the Docker stateless microservices paradigm or like we have seen attempted recently – how to make Docker retrofitted to support stateful.
Why is everyone now rushing to provide persistent storage for containers? For one, state information is required to do anything meaningful with software programs because data about an activity is fundamental to runtime processing.
In traditional distributed architectures, application processing logic moved from the client to the middle tier. As a result, a server-side program was required to manage interaction with multiple client programs, each with their own individual state information processing requirements
Stateful and Stateless Applications
For clarification, generally, stateful means the computer or program keeps track of the state of interaction, usually by setting values in a storage field/parameters designated for that purpose. A stateful app stores information about what has happened or changed since it started running.
Stateless applications have no record of previous interactions and each interaction request is handled based entirely on information that comes with it.
For Docker to handle stateful applications, it needs to provide for data persistence, typically related to storage. You might say, but Docker has a concept of a storage volume plug-in. However, it is fairly new so I’m not sure how “battle tested nor optimized for production” it is. In Docker, a volume is simply a directory on disk or in another container. Docker now provides volume drivers, but the functionality is very limited because you can only have one volume driver per container and there is no way to pass parameters.
While this basic container related storage may suffice in some cases, it has major flaws when it comes to HA (High Availability), bringing containers back up on different nodes, multiple volumes in multiple containers representing the same app, etc.
Is Kubernetes, ready for Stateless?
In Kubernetes, a storage volume has an explicit lifetime – the same as the pod that hosts it. A volume outlives any containers that run within the Pod, and data is persistent across container restarts. When a Pod “dies”, the volume will disappear as well.
So, you ask, how is Kubernetes, which was designed and optimized for stateless, can claim stateful application support and persistent storage, let alone support multiple containers and clusters?
Do you care about performance?
Kubernetes recommends using StatefulSets with remote storage. In plain English – you will have to be ready to tolerate the performance implications of network attached storage (NAS). Even taking the storage optimized instances, you are likely to lose performance versus locally attached storage.
Do you care about guaranteeing predictable application performance?
We have not yet seen Kubernetes supporting isolation of network or storage I/O across containers. After taking your performance hit, think about collocating applications sharing the same storage. You will have to accept noisy neighbors that will hurt the IOPS your application can handle.
One can “work around” this by scheduling the Pod containing the application as the only tenant on a node (dedicated machine) or by using Pod anti-affinity rules to segregate Pods that contend for network or disk, but this will mean constant manual active monitoring of hot spots to potentially address the issues. Your need for additional DBAs, custom scriptology, and headaches will grow faster than your data.
A Stateful Answer
At Robin, our conversations with companies about our Hybrid Cloud Platform have turned how we handle stateful applications using containers given Docker’s optimized design for stateless micro-services architecture.
We chose container technology, either Docker or LxC, to virtualize the infrastructure from the apps primarily because of bare-metal performance but also because of much better consolidation capability. We then added our own block storage – designed and developed for specifically for container technology, capable of handling 100s of thousands of volumes and IOPS very efficiently and effectively.
Building the container-based application-aware scale-out storage allows us to go so much farther than the very basic and limited volume plug-in. In fact, in cases where there is a need to scale or move containers across hosts, we can re-mount its volume on the new host totally transparently to the users and the same applies in HA cases.
The ability to control the entire application IO path from the compute through the actual storage blocks enables us not only to support stateful applications, but also provide entire application lifecycle ranging from scaling (in/out, up/down) to relocation to snapshots (and time travel) & cloning, as well as thin provisioning.
Kubernetes needs an army of DBAs and engineers due to its container architecture. Robin Cloud Platform (RCP) is designed to understand applications. Scaling, HA, Cloning, Time-travel, relocation are simple tasks that one person can handle with a couple mouse clicks across various applications since the application complexity is abstracted by the platform.
Want to do that with Kubernetes? Start your years of custom scripting now, and yes -good luck.
To sum it all up, the container market is winning by going after the low-hanging fruit of stateless, webscale applications. Moving up the tree to the hard-to-get-at-fruit will require a whole new framework. It is much better to start with a ladder designed to reach all the fruit.