I was starting with the Google Cloud Platform's microservice demo. And I was curious how gRPC stubs work when the services are deployed in containers.
As far as my understanding goes, the container of a particular service are addressed by the Service IP specified in the YAML configuration file. So the gRPC server of a service must listen at the service IP? But I came across the following snippet of code:
l, err := net.Listen("tcp", fmt.Sprintf(":%s", port))
if err != nil {
log.Fatal(err)
}
I am wondering how does the server listen to an address without an IP?
CodePudding user response:
:{port}
isn't an "address without an IP".
The documentation for Listen includes "if the host in the address parameter is empty or a literal unspecified IP address, Listen listens on all available unicast and anycast IP addresses of the local system".
So, in this case, without a host address, the effective address would be 0.0.0.0
which corresponds to all interfaces. Corollary a common mistake people make when using containers is to bind their code to localhost
(127.0.0.1
) which cannot be accessed from outside the container.
Using 0.0.0.0
is a common (good) practice, particularly when using containers, as it effectively delegates address binding to the container runtime.
So, your app runs on {port}
on all interfaces within the container. The container runtime then binds (one of more of) these interfaces to the host's interface(s) and your e.g. client code connects to the host's IP address.
When your container is being managed by Kubernetes, Kubernetes assigns IP address(es) to the containers running your app and these are often exposed to other services using a Kubernetes Service resource which not only has an IP address but also a cluster DNS.
- The Kubernetes YAML probably specifies a Service DNS.
- Kubernetes resolves requests to the DNS name to a selected container (IP and port)
- The container runtime routes incoming requests on the host's port to the container's port
- Your gRPC server will accept traffic from the container runtime on any interface that's on the
{port}
that you've defined it tonet.Listen
on.
CodePudding user response:
It listens to localhost
by default.