Much of what's included here and in the following blog entries on Docker is based on a very good class I took at LinuxCon 2016 run by Bruno Cornec. He had some slides prior to the class itself: they're probably available online but I'm not sure where. Here's a link to the lab we were following: https://github.com/bcornec/Labs/tree/master/Docker .
An explanation of Docker per Wikipedia:
Docker provides an additional layer of abstraction and automation of operating-system-level virtualization on Linux. Docker uses the resource isolation features of the Linux kernel such as cgroups and kernel namespaces, and a union-capable file system such as aufs and others to allow independent "containers" to run within a single Linux instance, avoiding the overhead of starting and maintaining virtual machines.
The Linux kernel's support for namespaces mostly isolates an application's view of the operating environment, including process trees, network, user IDs and mounted file systems, while the kernel's cgroups provide resource limiting, including the CPU, memory, block I/O and network.
Notice the "mostly isolates." Docker's security isn't as good as a full virtual machine - although we can't claim that's perfect either. I believe the kernel security features that made Docker's containerization possible were introduced in the 3.x kernel series, although Docker's documentation notes that there are issues with kernels prior to 3.10. Not that this should be an issue for anyone: most kernels are much more recent than that.
Docker allows you to create something that looks and behaves like an isolated virtual machine, with the very important distinction that it runs on top of your existing kernel (a "real" VM has its own kernel). This gave me something of a head-spinning moment when I was using a CentOS Docker instance on my machine, and the
uname -a command returned the name of the underlying Debian kernel. Docker instances are also lighter weight, faster starting, and more transportable than VMs.
One important aspect of Docker instances I'm not entirely fond of: they're immutable. While I don't like it, I can also see the security advantages. When the instance is running, it can change: but when you restart it, it resets and remembers none of the changes. To modify the instance permanently, you have to modify the Dockerfile from which the instance was built, and rebuild the image. Even that isn't a full description, and I'm not entirely sure that my understanding is complete or accurate: if you have an image and rebuild it with the Docker file, new changes are simply laid on top of the existing image as an aufs overlay ("Advanced multi-layered Unification FileSystem", an improvement on the older UnionFS).
Next: Basic Docker