So, a software engineer installs Docker and is blown away with how quickly he or she was able to provision an instance...
of the stack desired. Then, the engineer is struck by a thought: “Haven’t I done this already with a virtual machine?”
Sure, container software is a fast way to provision, use and move around applications, but the core concepts around containerization of the stack are not new. The trusty VM can technically achieve all the same things that containers can, including compartmentalization of entire stacks, portability and full-stack deployments.
The reason VMs were not as widely adopted by developers could be an artifact of how they were delivered to them versus how they actually function. So the lack of enthusiasm and stagnation of VM technology could be philosophical and not technological.
So why is container software getting so much more attention from software developers today than VMs? There must be a reason. Here I will discuss the technical and philosophical differences between containers and virtual machines. Let's dive deeper into each category exploring containers vs.VMs.
- Hypervisor: The hypervisor requirements for VMs are large and are inevitably tied to where the hypervisor is installed and its version. VM containers are also confined to a specific hypervisor type. There are plenty of conversion tools, but the conversion process has to happen before you can move from one hypervisor to another. Meanwhile, containers are hypervisor independent.
- Back-end Support: VMs have a much wider support for the back end of applications. Today, it is not very practical to create Docker containers for your back end, nor does it really fit with the principles of containers, which should have relatively short lifespans. Ideally, upon every release, all current production containers are destroyed and replaced with new ones.
- Size: Sans the lack of support for back ends, which can bloat any container, containers are substantially smaller. A one-for-one comparison of just front-end application deployments on a Docker container will be much smaller than its equivalent VM. This means that provisioning, which requires the copy of the physical image file, is much faster with containers.
- Speed: The difference in speed degradation from the host OS to the container is an important consideration. There is a loss with VMs, while containers arguably have none -- excluding the small overhead for the Docker service. This means you will get a greater performance benefit with containers versus VMs. However, this is easily made a moot point when you realize that most Docker instances run on VMs. There may be no loss, but they inherit the degradation of the VM from its bare metal host. With the exception of developer machines, the best practice is to run on a VM instead of the local machine.
- Host OS: A VM is fully isolated from the host OS, where Docker has isolated memory and disk space, but it is leveraging the same kernel. Additionally, Docker does not support the breadth of host or container OS that a VM does. VM allows you to choose your own, but Docker is limited to both Linux host and container. If you are a Microsoft shop, you have more options running Docker on Window Server 2016, but much fewer options than with VMs.
- Networking: VMs have a broader set of networking capabilities. VMs support virtual networks, which can be snapshot along with a collection of networked VMs. This offers a lot more flexibility, but is probably more relevant for desktop environments and less for application development. Containers can also be networked, but the technology is less mature and configuration more complex, and negates the portability aspects.
- Images: VM snapshots and container images are both ways to maintain a library of instances to be provisioned in the future. One feature of VMs that is not possible with Docker is the ability to suspend and maintain memory state. This actually can fast track full-stack deployments for enterprises and offers a unique ability to address application bugs. Docker supports PAUSE and UNPAUSE, but it is still only local to the active instance.
- Management: Both VMs and Docker containers have unique management considerations. Docker containers, in particular, need to be treated like application components and versioned and stored in a repository. Docker containers are built of layers and have a lot of moving parts for which all changes need to be tracked. VMs change less frequently, but still need to be managed. It is likely that a typical setup of Docker will have more containers than the number of VMs in a typical setup of a hypervisor. So container sprawl is more likely than VM sprawl, but both suffer from this critical issue.
- Portability: Because of size, networking, and hypervisor, among others, VMs are not nearly as portable as Docker containers. It also means that you are locked into a specific vendor's hypervisor. You can move, but it is not as seamless as provisioning a new instance of a Docker container anywhere you want without any overhead.
- Culture: While it's difficult to quantify the impact of people on technology adoption, this does not mean there is a lack of impact. Docker was launched as a tool built by developers for developers. It was something that developers understood in their typical development flow and could access much easier. On the other hand, VMs were introduced at a time when IT had full control of all infrastructure, including development, and it has since been considered IT's domain.
- Process: Docker is considered a development tool, not an enterprise IT tool, meaning it was built with the development process in mind. It better supports release automation and full-stack deployments. This is largely due to the fact that it is better documented, includes more integrations and a smoother flow. But a lot of third party vendors are addressing the hurdles that the technology is trying to overcome.
- Overhead: Because VMs are tied to a hypervisor and are bigger, there is still typically a process to procure them. This could be eliminated, but for most organizations this is not an option to do to existing setups. Because there is still a process to procure them, it does not support the modern DevOps delivery chain and keeps them in the IT domain.
- Price: Docker is free, or that is the perception. Serious organizations need to purchase the proper Docker ancillary tools and the more expensive third-party tools that enable better repository, management and auditing. The resulting costs will still be far less than the two largest providers of hypervisor technology. For this reason, and if the budget falls under development, Docker is a very attractive solution.
We are missing one relatively obvious and big thing: Docker's container software nearly always runs on a VM. But again, the VM is a set and forgets its infrastructure, so having Docker run on them builds more flexibility. Additionally, if you choose to run containers on bare metal, it may not be a common implementation, but is a huge benefit to performance.
I have frequently seen organizations that end up treating Docker containers like VMs. But if this is the case, the value is mostly lost.
The limitations of VM adoption in development have mostly been due to how organizational structures were set up around them. Docker's container software wins on agility for sure, but besides the key difference of size and machine speed, there is nothing that prevents VMs from being a full-blown containerized solution for the modern software delivery chain. The differences, in my opinion, are close enough that enterprises should consider VMs as a viable solution and should not use Docker as an excuse to not move to DevOps processes, such as Continuous Integration, Delivery and Deployment.
Manage polygot programming by choosing the right DevOps tool