我从Google Cloud Platform的微服务演示开始。我很好奇当服务部署在容器中时,gRPC存根是如何工作的。
就我的理解而言,特定服务的容器由YAML配置文件中指定的服务IP寻址。所以服务的gRPC服务器必须监听服务IP?但是我遇到了下面的代码片段:
l, err := net.Listen("tcp", fmt.Sprintf(":%s", port))
if err != nil {
log.Fatal(err)
}
我想知道服务器如何在没有IP的情况下监听地址?
:{port}
不是没有ip的地址
Listen的文档包括"如果address参数中的host为空或未指定的IP地址,Listen将监听本地系统中所有可用的单播和任意播IP地址"。
因此,在这种情况下,没有主机地址,有效地址将是0.0.0.0
,对应于所有接口。人们在使用容器时常犯的一个错误是将他们的代码绑定到不能从容器外部访问的localhost
(127.0.0.1
)。
使用0.0.0.0
是一种常见的(好的)实践,特别是在使用容器时,因为它有效地将地址绑定委托给容器运行时。
所以,你的应用程序在容器内的所有接口上运行在{port}
上。然后,容器运行时将这些接口绑定(一个或多个)到主机的接口,然后你的客户端代码连接到主机的IP地址。
当你的容器由Kubernetes管理时,Kubernetes为运行你的应用程序的容器分配IP地址,这些IP地址通常暴露给使用Kubernetes服务资源的其他服务,该资源不仅有IP地址,而且有集群DNS。
- Kubernetes YAML可能指定了一个服务DNS。
- Kubernetes将DNS请求解析到选定的容器(IP和端口)
- 容器运行时将主机端口上的传入请求路由到容器端口
- 您的gRPC服务器将接受来自任何接口上的容器运行时的流量,您已经将其定义为
net.Listen
上的{port}
。