Service Discovery for Microservices with Kubernetes

Preetham Umarani
3 min readAug 2, 2022

Table of Contents

  • Prerequisites
  • Application Architecture
  • Deploy Application
  • Access Application
  • Delete Application

This chapter shows an example of how different microservices within an application can use service discovery to locate each other in the infrastructure rather than via hardcoded IP addresses.

Prerequisites

To perform exercises in this chapter, you’ll need to deploy configurations to a Kubernetes cluster. To create an EKS-based Kubernetes cluster, use the AWS CLI (recommended). If you wish to create a Kubernetes cluster without EKS, you can instead use kops.

All configuration files for this chapter are in the microservices directory. Make sure you change to that directory before giving any commands in this chapter.

Application Architecture

The sample application uses three services:

  1. webapp: Web application microservice uses greeter and name microservice to generate a greeting for a person.
  2. greeter: A microservice returns a greeting based upon greet name/value keypair in the URL.
  3. name: A microservice that returns a person’s name based upon id name/value keypair in the URL.

These services are built as Docker images and deployed in Kubernetes. All services are built as Node.js applications. The source code for the services is at https://github.com/arun-gupta/container-service-discovery/tree/master/services.

The webapp service needs to be configured with the environment variables below to communicate with the name and greeter services. The NAME_SERVICE_HOST and GREETER_SERVICE_HOST environment variables refer to these services by their labels rather than by static references like pod or host IP addresses. The benefit is that if an existing name and/or greeter a pod is no longer operable, the webapp service will continue to function if there are sufficient resources in the cluster to continue running the services it depends on:

  1. NAME_SERVICE_HOST
  2. NAME_SERVICE_PORT
  3. NAME_SERVICE_PATH
  4. GREETER_SERVICE_HOST
  5. GREETER_SERVICE_PORT
  6. GREETER_SERVICE_PATH

The configuration file with three different services is defined at app.yml.

The replica set for the webapp service has the following environment variables:

spec:
containers:
- name: webapp-pod
image: arungupta/webapp-service:latest
env:
- name: NAME_SERVICE_HOST
value: name-service
- name: NAME_SERVICE_PORT
value: "8080"
- name: NAME_SERVICE_PATH
value: /
- name: GREETER_SERVICE_HOST
value: greeter-service
- name: GREETER_SERVICE_PORT
value: "8080"
- name: GREETER_SERVICE_PATH
value: /

The environment variables point to the name and greeter service as defined in the application configuration.

An ingress load balancer for webapp service is created by using the following fragment:

spec:
selector:
app: webapp-pod
ports:
- name: web
port: 80
type: LoadBalancer

Overall, the services communicate with each other as shown below:

Deploy Application

  1. Deploy the application:
$ kubectl create -f templates/app.yml

2. Get the list of services:

$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
greeter-service 100.64.44.23 <none> 8080/TCP 13s
kubernetes 100.64.0.1 <none> 443/TCP 23m
name-service 100.66.113.58 <none> 8080/TCP 13s
webapp-service 100.71.126.195 a5427e1288472... 80:31234/TCP 12s

3. Get more details about the service:

$ kubectl describe svc/webapp-service
Name: webapp-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=webapp-pod
Type: LoadBalancer
IP: 100.71.126.195
LoadBalancer Ingress: a5427e128847211e782280a896fc2bfc-283874069.us-east-1.elb.amazonaws.com
Port: web 80/TCP
NodePort: web 31234/TCP
Endpoints: 100.96.2.12:80
Session Affinity: None
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
30s 30s 1 service-controller Normal CreatingLoadBalancer Creating load balancer
29s 29s 1 service-controller Normal CreatedLoadBalancer Created load balancer

Wait for ~3 mins for the load balancer to accept the request.

Access Application

Access the application using the following URLs with curl or via a browser:

http://<host>
http://<host>?greet=ho
http://<host>?id=1
http://<host>?greet=ho&id=1

<host> is the value of the ingress load balancer’s address:

$ kubectl get svc/webapp-service -o jsonpath={.status.loadBalancer.ingress[0].hostname}
a5427e128847211e782280a896fc2bfc-283874069.us-east-1.elb.amazonaws.com

Delete Application

Delete the application with this command:

$ kubectl delete -f templates/app.yml

--

--