Kubernetes Headless Service
Tags: kubernetesadvanced
Published: 2021-10-02 16:32:10

---
title: Kubernetes Headless Service
published: true
date: 2021-10-02 08:27:37 UTC
tags: kubernetesadvanced
canonical_url: https://krzwiatrzyk.eu/kubernetes-headless-service/
---

<iframe width="100%" height="80" title="Spotify Embed: Funnel Of Love" frameborder="0" allowfullscreen allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" src="https://open.spotify.com/embed/track/2klYSnu3sbZhoQ6g28aSsj?si=a2751e27b7bf4845"></iframe>

* * *

## What is a headless service?
 ![Kubernetes Headless Service](https://krzwiatrzyk.eu/content/images/2021/10/Screenshot_8.png)

A **headless service** is a Kubernetes Service without _ClusterIP._

## What is the difference between headless service and normal service?

First, let's see the differences between **headless** and **headful** service.

![Kubernetes Headless Service](https://krzwiatrzyk.eu/content/images/2021/10/image-2.png)

> NOTE: Originally, there isn't something like "headful" service in Kubernetes nomenclature. It is used in this article to differentiate services.

After creating both services, it is visible that **ClusterIP** was not set for **headless** service.

![Kubernetes Headless Service](https://krzwiatrzyk.eu/content/images/2021/10/obraz_2021-10-02_103514.png)

I have 3 containers (called _test-\*_) that will be included in **headless** and **headful** services.

![Kubernetes Headless Service](https://krzwiatrzyk.eu/content/images/2021/10/image-1.png)

First, let's check (with usage of **dnsutils** pod) what addresses will be returned from DNS for particular services.

![Kubernetes Headless Service](https://krzwiatrzyk.eu/content/images/2021/10/image-8.png)

Can you see the difference? If **ClusterIP** is set, then only one IP address is returned in answer, thus load balancing is done by the cluster itself. However, if **ClusterIP** is empty, addresses of all available endpoints are returned, allowing the application to know and decide which target instance to connect to.

## Another approach with StatefulSets

With **StatefulSets** you can achieve the same behavior as with **headless** service by specifying _spec.serviceName_ field (headful or headless, doesn't matter).

I have created a **StatefulSet** with 3 pods (_test-\*_).

![Kubernetes Headless Service](https://krzwiatrzyk.eu/content/images/2021/10/image-9.png)

And pointed a **headful** service in the spec.

![Kubernetes Headless Service](https://krzwiatrzyk.eu/content/images/2021/10/image-10.png)

Now, it is possible to resolve specific pods in this service (this is not normally possible).

![Kubernetes Headless Service](https://krzwiatrzyk.eu/content/images/2021/10/image-14.png)

That's great, you can create an application that can connect to particular instances by name of the pod.

Drawback? Somehow, your client must know how many instances of the target application are there.

## Headless service with StatefulSet

If **StatefulSet** has specified _spec.serviceName_ field and targeted a **headless** service, then DNS discovery can be used for getting the number of instances available (i.e. 3) and then using the above solution to connect (i.e.: _test-0.headful, test-1.headful, test-3.headful_).

Where this is useful? One of the best examples is Kafka, where sometimes a particular topic's partition leader is on a different broker than the application connected to. Check the diagram below.

![Kubernetes Headless Service](https://krzwiatrzyk.eu/content/images/2021/10/Kafka-Topic-Partition.drawio--2-.png)