使用 Stork 在 Kubernetes 中进行服务发现和选择
正如我们在上一篇文章中所述,SmallRye Stork 是一个服务发现和客户端负载均衡框架,它提供了开箱即用的 Kubernetes 集成。本文将解释此集成,如何在客户端微服务中配置 Stork,以及它与传统的 Kubernetes 服务发现和负载均衡有何不同。
| 本文已更新,在配置 stork 属性时使用 quarkus.前缀。自 Quarkus 2.8 起,此前缀是必需的。 | 
Kubernetes 服务发现和负载均衡
Kubernetes 内置了服务发现和负载均衡功能。
假设您有一个部署在 Kubernetes 中的应用程序,并且公开了一个 HTTP API。您可以声明一个 Kubernetes 服务,该服务将调用委托给您的应用程序。此服务充当一组 Pod(通常是应用程序副本)前面的代理。当另一个应用程序调用我们的 HTTP API 时,它使用 DNS 来定位 Kubernetes 服务并使用解析后的地址。重要的是要理解,它定位和调用的不是应用程序实例,而是 Kubernetes 服务。然后,此服务将调用委托给实际应用程序,并在存在多个副本时实现轮循。
 
Stork 为 Kubernetes 带来了什么?
尽管 Kubernetes 内置了服务发现支持,但有时我们需要在服务实例选择方面拥有更大的灵活性。如我们所见,Kubernetes 服务实现的是轮循。使用 Stork,您可以自定义选择。
与前面的示例不同,Stork 不使用 DNS 来定位 Kubernetes 服务。它使用 Kubernetes API 来检索 Kubernetes 服务后面的 Pod 集合。然后,您可以应用任何 Stork 服务选择,甚至实现自己的选择。
下图描绘了架构以及 Stork 如何定位和选择服务实例。
 
如上图所示,Kubernetes rest-service 由两个 Pod 支持。虽然传统的 Kubernetes 服务发现会确保对 rest-service 的请求在这些 Pod 之间进行负载均衡,但 Stork 直接检索 Pod 的地址。因此,它可以处理服务选择(目前使用轮循)。
请注意,虽然使用 Stork 的应用程序不使用 Kubernetes 服务委托,但它们仍然需要 Kubernetes 服务来发现支持的 Pod。因此,这不会改变您的 Kubernetes 部署。
配置和使用 Stork Kubernetes 服务发现
在客户端,我们的 Quarkus 应用程序使用 REST Client Reactive 与 rest-service 公开的 REST API 进行交互。客户端应用程序使用 Stork 来发现 rest-service 实例。启用 Stork 的最简单方法是将相应的 Jar 添加到您项目的类路径中
    <dependency>
        <groupId>io.smallrye.stork</groupId>
        <artifactId>stork-service-discovery-kubernetes</artifactId>
    </dependency>有了 Stork 和 Stork Kubernetes Service Discovery 在类路径中,我们需要告诉 Stork 如何定位和选择服务。为此,我们只需在 Quarkus 应用程序配置中添加 stork.[service-name].[kebab-cased-property-name]。在我们的例子中,要配置 rest-service 并指示 Stork 使用 Kubernetes,我们添加
quarkus.stork.rest-service.service-discovery.type=kubernetes
quarkus.stork.rest-service.service-discovery.k8s-namespace=my-namespace请注意,您也可以通过注解配置它们,请查看 @ServiceDiscoveryType 和 @ServiceDiscoveryAttribute 注解。
我们还可以将服务查找限制在我们的命名空间内。我们也可以使用 all 值来查找所有命名空间中的服务。
我们还可以配置更多属性来调整服务发现
| 属性 | 描述 | 
|---|---|
| quarkus.stork.service-name.service-discovery.k8s-host | Kubernetes API URL | 
| quarkus.stork.service-name.service-discovery.application | 目标应用程序的名称 | 
| quarkus.stork.service-name.service-discovery.refresh-period | 服务发现缓存刷新周期 | 
| quarkus.stork.service-name.service-discovery.secure | 使用安全连接(例如 HTTPS) | 
这就是 Stork Kubernetes 服务发现的简单之处。
配置好 Stork 后,我们需要配置 REST Client 来使用它。这可以在 @RegisterRestClient 注解的接口中通过添加带有 stork:// 方案的 baseUri 属性来完成
@Path("/test")
@RegisterRestClient(baseUri = "stork://rest-service")
public interface Client {
@GET
@Path("/")
Uni<String> get();
}自定义服务选择
现在服务已定位,我们需要选择最佳实例。例如,您可以使用最少响应时间负载均衡器实现。此选择策略会监视交互并选择最快的实例以改善响应时间。
为此,您需要将负载均衡器实现添加到类路径中
<dependency>
    <groupId>io.smallrye.stork</groupId>
    <artifactId>smallrye-stork-load-balancer-response-time</artifactId>
</dependency>然后在应用程序配置中添加
quarkus.stork.my-service.load-balancer.type=least-response-time显然,您可以选择任何负载均衡策略,甚至实现自己的策略!