This is a good question, Ashish, and one that many people ask. The critical difference between containers and virtual machines is that containers on the same runtime all share the same Linux kernel. This has both advantages and disadvantages. The ease of integration with the host operating system, and interaction and overlap of containers on the same host can be an advantage both in performance and in resource over-allocation. But the flipside is that it is not as secure because the only barrier between containers is the kernel, rather than actual CPU-level enforcement like you get from a virtual machine. Containers also run a higher risk of noisy neighbor issues than do virtual machines.
Some container runtimes have made the best of both worlds, using micro-vms to run container images rather than a container runtime. We talk about some of this in the book as well.
In general things running in containers on the same host need to be assumed to be cooperating with each other from both a resource and security enforcement standpoint. There are resource utilization and security barriers, but they are just not solid enough to be used to run e.g. workloads publicly configured by end users.
Containers are more than just the runtime, though, as we explain in the book. They make portability and containment of all depedencies for your application easy. The ergonomics are very good, and resource utilization can also be excellent. Those and other workflow/tooling improvements are many of the reasons for their success.