In Go, that looks like this:
http.ListenAndServe(":80", nil)
The above code will bind to all TCP interfaces. Since Kubernetes does support dual-stack IPv4 & IPv6 our services should bind to all interfaces (we do not currently have IPv6 services).
If you must specify an ip address to expose your service on, choosing 0.0.0.0:port is typically a good choice. What this does can be OS and platform-specific.
Binding to localhost:port or 127.0.0.1:port is binding to a local-only interface that constrained to the same "host". In Kubernetes, other containers within the Pod may still communicate with this service AND you may port-forward this container and associated service
(Why?).
This may be preferred in a sidecar pattern where you do not want a container accessible outside a Pod or when you don't want expose your laptop to the cofeeshop wifi but generally, code should not be merged that binds to localhost or 127.0.0.1.
Due to the way that kube-proxy works when you port-forward a pod or a service kube-proxy opens a tunnel to that pod (or a pod that backs that service). This can make debugging why a service is accessible in the pod but not outside of the pod hard to understand.
You can also use kubectl port-forward --address 0.0.0.0 if you need to expose a port-forwarded service outside of your local machine (it defaults to 127.0.0.1). link 🤯
We also have CI test for this here
- https://stackoverflow.com/questions/20778771/what-is-the-difference-between-0-0-0-0-127-0-0-1-and-localhost
- https://serverfault.com/questions/21657/semantics-of-and-0-0-0-0-in-dual-stack-oses/39561#39561
- https://stackoverflow.com/questions/49067160/what-is-the-difference-in-listening-on-0-0-0-080-and-80