Containerization is not Virtualization

“Another experiment” by Guillermo Mont

It seems like one of the most frequent questions I hear about containers is, “How is this different from virtual machines?” The answer I give generally depends on how many different ways the same person has asked the question. But I like to start with, “Containers and virtual machines are only alike in that they both provide isolation.” I go on to elaborate on the differences, “Containers do much less and are thusly inexpensive to use. Virtual machines provide whole virtualized hardware layers and can do much more but at a significant cost.” I think the biggest reason people get tripped up is that the two technologies seem similar in their function, at least at first.

“How will this effect my deployment strategy?”

People want to jump right to the conclusion and right to their bottom line. “How will this effect my deployment strategy? I just got to the cloud, am I really going to have to change everything again? How much is this going to cost? How much effort is this going to take to learn?”

Their suspicion usually turns to curiosity if you can peel them back from the ledge. Show them how projects like Docker make containers simple, how integration has already been implemented for the tools they already use. They’ll understand that there is some work to do, but learning and integration should be cheap. They still want to see the details.

“What is the performance like?”

“What is the performance like?” This is even more common than the first question. I’m not exactly sure what they expect to hear or why they ask, but the answer almost always surprises them. The performance is very near bare metal (direct / non-virtualized) performance. They cannot believe it and the reason is that isolation is not virtualization.

Docker volumes are just bind-mounted files (files are just like pointers to a location on disk and creating a bind-mount just creates another file that points to the same spot). Reading or writing to that file is basically as cheap as bare metal. On the other hand, reading or writing to Docker container file systems outside of a volume is more expensive. So don’t do that.

Docker networking is just like bare metal networking. There are a set of virtual (read logical) ethernet interfaces created for each container. Any network performance drop is due to an extra internal hop, NAT, etc.

Containers are built from a set of walls provided by functionality in the Linux Kernel. There is little (if any) additional processing or redirection required for IO. Containers are cheap. Oh, and since the software that makes them work is built into the operating system you can stop (or at least reduce) spending on virtualization software (or cloud instances).

“Wouldn’t this be less secure than virtual machines?”

Inevitably savvy conversationalists will ask, “Wouldn’t this be less secure than virtual machines?” Maybe... for now.

It is complicated because it depends on what you are doing inside of them. For the full break down checkout Docker, Linux Containers (LXC), and Security on Slideshare by Jérôme Petazzoni. I’ll do my best to summarize.

Containers are built using namespaces provided by the Linux Kernel. Namespaces turn what most people think of as an authorization decision (does process X have permission to access resource Y) into a context or domain decision.

If a process inside a container scans the filesystem looking for things to steal, it will only be able to see the files that have been made specifically visible to the container. If a process inside a container wants to try to do something malicious like open a backdoor service on port 31337, it will do little good because that port will not actually be exposed anywhere outside of the container. A malicious process inside of a container will not be able to access the memory of any other process outside of that container.

There are a few ways to break out of a container, but those generally require root access in that container. Don’t run applications as root. Harden root access through a few simple steps.

Containers use cgroups to provide the same level of resource use protection as a virtual machine. Both containers and virtual machines can gobble up a network link.

Some will point out that not everything in the Linux Kernel is namespaced. Meaning that there are some resources that are not yet isolated. That may be true, but it is changing. Going beyond the tools that ship with the Kernel, integrating with other hardening tools like AppArmor or SELinux will help you build some real fortresses. If there is extra work to do for containers to reach the same level of security as a virtual machine it is worth it.

  • Container provided isolation can be declaratively lessened for closer software integration. Virtual machines are rigid.
  • Containers do not run full operating systems (though they can). Virtual machines must always do so.
  • Containers use less idle resources than virtual machines. They do not run full operating systems.
  • Containers can be multiplexed over cloud hardware (or virtual machines) just like virtual machines can be multiplexed over bare metal. The difference is…
  • Containers take milliseconds to provision. Virtual machines take minutes. So you can reprovision, rebalance, release, and iterate much more quickly with containers than with virtual machines.

Honestly, most of these points feel silly to me. In my experience the most common reason that people provision hardware (virtual or physical) is to provide isolation.

Isolation

It is easier to manage your fleet if only one service/database is running per box. It is easier to monitor performance, understand failure impact, and forecast cost. At companies like Amazon where teams own their software and their hardware, isolation is critical for lines of ownership. Have you ever shared a critical resource like a load balancer with another team? Well, when your service tanks and you get paged in the middle of the night because they set their VIP to use a surge queue instead of spillover, you will start yearning for isolation.

The further from the target process, the more expensive isolation becomes. Virtual machines are great for abstracting increases in parallelism, serving multi-operating system use-cases, and best in class lazy security. But they are terribly expensive tools for isolation.

Containers provide isolation on the cheap. Get it while it is hot.

If you want to read more about Docker and containers check out my book, Docker in Action. Electronic copies are currently available through the Manning Early Access Program.