【问题标题】:Java - Kubernetes find services by labelJava - Kubernetes 按标签查找服务
【发布时间】:2017-10-26 06:52:22
【问题描述】:

我正在尝试使用 spring cloud 和 minikube 开发一个示例应用程序,其中包含 3 个 spring boot 应用程序。

前两个是两个不同的应用程序(服务器),它们具有相同的端点但功能不同,第三个是一个客户端,用于将其他两个应用程序集成到一个公开的 api 中。

我设法在 minikube 中部署了所有三个应用程序,并设法开发了完整的堆栈并使它们相互通信,但现在我想更进一步,自动发现两个服务器,而无需硬编码服务名称。

我在 minikube 中使用相同的标签部署了两个服务器,并希望找到一些东西,以便客户端能够自动找到与两个服务器应用程序相关的服务。这将允许轻松扩展应用程序,因此当我将新服务器添加到堆栈时,客户端将找到它并将其公开,而无需任何更改。

使用 Netflix Eureka,这可以通过使用类似的东西轻松实现

discoveryClient.getInstances("service-name").forEach((ServiceInstance s)

但我不想在微服务列表中添加额外的 eureka 服务器,因为我们将使用 kubernetes。

是否有任何库为 kubernetes 提供此功能?

【问题讨论】:

    标签: java spring-boot kubernetes spring-cloud microservices


    【解决方案1】:

    我找到了帮助我实现这一目标的 fabric8 库。 仍然不知道这是否是正确的答案,但它有效:D

    https://github.com/fabric8io/kubernetes-client/tree/master/kubernetes-client

    @RequestMapping("/")
    private String getResponse() {
        String ret = "hello from Client L0L!!!\n";
    
        //Config config = new ConfigBuilder().withMasterUrl("https://mymaster.com").build();
        //KubernetesClient client = new DefaultKubernetesClient(config);
        KubernetesClient client = new DefaultKubernetesClient();
    
    
        ServiceList services = client.services().withLabel("APIService").list();
        Service server = null;
        log.warn("---------------------------------------------->");
        for (Service s : services.getItems()) {
            log.warn(s.getMetadata().getName());
            log.warn(s.toString());
            if (s.getMetadata().getLabels().containsKey("ServiceType") && s.getMetadata().getLabels().get("ServiceType").equals("server"))
                server = s;
        }
    
        log.warn("---------------------------------------------->");
    
        String s = "";
        if (server != null) {
            RestTemplate t = new RestTemplate();
            String url = "http://" + server.getMetadata().getName() + ":" + server.getSpec().getPorts().get(0).getPort() + "/";
            log.warn("Contacting server service on: " + url);
            s = t.getForObject(url, String.class);
            log.warn("Response: " + s);
        } else {
            log.warn("Didn't find service with label ServiceType=server!!!");
        }
    
        return ret + " - " + s;
    }
    

    我创建了两个服务并添加了代码中使用的两个标签。

    【讨论】:

      【解决方案2】:

      你可以使用:

      CLI:kubectl get services --selector=YOUR-LABEL-NAME.

      API:GET /api/v1/namespaces/{namespace}/serviceslabelSelector 参数参见 API docs

      但是要小心服务内部的动态服务发现。正如 derSteve 在下面的 cmets 中提到的 - 服务之间依赖关系的最佳实践是将它们部署为称为 deployments 的逻辑捆绑包,无需执行对以前未知服务的发现。请参阅此link

      【讨论】:

      • 我知道 cli 和 api,但是有没有一个 java 库可以做到这一点并转换为 spring 云服务?
      • 最简单的是从你的spring云服务调用API?为什么需要 java 库?
      • 应用程序不应该知道它在其中运行的环境——这意味着调用 kubernetes api 从消费服务中检索服务的实际 URL 违反了这一点,并使应用程序知道它们的环境。
      • @derSteve:这当然是一个很好的原则,但是 OP 专门询问如何使用 kubernetes 发现以前未知的服务。如果他在他自己的服务或部署基础设施中包含这部分逻辑似乎不在问题的范围内。但是,我在答案中添加了关于 kubernetes 中服务依赖项的最佳实践的句子。
      猜你喜欢
      • 2020-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 2014-07-29
      • 2020-05-13
      相关资源
      最近更新 更多