gRPC如何获取微服务的服务IP地址?

huangapple go评论98阅读模式
英文:

How does gRPC know service ip addresses for Microservices

问题

我正在使用Google Cloud Platform的微服务演示进行开发。我很好奇当服务部署在容器中时,gRPC存根是如何工作的。

据我理解,特定服务的容器由YAML配置文件中指定的服务IP进行寻址。所以一个服务的gRPC服务器必须监听该服务的IP地址?但是我在以下代码片段中遇到了以下代码:

l, err := net.Listen("tcp", fmt.Sprintf(":%s", port))
if err != nil {
	log.Fatal(err)
}

我想知道服务器如何在没有IP的情况下监听一个地址?

英文:

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?

答案1

得分: 5

:{port} 不是一个“没有 IP 地址”的地址。

Listen 的文档中包含了“如果地址参数中的主机为空或为未指定的 IP 地址文字,Listen 将监听本地系统上所有可用的单播和任播 IP 地址”的说明。

因此,在这种情况下,没有主机地址,有效地址将是 0.0.0.0,对应于所有接口。因此,当使用容器时,人们常犯的一个错误是将代码绑定到 localhost (127.0.0.1),这无法从容器外部访问。

使用 0.0.0.0 是一种常见(好的)做法,特别是在使用容器时,因为它有效地将地址绑定委托给容器运行时。

因此,你的应用在容器内的所有接口上运行 {port}。容器运行时然后将这些接口(其中一个或多个)绑定到主机的接口,并且你的客户端代码连接到主机的 IP 地址。

当你的容器由 Kubernetes 管理时,Kubernetes 会为运行你的应用的容器分配 IP 地址,并且通常使用 Kubernetes Service 资源将其暴露给其他服务,该资源不仅具有 IP 地址,还具有集群 DNS。

  1. Kubernetes YAML 可能指定了一个 Service DNS。
  2. Kubernetes 将请求解析到 DNS 名称,并选择一个容器(IP 和端口)。
  3. 容器运行时将主机端口上的传入请求路由到容器的端口。
  4. 你的 gRPC 服务器将接受来自容器运行时在你定义为 net.Listen{port} 上的 任何 接口的流量。
英文:

:{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.

  1. The Kubernetes YAML probably specifies a Service DNS.
  2. Kubernetes resolves requests to the DNS name to a selected container (IP and port)
  3. The container runtime routes incoming requests on the host's port to the container's port
  4. Your gRPC server will accept traffic from the container runtime on any interface that's on the {port} that you've defined it to net.Listen on.

huangapple
  • 本文由 发表于 2023年1月13日 00:00:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75099097.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定