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.
In order 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.
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 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 application. 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
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 the application:
$ kubectl create -f templates/app.yml
-
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
-
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 request.
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 the application with this command:
$ kubectl delete -f templates/app.yml
You are now ready to continue on with the workshop!