Docker is now a wrapper around libcontainer which runs an executable as PID1, with a build system for those containers (Dockerfiles) and support for features exposed by libcontainer (ports, bind mounts, etc).
The use case of "operating system level virtualization" is "I'm already running Linux, Solaris, BSD, AIX, or whatever, but I want to run another copy on top of it in order to segment off my clients/webserver/business unit/whatever". There's an implication that there'll be a real init as PID1, you may want to run sshd or another access point to let users in, and it's a "pet" in the pets v. cattle parlance.
The use case of Docker is "I built my application with this set of libraries on top of Ubuntu, but I want to deploy it alongside applications with different versions of libraries (also on Ubuntu or RHEL or whatever), and my application is the only thing that'll be running".
Remember when you got tarballs to unpack in /opt/${application} which came with start scripts which started with "export LD_LIBRARY_PATH='/opt/oracle/lib'"? Docker does that in a modern way. It can also do more than that with etcd, fleet, haproxy, and bits tacked on top to shuffle containers around, but that's the core of docker.
You, the developer, ship your application along with all the libraries it needs and it runs in a container on top of Ubuntu but it's using RHEL glibc/libwhatever without starting logind and all the other services associated with RHEL.