Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Kubernetes find services by label

I'm trying to develop a sample application using spring cloud and minikube which consist of 3 spring boot applications.

The first two are two different application (servers) which have the same endpoint but different functionality, and the third one is a client used to integrates the two other applications into one single exposed api.

I managed to deploy all three applications in minikube and managed to develop the full stack and make them communicate between each other, but now I want to go a step further and make the discovery of the two servers automatically, without hard coding the service names.

I deployed the two servers in minikube using the same label and would like to find something so that the client is able to find the services related to the two server apps automatically. This will allow expanding the application easily, so that when I add a new server to the stack the client will find it and expose it without need of any change.

Using Netflix Eureka this can be easily achieved by using something like

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

But I do no want to add an extra eureka server to the list of microservices since we are going to use kubernetes.

Is there any library which gives this functionality for kubernetes?

like image 768
Sebb77 Avatar asked Oct 29 '22 07:10

Sebb77


2 Answers

I found fabric8 library that helped me to achieve this. Still don't know if this is the correct answer, but it works :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;
}

I create the two services and added the two labels used in the code.

like image 145
Sebb77 Avatar answered Nov 15 '22 05:11

Sebb77


You can use:

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

API: GET /api/v1/namespaces/{namespace}/services with labelSelector parameter see API docs.

However be careful with dynamic service discovery inside services. As derSteve mentions in the comments below - The best practice for dependencies between services is to deploy them as logical bundles called deployments for which it is not necessary to perform discovery of previously unknown services. See this link.

like image 26
Oswin Noetzelmann Avatar answered Nov 15 '22 06:11

Oswin Noetzelmann