Personally, I think K8S with their cri-o (https://github.com/kubernetes-incubator/cri-o/blob/master/RE...) runtime is going to eventually eat Docker's lunch.
As a company, Docker needs Swarm/Enterprise to take off in order to have a differentiator. That isn't happening.
Kubernetes, on the other hand, just needs cri-o (mostly done) and an image repository / builder to kill off Docker.
See this for how small the gap really is: https://github.com/p8952/bocker/blob/master/README.md
Basically, Docker has almost no moat. They have mostly only brand recognition. Not discounting their efforts, but they are playing checkers and Google is playing chess.
If I had to rank understanding in explanations of docker:
1. "Makes your application really portable"/other explanations that only cover the benefits of docker not how it works
2. "Lightweight VMs"
3. "LXC + some other stuff"
4. "processes + namespaces + cgroups (+/- image management tools, etc)"
100% agreed on the point you made, pretty sure docker+swarm and other orchestration efforts have basically lost the competition. Kubernetes just has the mind share, and even better than that -- it's actually good.
Kubernetes also has multiple competing container runtimes all rushing to fit the CRI (Container Runtime Interface). Just some of the stuff out there:
* cri-containerd - https://github.com/containerd/cri-containerd
* runv (hypervisor based) - https://github.com/hyperhq/runv
* clear containers (hypervisor based) - https://github.com/clearcontainers/runtime
* kata containers (hypervisor based, collaboration of runv + clear container) - https://katacontainers.io/
* frakti (combination of runv & docker, enabling switching @ runtime) - https://github.com/kubernetes/frakti
A bunch of the projects are in their infancy, but the CNCF/kubernetes and the community are doing the right thing investing in lots of them, and letting the good ones bubble to the top. I don't run a production kubernetes cluster but I've found cri-containerd to be really easy to use and haven't had any major problems with it, mostly small configuration things.
The last one, frakti, gets me really excited, because it lets you be flexible about which containers run in more protected environments and which don't. Also really exciting is frakti v2 (https://github.com/kubernetes/frakti/tree/containerd-kata), which is kata + containerd.
Explaining docker is frustrating for me because I was a Unix admin back in the 90's. So, for me, it's pretty easy to see what it is. And, it isn't new. There isn't much it does that Solaris zones or BSD jails, didn't do. And those predate docker by years. Namespaces, cgroups, and pivot_root. That's basically all of it. Kudos to docker for marketing it better.
Explaining it, on the other hand, to a broad audience...
As a person who wasn't a linux admin back in the 90s, and doesn't normally hang out on mailing lists, the first time I saw lxc was some random article on lwn.net (I don't hang out there, but they have some super high quality articles), and I definitely didn't put together how much of a difference it was poised to make, or even know why it was a good idea (people were still getting used to vagrant everywhere at the time) -- docker definitely did the community a service by bringing the hype train, if only so that once the hype subsided containers would be here to stay.
Nobody was a Linux admin in the ‘90’s: we ran HP-UX, IRIX, OSF/1 DECUnix (and Ultrix), AIX, Solaris and NetBSD; those were our Linux we grew up on like you grew up on a Linux ISO on your parents’ PC bucket.
Also, whoever wrote x3270. Thank you!
Crazy.
For example, filed in 2003: https://patents.google.com/patent/US20050021788
Did userspace filesystems/layered filesystem-in-a-box implementations exist before? Sure: from ZFS to squashfs to tar, all the components were around.
But Docker's popularity is due to its integration; not its novelty. By bundling a filesystem-in-a-box abstraction layer with varying degrees of native OS support into something like a mountable artifact/image, hiding the image caching mechanics behind a nice CLI and image-configuration file format (love 'em or hate 'em, Dockerfiles are a phenomenal example of minimalism and convenience: add some meta commands, and everything else is just shell), and integrating all that with the privacy/isolation (namespaces/chroots) and resource management (cgroups/quotas) stuff, Docker made a really, really powerful model of thinking about "containers" as a single concept.
The thought model is Docker's big achievement: other competitors may unseat Docker eventually, but the concept of "container" as a single, unitary thing that's almost like a VM image will stick around, and the more piecemeal understanding of how containers work will be largely unnecessary, and thus save a lot of time for a lot of people.
K8s could easily release a command line clone and unseat docker in fairly short order.
Not dimininishing the value of what the docker folks bundled together and marketed. They did a terrific job. It just isn't very protected.
I think what made Docker popular was that it was easier for developers to use, with small bits of information like what ports the container wants to listen on and so on. From an administration standpoint, LXC was already more than good enough.
Any good resources you could suggest for learning more about what you describe as the relevant areas?
I think a good place to start is those talks (and stuff from any container-centric conferences), along with lots and lots of practice using containers.
In general, I'm pretty sure if you read up on chrooting, processes on linux, process isolation on linux, LXC, then the relevant standards/tools that underly docker like runc (https://github.com/opencontainers/runc), you'll have a pretty deep understanding.
Also, for day-to-day use, I honestly think you can do just light research on the above topics and start using docker and know way more than the average developer. As you use it more and more, you'll gain more intuition, and when you bump up against certain issues, you'll probably gain some intuition as to where things are going wrong (though honestly the toolchains are pretty stable now).
The goal of a lot of these projects is to be so stable you don't have to worry about it, so I don't feel too guilty about it, in the same way I don't feel too guilty about not ever having cache-line-optimized a program in my life.
Docker might well die but first I will have to be able to locally build and test containers on Windows and macOS, before deploying them to the Kubernetes cluster–without fooling around with Virtualbox, Vagrant and the like.
My personal expectation is that Docker will be bought by Microsoft, probably this year or next ...
Well how do you build images without docker?
https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0...
"Since CPU servers and terminals use the same kernel, users may choose to run programs locally on their terminals or remotely on CPU servers. The organization of Plan 9 hides the details of system connectivity allowing both users and administrators to configure their environment to be as distributed or centralized as they wish. Simple commands support the construction of a locally represented name space spanning many machines and networks. At work, users tend to use their terminals like workstations, running interactive programs locally and reserving the CPU servers for data or compute intensive jobs such as compiling and computing chess endgames. At home or when connected over a slow network, users tend to do most work on the CPU server to minimize traffic on the slow links. The goal of the network organization is to provide the same environment to the user wherever resources are used."
People are always amazed that container products are actually mostly just the glue around what the kernel already provides and that their history goes back almost two decades.
My mainframe folks, when talking about docker, universally yawn.
Is it Docker that is taking 200ms to start the container or just the nature of the OS APIs?
For starters, if you're just running the typical Docker set up to talk back and forth using a UNIX or TCP socket, all of _that_ networking and HTTP/JSON encoding+decoding will add some overhead. This is even worse if you're going through a proxy layer like the socket which Docker for Mac creates and forwards to the Linux VM. OK, so there's at least a few milliseconds of latency built in for this, the socket forwarding hop on my Docker for Mac seems to add ~5-15ms for instance.
Once the daemon receives the request, runc, the command that actually does the work to create a container without all that hoopla, is invoked.
Then, to actually start up a container quite a few mounts get set up either for devices (potentially including tty in the case of `run -t`) or for the union filesystem. Take a look at the output of `mount` in a container sometime, around 30-40 mounts (and all those overlay layers...) and a lot of that gets set up on the fly because each container has its own unique mount namespace and view of the world.
Then after all of that, you need to set up networking too (`docker run --net none` will skip this), otherwise containers can't talk to the Internet, to each other, or listen on ports of the host. Remember, each has its own network namespace, created from scratch. So, Docker's doing all manner of adding port proxies, modifying iptables, attaching containers to interfaces, and so on. Otherwise, `docker run alpine wget -qO- https://google.com` or `docker run --net=internalnet` wouldn't work out of the box.
The work isn't easily done concurrently since there are so many dependencies - e.g., you need to have a process in order to set a network namespace, in order to run that process, you need to have a root FS prepared to pivot root into, and so on.
Meanwhile to all of this happening the Docker daemon is doing god knows what, it could be pulling images, or running other containers already, supervising processes, etc. While many of those things are concurrent due to use of goroutines, they do eat up resources and generally too much work saturates and slows down the daemon. That's not really unique to Docker though, any program doing all this stuff at once would have that issue.
Anyway, that's why Docker takes way longer to start a process than good old execve() in your shell.
Therefore, it is as light weight as launching a process?
Is that about right?
There is a lot of cgroups and capabilities tweaking involved also. You can also use bpf (e.g. seccomp-bpf to restrict system calls etc.
In general you i) add the illusion of king in your little own world ii) provide necessary handling that the kernel expects from a king iii) restrict resources (e.g. memory, system calls,...) and facilitate communication with the rest of the worlds.