Every Pod gets his own IP address, containers within that pod share that IP address and can communicate freely with each other in the cluster. Why? Because the IP addresses are preserved across the pod network.
The restriction or let's said network isolation is being handled by the network policies. These policies determine what each pod can communicate with.
So at the end of the story pods can be considered like VMs or hosts, in that they all have a unique IP address.
Due to the fact that Kubernetes has limited and very basic built-in network support called kubenet, it is common to use third-party networking implementations that plug into Kubernetes using the Container Network Interface (CNI API).
There are different kinds of CNI plugins and they can be chained together.