Two of the hottest buzzwords in IT, right now, are DevOps and containers. While both terms are emerging and so battling with varying meanings and unclear expectations, they represent activities and technologies that are likely to become part of many developers' daily work. Fortunately, DevOps and containers provide real value, and they are even more compelling when used together. So what exactly can they do for you as a developer?
Starting with Stateless
Over the past few years, the IT industry has really embraced the concept of the truly stateless application. This isn't new. As developers, we have long claimed to write stateless applications using various methods including (but not limited to) HTTP, EJB, and CORBA. In practice, the applications were rarely, truly stateless.
As a simple example, take your favorite application. How easy is it for you to spin up a new front-end server instance and replace the existing one? Is the experience a seamless one for your users? I doubt it.
Why do we care about this? When we make stateless applications, the operational aspects of deploying and maintaining the application become much simpler. For development purposes, application maintenance and feature additions are also streamlined because the application is much more compartmentalized. Users appreciate stateless applications, although they may not realize it, because the perceived uptime is better and the application more consistent.
Smaller is Better
Once we have stateless applications, we have more flexibility. In particular, we start to think about how we can get "just what's needed" to underpin our application. In doing so, we can create very small dependency chains, which has several advantages:
- Less effort to maintain: With the smallest number of dependency updates, there is less to patch and we are less likely to introduce new bugs/patch breaks
- Lower infrastructure requirements
- More deployment options, as in virtual machine (VM), physical, or cloud
- The smallest attack surface possible for hackers to use
The tradeoff, however, is knowing what is "small enough" but not "too small." Enter containers. A container isolates your application from wherever you are running it you install only what you need to run your application and nothing more. You can also develop directly in a container, as it gives you a separate network stack and storage without the overhead of building and running a virtual machine (VM).
While freshly built containers can be deployed straight into production, I think that it's important to first rebuild containers with just the components you need. Why take this extra step? It is important for you to know exactly what is in a container, and it's also important to be able to prove it to your team/stakeholders.
When you know exactly what's in the container, you have a better idea of your risk exposure and future needs. At the very least, you can be confident that you can code and reproduce it in your development environment. And because of the container's independence from the operating system, it will "just run" when it moves to deployment, eliminating the variations of the excuse that "it worked on my machine."
The deployment independence of a container also enables sharing your development environment with other developers, QA engineers, security folks, and anyone else that needs to run the application during development or testing.
You could, of course, use a regular VM to get many of the same benefits of a container, but VMs have several important drawbacks. The most important of these is that VMs have a lot of overhead and, no matter how minimal the OS is, you (normally) need to fully copy that OS for each application. Because of this constraint, I am seeing containers and VMs used in a complementary fashion. For example, I have been using the new Project Atomic "Docker host" as a VM on my laptop for development. I then mount my local
\projects directory to the VM and then mount the particular project source into a container for local testing. This gives me the "containment" of a VM to separate my development installs from my local machine and the portability of the VM in case I want to move my development to another machine. By using multiple containers inside of the VM, I can work on multiple Web projects without having to create a VM for each one or wasting time setting up lots of different ports and application configurations.
In the production world, many people are already operating in virtualized environments. If you are leveraging containers for deployment, you can easily drop an application onto a VM, physical machine, or a third-party cloud VM. Again, all of these advancements in flexibility are derived by having a layer of abstraction between the OS and your application.
The DevOps Aspect
We now have stateless development, containerization, and the complementary use of VMs, but what does any of this have to do with DevOps? Note that DevOps is a lot of things to a lot of people. For our purposes, the most important aspect is boosting collaboration between developers and operations for application deployment.