(2) Building on (1), SkyDNS allows pods to be named.
(3) Building on (2), we can define Services that are dynamically selected from pods. That means if I have a pod that depends on another pod, I can instead have it depend upon a Service. The individual pods that make up the Service can come up or go down, allowing updates and maintenance to be decoupled.
Those are the basics. Note that, I remember seeing a presentation from the Docker folks debating whether they should implement something like this. The idea is too useful not to use.
This is sufficiently useful to run a single-node kubelet on your dev machine instead of using Docker Compose on your dev machine. Compose will still be OK if you are only working with a single microservice/app. When that n > 1, that's when the pods and services of K8S start making a lot more sense.