Service discovery with microservices in kubernetes Service discovery with microservices in kubernetes kubernetes kubernetes

Service discovery with microservices in kubernetes


I understand that by saying service you mean microservice,but to avoid ambiguity, first I would like to define some things. When I say service I am refering to k8s service. When I say application I am refering to application running in pod.

Now your questions:

How does each service find the other service without passing the service name and port number to each microservice

In kubernetes there is a concept of services (link to docs).Each service is registered in k8s dns server (typically CoreDNS). You can use names of these services as regular FQDN.


Let's say Service A is exposed on port 8080 which needs to call Service B which is exposed on port 8081 and another service which is running on port 8082; this means that we need to pass the ports as environment variables to Service A.

As @sachin already mentioned correctly, you don't typically use different ports for every application just beacuse you can.Porst are good to use to know what type of application you can expect on specific port. e.g. when you see port 80 it is almost certain it's HTTP server. When you see 6379 you can be pretty sure its redis etc.

In k8s documentation on Kubernetes networking model you can find:

Every Pod gets its own IP address. This means you do not need to explicitly create links between Pods and you almost never need to deal with mapping container ports to host ports. This creates a clean, backwards-compatible model where Pods can be treated much like VMs or physical hosts from the perspectives of port allocation, naming, service discovery, load balancing, application configuration, and migration.


One last thing you may have not known about is that when k8s starts a pod some information about already existing services is passed through environment variables. You can check it yourself; just exec to any pod an run set to see all environment variables.

Here is example output (I removed unimportant part):

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

But please notice that these environment variables are services listed only within the same namespace as your application and only those that existed then creating the pod. Anything created after container started will not be reflected in envs.


To summarize and answer your question:

How do people solve such a problem?

People use DNS (existing on every k8s cluster) and static ports (ports that don't change randomly).

Of course there are solutions like Consul, but out of the box functionality of k8s is sufficient for 90%+ usecases.


I assume the application has some client library to communicate with kubernetes which has service discovery capability.Each application is exposed to other applications in kuberenetes by Kubernetes services.

Instead of giving each microservices a seperate port , give same port for each application eg:8080. Then correctly map your application to the Kubernetes service object.After that, you can easily call other microservices with http://your-kubernetes-service-name:8080 to communicate.

Basically if your pod contains only one container per pod, you need not pass different port numbers for different services. Its recommended to run one container per pod as a best practice.