What is a headless service, what does it do/accomplish, and what are some legitimate use cases for it?

Kubernetes

Kubernetes Problem Overview


I've read a couple of passages from some books written on Kubernetes as well as the page on headless services in the docs. But I'm still unsure what it really actually does and why someone would use it. Does anyone have a good understanding of it, what it accomplishes, and why someone would use it?

Kubernetes Solutions


Solution 1 - Kubernetes

Well, I think you need some theory. There are many explanations (including the official docs) across the whole internet, but I think Marco Luksa did it the best:

> Each connection to the service is forwarded to one randomly selected > backing pod. But what if the client needs to connect to all of those > pods? What if the backing pods themselves need to each connect to all > the other backing pods. Connecting through the service clearly isn’t > the way to do this. What is? > > For a client to connect to all pods, it needs to figure out the the IP > of each individual pod. One option is to have the client call the > Kubernetes API server and get the list of pods and their IP addresses > through an API call, but because you should always strive to keep your > apps Kubernetes-agnostic, using the API server isn’t ideal > > Luckily, Kubernetes allows clients to discover pod IPs through DNS > lookups. Usually, when you perform a DNS lookup for a service, the DNS > server returns a single IP — the service’s cluster IP. But if you tell > Kubernetes you don’t need a cluster IP for your service (you do this > by setting the clusterIP field to None in the service specification ), > the DNS server will return the pod IPs instead of the single service > IP. Instead of returning a single DNS A record, the DNS server will > return multiple A records for the service, each pointing to the IP of > an individual pod backing the service at that moment. Clients can > therefore do a simple DNS A record lookup and get the IPs of all the > pods that are part of the service. The client can then use that > information to connect to one, many, or all of them. > > Setting the clusterIP field in a service spec to None makes the > service headless, as Kubernetes won’t assign it a cluster IP through > which clients could connect to the pods backing it.

"Kubernetes in Action" by Marco Luksa

Solution 2 - Kubernetes

Let me break this question into each sub-parts the way we do in agile.

>What exactly is a headless service.

It is used for discovering individual pods(especially IPs) which allows another service to interact directly with the Pods instead of a proxy. With NodePort, LoadBalancer, ExternalName, and ClusterIP clients usually connect to the pods through a Service (Kubernetes Services simply visually explained) rather than connecting directly.

> What does it accomplish?

The requirement is not to make single IP like in the case of other service types. We need all the pod's IP sitting behind the service.

> What are some legitimate use cases for it?

  • Create Stateful service.

  • Deploying RabbitMQ or Kafka (or any message broker service) to Kubernetes requires a stateful set for RabbitMQ cluster nodes.

  • Deployment of Relational databases

  • and many more


Some Practical in Action

Deployment config

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  labels:
    app: server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80

Regular Service

apiVersion: v1
kind: Service
metadata:
  name: regular-svc
spec:
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

Headless Service

apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None # <= Don't forget!!
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

Create all resources and run tmp pod.

k run tmp01 --image=tutum/dnsutils -- sleep infinity

k exec tmp01 -it -- /bin/sh

#=> nslookup regular-svc
Server:		10.96.0.10
Address:	10.96.0.10#53

Name:	regular-svc.moon.svc.cluster.local
Address: 10.109.150.46


#=> nslookup headless-svc
Server:		10.96.0.10
Address:	10.96.0.10#53

Name:	headless-svc.moon.svc.cluster.local
Address: 172.17.0.31
Name:	headless-svc.moon.svc.cluster.local
Address: 172.17.0.30
Name:	headless-svc.moon.svc.cluster.local
Address: 172.17.0.32

The DNS server returns three different IPs for the headless-svc.moon.svc.cluster.local FQDN.

Note 1: with a headless service, clients can connect to its pods by connecting to the service’s DNS name, as they can with regular services. But with headless services, because DNS returns the pods’ IPs, clients connect directly to the pods, instead of through the service proxy.

Note 2: Headless services still provide load balancing across pods but through the DNS round-robin mechanism instead of through the service proxy.

Solution 3 - Kubernetes

Simply put, a Headless service is the same as default ClusterIP service, but lacks load balancing or proxying. Allowing you to connect to a Pod directly.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn LexusView Question on Stackoverflow
Solution 1 - KubernetesKonstantin VustinView Answer on Stackoverflow
Solution 2 - KubernetesGuptaView Answer on Stackoverflow
Solution 3 - KubernetesRaffView Answer on Stackoverflow