Skip to content

Latest commit

 

History

History
 
 

microservices

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Service Discovery for Microservices with Kubernetes

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

This chapter uses a cluster with 3 master nodes and 5 worker nodes as described here: multi-master, multi-node gossip based cluster.

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:

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 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 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:

  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:

k8s services

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 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