kubernetes中的微服务发现服务

时间:2020-06-08 17:19:47

标签: kubernetes microservices service-discovery

最近,我已经阅读了很多有关微服务和kubernetes的文章,并且还尝试了这两种技术。 我知道k8中可用的不同组件,例如pod,服务,部署... 我还知道服务可以是ClusterIP类型,以限制到群集内的连接。

假设我们有10个微服务,每个微服务都使用某种http服务器来公开其功能。基本上每个微服务都是一个REST API。 用kubernetes来讲,这是一个由Pod管理的容器,并且会有一个服务来管理此Pod的连接。

我的问题如下: 如果您未使用像Spring这样的利用Eureka的框架,例如每个微服务中的裸骨golang http服务器。每个服务如何在不将服务名称和端口号传递给每个微服务的情况下找到另一个服务。

例如: 假设服务A在端口8080上公开,需要调用服务B在端口8081上公开,而另一个服务在端口8082上运行;这意味着我们需要将端口作为环境变量传递给服务A ...您可以清楚地看到,当服务数量增加时,将很难维护所有这些环境变量。

人们如何解决这个问题?他们是否使用某种集中式服务注册表?如果是,那么该服务注册表将如何与kubernetes服务集成?

预先感谢

更新

提供的可接受答案带有解释,我看不到的是,例如在kubernetes中,通常每个部署对象都有其自己的IP地址,因此可以为每个微服务使用相同的端口号

如果有人对简单/虚拟微服务示例感兴趣,那么我整理了一个可以在带有minikube的本地kubernetes集群上运行的小项目。

https://github.com/fouadkada/simple_microservice_example

2 个答案:

答案 0 :(得分:3)

我了解到,说服务就是微服务, 但是为了避免歧义,首先我想定义一些东西。当我说 service 时,我指的是k8s服务。当我说应用程序时,是指在pod中运行的应用程序。

现在您的问题:

每个服务如何在不将服务名称和端口号传递给每个微服务的情况下找到另一个服务

在kubernetes中,有一个服务概念(link to docs)。 每个服务都在k8s dns服务器(通常是CoreDNS)中注册。您可以将这些服务的名称用作常规FQDN。


比方说,服务A在端口8080上公开,需要调用在端口8081上公开的服务B,以及在端口8082上运行的另一个服务;这意味着我们需要将端口作为环境变量传递给服务A。

正如@sachin已经正确提到的那样,通常不会因为每个应用程序都对每个应用程序使用不同的端口。 最好使用Porst来了解特定端口上可以使用的应用程序类型。例如当您看到端口80时,几乎可以确定它是HTTP服务器。当您看到6379时,可以确定它的redis等。

Kubernetes networking model上的k8s文档中,您可以找到:

每个Pod都有自己的IP地址。这意味着您无需在Pod之间显式创建链接,并且几乎不需要处理将容器端口映射到主机端口的问题。这将创建一个干净的,向后兼容的模型,从端口分配,命名,服务发现,负载平衡,应用程序配置和迁移的角度来看,可以将Pod像VM或物理主机一样对待。


您可能不了解的最后一件事是,当k8s启动pod时,一些有关已经存在的服务的信息会通过环境变量传递。您可以自己检查;只需执行set到任何Pod即可查看所有环境变量。

以下是示例输出(我删除了不重要的部分):

KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443

但是请注意,这些环境变量是仅在与您的应用程序相同的名称空间中列出的服务,并且仅列出在创建pod时存在的服务。容器启动后创建的任何内容都不会反映在环境中。


总结并回答您的问题:

人们如何解决这个问题?

人们使用DNS(每个k8s群集中都存在)和静态端口(不会随机更改的端口)。

当然也有类似Consul的解决方案,但k8的即用功能足以满足90%以上的用例。

答案 1 :(得分:1)

我假定该应用程序具有一些与库伯内特通信的客户端库,该库具有服务发现功能。每个应用程序都被Kubernetes服务暴露给kuberenetes中的其他应用程序。

不是为每个微服务提供单独的端口,而是为每个应用程序提供相同的端口,例如:8080。然后将您的应用程序正确映射到Kubernetes服务对象。之后,您可以轻松地使用http://your-kubernetes-service-name:8080调用其他微服务进行通信。

基本上,如果您的Pod每个Pod只包含一个容器,则无需为不同的服务传递不同的端口号。建议最佳做法是每个吊舱运行一个容器。