Everything needs to be namespaced
and there needs to be a scalable and robust model for sharing resources.
Containers do the first part but not the second. Classical OSes do the second part but not the first.
Here's what I would do if I were working on this problem:
(1) Shared libraries can be linked by name and version constraints or by specific cryptographic hash of the library. The former uses some kind of name resolution system to get a cryptographic hash from that name and version constraint. This is not terribly unlike NPM or modern Go module versioning. It would allow sharing of resources without security or "DLL hell" type issues. The OS lazily grabs libraries by cryptographic hash off a configurable list of sources that could include URLs, IPFS, BitTorrent, peers on the same LAN, etc. (1) Could also perhaps be extended to include binaries, but this would require more thought.
(2) Kill the concept of installing software "on" a machine, but in a finer grained way than containers. Segment applications and services the way users are segmented: each app or service has a home directory and a UID/GID. Get rid of /bin, /usr/bin, etc. in favor of some system infrastructure for finding binaries where they live. MacOS has some of these things but isn't consistent about them.
(3) Lock down the system a lot harder in terms of different users being able to see anything outside things they own. For example a user should not be able to "find /" at all. This would be similar to containers but a little simpler.
(4) Extend namespacing and user/group ownership to network identifiers like IP addresses and other things. I think you could do this with existing cgroups plus some user land support.
(5) Get rid of system level service management (except for truly system level services) in favor of per-user services. Each user can run their own services/daemons that bind to IPs/ports in their own namespace.
(6) Kill 'root' in favor of a hierarchical administrative permission system. This may require some new stuff in the kernel or maybe cgroups could be leveraged to implement it.
(7) Kill privileged ports. This stupid restriction is utterly antequated and serves no purpose on modern systems or networks, and it makes a ton of stuff needlessly insecure and complex by mandating 'root' to e.g. bind port 80. I wrote a rant on this years ago: http://adamierymenko.com/ports.html
(8) Implement process hibernate/restore and migration as a standard feature in the kernel (if it's not somewhere in there already... not sure). That way the 'box' can be rendered absolutely ephemeral and entire runtimes can be hot migrated between boxes.
(9) Replace numeric UID/GIDs with GUIDs or even better hashes of public keys to allow some transparent tie-in to some kind of IAM infrastructure. It's possible that this could be done by having a local mapping to numeric UIDs/GIDs to avoid having to recompile the universe and refactor code that expects UID/GID to fit in 'int' or 'long'. This way a user can log into any machine anywhere and still be the same user and all that UID/GID synchronization or LDAP or whatever trash can die.
I think that would be a start.
Some of these concepts have shown up in various places: MacOS, iOS, Android, Mosix/OpenMosix, Beowulf, various container virtualization stacks, etc. I have never seen them in one place or integrated nicely.