Discovering Services

Discovering services using DNS and environment variables#

Services can be discovered through two principal modes:

  • Environment variables
  • DNS

Every Pod gets environment variables for each of the active Services. They are provided in the same format as what Docker links expect, as well with the simpler Kubernetes-specific syntax.

Let’s take a look at the environment variables available in one of the Pods we’re running i.e. go-demo-2-db.

Let's get environment variables for go-demo-2-db

Find environment variable of pod 'go-demo-2-db'

The output, limited to the environment variables related to the go-demo-2-db service, is as follows.

Output of above command

The first five variables are using the Docker format. If you already worked with Docker networking, you should be familiar with them. At least, if you’re familiar with the way Swarm (standalone) and Docker Compose operate. Later version of Swarm (Mode) still generate the environment variables but they are mostly abandoned by the users in favour of DNSes.

The last two environment variables are Kubernetes specific and follow the [SERVICE_NAME]_SERVICE_HOST and [SERVICE_NAME]_SERIVCE_PORT format (service name is upper-cased).

No matter which set of environment variables you choose to use (if any), they all serve the same purpose. They provide a reference we can use to connect to a Service and, therefore to the related Pods.

Things will become more evident when we describe the go-demo-2-db Service.

Describe service 'go-demo-2-db'

The output is as follows.

Details of service 'go-demo-2-db'

The key is in the IP field. That is the IP through which this service can be accessed and it matches the values of the environment variables GO_DEMO_2_DB_* and GO_DEMO_2_DB_SERVICE_HOST.

The code inside the containers that form the go-demo-2-api Pods could use any of those environment variables to construct a connection string towards the go-demo-2-db Pods. For example, we could have used GO_DEMO_2_DB_SERVICE_HOST to connect to the database. And, yet, we didn’t do that. The reason is simple. It is easier to use DNS instead.

Let’s take another look at the snippet from the go-demo-2-api-rs.yml ReplicaSet definition.

Selected output of 'kubectl describe svc go-demo-2-api-rs.yml'

We declared an environment variable with the name of the Service (go-demo-2-db). That variable is used by the code as a connection string to the database.

Kubernetes converts Service names into DNSes and adds them to the DNS server.

Sequential breakdown of the process#

Let’s go through the sequence of events related to service discovery and components involved.

  1. When the api container go-demo-2 tries to connect with the go-demo-2-db Service, it looks at the nameserver configured in /etc/resolv.conf. kubelet configured the nameserver with the kube-dns Service IP (10.96.0.10) during the Pod scheduling process.

  2. The container queries the DNS server listening to port 53. go-demo-2-db DNS gets resolved to the service IP 10.0.0.19. This DNS record was added by kube-dns during the service creation process.

  3. The container uses the service IP which forwards requests through the iptables rules. They were added by kube-proxy during Service and Endpoint creation process.

  4. Since we only have one replica of the go-demo-2-db Pod, iptables forwards requests to just one endpoint. If we had multiple replicas, iptables would act as a load balancer and forward requests randomly among Endpoints of the Service.

Service discovery process and components involved
Service discovery process and components involved

Destroying Everything#

We have exhausted this topic and the time has come to destroy everything we did so far. Use the following command to delete the cluster to start afresh for the next chapter.

Delete k3d Cluster

Try it yourself#

A list of commands used in this lesson is given below.

Commands used in this lesson

You can practice the commands in the following code playground by pressing the Run button and waiting for the cluster to set up.

/
go-demo-2.yml
Discover Services
Defining Multiple Objects in the Same YAML file
Comparison with Docker Swarm
Mark as Completed
Report an Issue