Service Discovery for Microservices with Kubernetes
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:
webapp
: Web application microservice usesgreeter
andname
microservice to generate a greeting for a person.greeter
: A microservice returns a greeting based upongreet
name/value keypair in the URL.name
: A microservice that returns a person’s name based uponid
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:
NAME_SERVICE_HOST
NAME_SERVICE_PORT
NAME_SERVICE_PATH
GREETER_SERVICE_HOST
GREETER_SERVICE_PORT
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
- 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