The real power of containers comes with container orchestration (i.e. Kubernetes, Mesosphere, and OpenShift). By leveraging containers, container orchestration systems can provide high availability, scalability, and zero-downtime rollouts and rollbacks, among many other things. These things were hard before containers & container orchestration. By allowing containers to be moved between nodes in a cluster, one generally achieve higher hardware utilization than with VMs alone (which is in itself a big improvement upon software on bare-metal hardware). All of this also leads to easier/better continuous deployment, as well. This, in turn, leads to easier testing, and greatly simplifies provisioning of hardware for new projects.
So, the benefits are:
- Cheaper than VMs (through better hardware utilization)
- More reliable, through HA load balancers
- More scalable, through scalability load balancers
- Better testing, through CI/CD enabled by containers
- Faster application delivery by simplifying provisioning - Nobody ever used VMs the way containers are
- A HA load balancer is not a container-specific concept
- There is no such thing as a 'scalability load balancer'
- You don't need a container to do CI/CD
- It's not faster, it's slower, and it's not simpler, it's more complex- I never said an HA load balancer is a container-specific concept. I said that "these things were hard before containers". I stand by that statement. Containers and container orchestration make HA proxies really, really simple.
- A scalability load balancer is a load balancer in front of a service that monitors load and scales up, or down, the number of instances behind that load balancer. Again, container orchestration makes this really easy.
- No you don't need a container to do CI/CD. But containers make it much, much easier.
- It is faster. I can provision an entire cluster of machines in about 5 minutes on AWS or GKE. If I have an existing cluster to publish to, it's even easier--it's one line in my continuous integration config file. Container orchestration has a learning curve (I'm assuming this is why you say "it's more complex"?), but it is tremendously easier and faster to provision hardware for a project with containers and container orchestration when compared to provision actual hardware, or even provisioning VMs.
Sounds like you haven't really used containers at all.
The old model was a system would be running, and a lot of software components within that system would depend on each other, creating a web of dependencies. If one of the dependencies had a problem, it could bring down the whole system [in theory].
The new model is "simpler" in that every software component has its own independent operating environment, with [supposedly] no dependency on the others. In this way, if one dependency fails, it can do so independent of the system at large - the failed piece is simply replaced by a different, identical piece. In addition, the component environments don't store state or anything else that would be necessary in order to replace it.
We basically bloat up our RAM and waste CPU and disk space in order to be able to understand and support the system in a more abstract way, in the service of better availability, and also, better scalability.
How is this different from simply running a bunch of chroot'ed services on a system without containers? It really isn't. But you get more control over the software by adding things like namespaces and control groups, and by everyone using the same containers, more uniformity. By dealing with the annoyance of abstractions and bloat, we get more human-friendly interoperability.
There's no good reason we should have had that many in production. We had three versions of the 2.X series and two versions of the 3.X series because of mixing-and-matching base images we used plus management deciding that we could do partial upgrades of Python version by upgrading a project at a time. (We switched from 2 to 3, which meant we had containers -- with different base images -- where we updated the 2.X version but not the 3.X version and containers where we updated the 3.X version but not the 2.X version. This gave us all kinds of mixes and matches of Python 2/3 versions.)
So I just hoped whoever was maintaining base images was actually maintaining their security patches, kept the versions we were intentionally using up to date during container construction, and it (mostly) just sort of worked out.
We're down to... 3 versions of Python and 3 base images. I'm trying to get down to 2 versions of Python (a 2.X and 3.X).
Note also that binary packages help with repeatable deployment that uses Docker, deployment tools (e.g. Ansible or Salt), configuration management tools (CFEngine, Puppet), even manual -- and mix of all these. Docker images only help with Docker deployment.
I'd argue that only Linux containers are like VMs.
Nix[0] genuinely tries to solve the problem.
For example, here: https://github.com/mbrock/gf-static/blob/master/Dockerfile
Making static binaries is often extremely painful and confusing. It's easier on a distribution like Alpine, and nicely enough, Alpine comes as a Docker image.
In general, Docker's ability to basically spin up a whole Linux distribution, with a whole root file system, makes it very different from just using static binaries.
Along with Docker's image repository infrastructure, it makes some things easy that weren't easy before. Like, I don't know if there is a static binary build of the Erlang runtime system, and I don't know what kind of file system tree that system needs, but I just now opened an xterm and typed "docker run -it --rm erlang" and got an Erlang 9.0.2 shell.