Why do we need Service Discovery?
Kubernetes deploys applications through Pods. Pods can be placed on different hosts (nodes), scaled up by increasing their number, scaled down by killing the excess ones, and moved from one node to another. All those dynamic actions must occur while ensuring that the application remains reachable at all times. To address this critical requirement, we use the Service Discovery pattern. To understand service discovery, let’s briefly visit the Service Discovery Architecture (SOA).
In a microservices design, the application is broken down into a number of components, where each component is responsible for a specific role. Different components must communicate with each other using network protocols (for example, HTTP). So, imagine that a client component (consumer) needs to send an HTTP message to service (producer). If there’s only one instance of the producer, the solution is straightforward: place the producer connection information (like the IP address or DNS name, the protocol, and the port) in a configuration file for the client to use. However, to achieve high availability, there’s often more than one instance of a particular service available. In this case, the client cannot just hook itself to one of the producers. If this service instance was deleted or renamed, the client loses connectivity and part of the application breaks. Hence, the client needs some way to discover which service instance is healthy and available to that it can connect to it. So, back to SOA, there are two ways for a client to discover services:
Client-side discovery: in this mode, the client is responsible for determining which service instance it should connect to. It does that by contacting a service registry component, which keeps records of all the running services and their endpoints. When a new service gets added or another one dies, the Service Registry is automatically updated. It is the client’s responsibility to load-balance and distribute its request load on the available services.
Server-side discovery: in this mode, a load-balancing layer exists in front of the service instances. The client connects to the well-defined URL of the load balancer and the latter determines which backend service it shall route the request too.