= Service Discovery for Microservices with Kubernetes :toc: :icons: :linkcss: :imagesdir: ../../resources/images 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 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 link:../../01-path-basics/102-your-first-cluster#create-a-kubernetes-cluster-with-eks[AWS CLI] (recommended). If you wish to create a Kubernetes cluster without EKS, you can instead use link:../../01-path-basics/102-your-first-cluster#alternative-create-a-kubernetes-cluster-with-kops[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: [.thumb] image::services.png[] . `webapp`: Web application microservice uses `greeter` and `name` microservice to generate a greeting for a person. . `greeter`: A microservice returns a greeting based upon `greet` name/value keypair in the URL. . `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: . `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 link:templates/app.yml[app.yml]. The replica set for the `webapp` service has the following environment variables: [source, yml] ---- 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: [source, yml] ---- spec: selector: app: webapp-pod ports: - name: web port: 80 type: LoadBalancer ---- Overall, the services communicate with each other as shown below: [.thumb] image::k8s-services.png[] === Deploy Application . 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 8080/TCP 13s kubernetes 100.64.0.1 443/TCP 23m name-service 100.66.113.58 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: Annotations: 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:// http://?greet=ho http://?id=1 http://?greet=ho&id=1 `` 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 You are now ready to continue on with the workshop! :frame: none :grid: none :valign: top [align="center", cols="2", grid="none", frame="none"] |===== |image:button-continue-standard.png[link=../../03-path-application-development/303-app-update] |image:button-continue-developer.png[link=../../03-path-application-development/303-app-update] |link:../../standard-path.adoc[Go to Standard Index] |link:../../developer-path.adoc[Go to Developer Index] |=====