Why does k8s wordpress and mysql example use headless service for wordpress-mysql?

Viewed 619

The example is described here - https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/

The Service object for the wordpress-mysql is:

apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None

The headless services are documented here - https://kubernetes.io/docs/concepts/services-networking/service/#headless-services The Service definition defines selectors, so I suppose the following passage applies:

For headless Services that define selectors, the endpoints controller creates Endpoints records in the API, and modifies the DNS configuration to return records (addresses) that point directly to the Pods backing the Service

I have followed the example on a 3 node managed k8s cluster in Azure:

C:\work\k8s\mysql-wp-demo> kubectl.exe get ep
NAME              ENDPOINTS          AGE
kubernetes        52.186.94.71:443   47h
wordpress         10.244.0.10:80     5h33m
wordpress-mysql   10.244.3.28:3306   5h33m
C:\work\k8s\mysql-wp-demo> kubectl.exe get pods -o wide
NAME                               READY   STATUS    RESTARTS   AGE     IP            NODE                                NOMINATED NODE   READINESS GATES
wordpress-584f8d8666-rlbf5         1/1     Running   0          5h33m   10.244.0.10   aks-nodepool1-30294001-vmss000001   <none>           <none>
wordpress-mysql-55c74969cd-4l8d4   1/1     Running   0          5h33m   10.244.3.28   aks-nodepool1-30294001-vmss000003   <none>           <none>
C:\work\k8s\mysql-wp-demo>

As far as I understand there is no difference from the endpoints perspective.

Can someone explain to me - what is the point of headless services in general and in this example in particular?

1 Answers

A regular service has a virtual Service IP that exists as iptables or ipvs rules on each node. A new connection to this service IP is then routed with DNAT to one of the Pod endpoints, to support a form of load balancing across multiple pods.

A headless service (that isn't an ExternalName) will create DNS A records for any endpoints with matching labels or name. Connections will go directly to a single pod/endpoint without traversing the service rules.

A service with a type of ExternalName is just a DNS CNAME record in kubernetes DNS. These are headless by definition as they are names for an IP external to the cluster.

The linked myql deployment/service example is leading into StatefulSet's. This Deployment is basically a single pod statefulset. When you do move to a StatefulSet with multiple pods, you will mostly want to address individual members of the StatefulSet with a specific name (see mdaniels comment).

Another reason to set clusterIP: None is to lessen the load on iptables processing which slows down as the number of services (i.e. iptables rules) increases. Applications that don't need multiple pods, don't need the Service IP. Setting up a cluster to use IPVS alleviates the slow down issue somewhat.

service flow

Related