Kubernetes Service Discovery Guide


Kubernetes services help applications running in Kubernetes clusters to communicate. A service helps manage internal and external traffic to pods through IP addresses, ports, and DNS records. Service discovery is the process of connecting to a pod’s service.

This article explains what Kubernetes service discovery is and provides an implementation example.

Kubernetes Service Discovery Guide


Note: Kubernetes deployments quickly become complex.

phoenixNAP’s Bare Metal Cloud integrates Rancher as a solution, enabling one-click deployments. Check out how to set up cluster management on BMC using Rancher.

What is Service Discovery in Kubernetes?

Service discovery refers to the process of connecting to a Kubernetes service. Services provide Pods with a network connection, making them discoverable.

Pods represent the basic building block of Kubernetes and are a collection of containers that can move across nodes. Kubernetes assigns each pod with an internal IP address once deployed. A pod’s internal IP changes over time due to the movement, creation, and destruction across nodes.

A service binds to Kubernetes deployment pods, creating a DNS service inside the cluster and HTTP endpoints for service discovery. Although the IPs change, the HTTP endpoints remain the same.

Below is an example implementation of service discovery in Kubernetes.

How Does Service Discovery Work in Kubernetes?

This example uses Minikube to deploy a single-node cluster of a simple hello-kubernetes web app.

To start Minikube, run the following command in the terminal:

minikube start
minikube start cluster terminal output

Follow the steps below to see how service discovery works in Kubernetes.

1. Create Namespaces

The example infrastructure consists of two namespaces for development and production.

1. Create a namespace YAML file for development:

nano development-namespace.yml

2. Add the following code to the file:

apiVersion: v1
kind: Namespace
  name: development

3. Save the file and close nano (CTRL+XYEnter).

4. Create the namespace with:

kubectl apply -f development-namespace.yml
Namespace development created terminal output

A message appears confirming the namespace creation.

Repeat the same steps for the production namespace. Change the file name to production-namespace.yml and set the name in metadata to production.

5. To confirm both namespaces are active, run:

kubectl get namespaces
development and production namespaces list terminal output

The output shows the development and production namespaces on the list as Active.

2. Create Kubernetes Deployment

Deploy the example hello-kubernetes application in both namespaces.

1. Create an app deployment YAML configuration file:

nano app-deployment-development.yml

2. Add the following configuration:

apiVersion: apps/v1
kind: Deployment
  name: hello
  namespace: development
  replicas: 2
      app: hello
        app: hello
      - name: hello-kubernetes
        image: paulbouwer/hello-kubernetes:1.5
        - containerPort: 8080

The deployment consists of two pod replicas.

3. Save and close the file.

4. Apply the deployment configuration with:

kubectl apply -f app-deployment-development.yml
app deployment development hello created terminal output

The output confirms the hello deployment creation.

Repeat the deployment steps for the production namespace. Change the file name to app-deployment-production.yml and replace the metadata namespace name with production.

5. Confirm the two deployments are ready with:

kubectl get deployments --all-namespaces
development and production deployment list terminal output

The output shows the hello deployment on development and production namespaces.

3. Ping Pods

To verify the IP addresses work inside the cluster, create a temporary pod in the default namespace for running essential utility commands:

1. Create a busybox.yml configuration file:

nano busybox.yml

2. Add the following configuration:

apiVersion: v1
kind: Pod
  name: busybox
  namespace: default
  - image: busybox:1.28
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always

The busybox pod contains basic shell utilities, such as ping, nslookup, wget, etc.

3. Save the file and close.

4. Apply the file to create the pod:

kubectl apply -f busybox.yml
busybox pod created terminal output

The command creates the pod and applies the configuration.

5. Check the IP addresses of the nodes with:

kubectl get pod -o wide --namespace=development
kubectl get pod -o wide --namespace=production
Pods IP addresses terminal output

The output shows two addresses per pod (one for each node). Use any of the addresses for the following step.

6. Ping the address from the busybox pod in the default namespace with:

kubectl exec -it busybox -- ping <address>
busybox ping pod response terminal output

Replace <address> with the actual address from one of the pods. The ping command works within the cluster, confirming the pod address is correct.

Running nslookup does not resolve to a hostname:

kubectl exec -it busybox -- nslookup <address>
pod nslookup no hostname resolution terminal output

When deploying again, the application changes these addresses. A service helps create a stable endpoint, which makes service discovery straightforward.

4. Create Services

Creating services for the namespaces helps expose the addresses, allowing access from the web. To create a service for development and production, do the following:

1. Create a service file for the development deployment:

nano app-service-development.yml

2. Add the following code:

apiVersion: v1
kind: Service
  name: hello
  namespace: development
  type: LoadBalancer
  - port: 80
    targetPort: 8080
    app: hello

The service connects to the development namespace for the hello deployment on port 80. The service type is LoadBalancer.

Note: Other service types include ClusterIP, NodePort, and ExternalName.

3. Save the file and close.

4. Apply the service with:

kubectl apply -f app-service-development.yml
development service hello app created terminal output

The output prints a confirmation. Repeat the steps for the production deployment.

5. To view the services, enter:

kubectl get services --all-namespaces
get services no external IP terminal output

The output shows the hello deployment on development and production namespaces. Both are LoadBalancer types with a set cluster internal address. Connecting using the internal address automatically load balances the requests between two pods.

The external address is <pending> until exposed.

5. Expose the Service

To expose the service on the internet, do the following:

1. In another terminal tab, expose the services to the internet with:

sudo minikube tunnel
sudo minikube tunnel terminal output

Enter the password and leave the tab running.

2. Each service receives an external IP address. Check the IP addresses with:

kubectl get services --all-namespaces
services external IP addresses terminal output

The IP addresses expose the service to the internet, creating an HTTP endpoint and a DNS service.

3. Run nslookup on either address to see the name resolution:

kubectl exec -it busybox -- nslookup
pod nslookup hostname resolution terminal output

The address resolves to hello.development.

4. View the service in the browser by accessing the address.

hello kubernetes app browser

Accessing the address via port 80 also resolves to the same page.

Alternatively, use wget:

kubectl exec -it busybox -- wget -O - http://hello.development sh
wget hello.development response

The hello.development page resolves to the address and fetches the contents.


After going through this guide, you know what service discovery is in Kubernetes. The example helps demonstrate how service discovery functions and what Kubernetes does behind the scenes.

Đăng ký liền tay Nhận Ngay Bài Mới

Subscribe ngay

Cám ơn bạn đã đăng ký !

Lỗi đăng ký !

Add Comment

Click here to post a comment

Đăng ký liền tay
Nhận Ngay Bài Mới

Subscribe ngay

Cám ơn bạn đã đăng ký !

Lỗi đăng ký !