Whether anything is better or worse depends on so many factors that no answer is possible. I would say that most production clouds use physical servers for all nodes, but there may be situations where virtual nodes are feasible and make sense.
Using virtual machines for compute nodes would be extremely odd. I can't think of a use case.
Running all or some of the controller functionality on virtual machines could be useful for a small cloud. For example, see this ask.openstack.org question. Advantage: It makes it easier to separate services such as message queue, database, etc. Important factors are high availability and performance.
Red Hat discouraged virtual controllers for their overcloud as of a year ago. I don't think that has changed. On the other hand, Red Hat's undercloud can be virtual.
You may think of containers as a kind of virtual machines. Containerized OpenStack services seem to be all the rage now; see Kolla, OpenStack-Ansible or containerized TripleO. I don't know whether this is used in production yet.