This is at the core of the education issue with containerisation.

By pushing wrappers like LXC and Docker we have been positing containers as a replacement for virtual machines, a "lightweight" VM if you must.

The issue is this has lead to fundamental mis-understanding about how containers work on Linux.

In other communities like BSD and Solaris communities they have understood containerization for some time. Both BSD and Solaris have had network virtualization/namespacing for significantly longer than Linux and the community grew around them utilizing them the way they were intended - as a name spacing technology for processes.

Most people don't understand the underlying concepts that Docker and LXC rely on, this leads to people asking questions like "What is the performance impact of Docker?".
If you knew that Docker was basically constructed ontop of the cgroups, namespaces primitives and AUFS or Device Mapper you would probably not ask such a question because the answer would already be obvious.

For those that don't know the overhead of cgroups and namspaces is mostly constant (there are some exceptions but won't go into that), infact all of these systems are compiled and in operational in modern kernels even when the cgroups fs is not mounted. As such the CPU overhead of running a process in Docker should be close to nil.

There are 2 other important factors however, namely network and disk performance. The Docker graph storage system relies on Copy-on-Write (CoW) semantics. There are few filesystems that implement this and none are currently upstream, the fastest and most robust and AUFS and is the Docker default.
AUFS does have some overhead, it's by no means large but I wouldn't go as far to say it's negligible either (especially when creating lots of files).

However, if you are running on a system that doesn't have AUFS available you will be using the Docker Device Mapper graph driver. This driver is not actually using a CoW filesystem, it is instead using a CoW block storage system called Device Mapper thinp (Thin Provisioning). This has -many- more performance implications. Namely you can't utilize a block device directly, you need to format it with a filesystem. Docker supports ext4 and XFS. Then when you are adding layers it's creating block level overlays rather than file level overlays like AUFS.
The major difference here is the IO path, specifically in the case when you are not using a dedicated DM pool for storage.

ie. When using DM in default loopback mode

mounted layer -> dm-thinp device (funky stuff with thinp metadata device too) -> loopback file -> host filesystem -> host block device

I don't bring any of this up to bash Docker, I am just saying it's important that you know how this stuff is constructed.

Now, all of that can be completely avoided if you use Docker volumes for all IO intensive workloads (and you definitely should do that) as it should have close to no overhead as they are implemented as bind mounts. This is safe due to the way filesystem namespacing works. The isn't quite as good as Solaris zones which uses ZFS functionality to do all of this.

To quickly touch on networking Docker relies on stateful iptables NAT. This has significant performance implications and should be something you also understand if using Docker in production.

You could argue that none of this matters for the way people are using containers right now - and you would be right.
But I love this technology and I want to to be used in production and at scale, to do that we need to be educating people on what this technology really is, how it works and other ways you can put these building blocks together rather than just mimic-ing full virtualization.