Service discovery monitors and detects automatically devices and services on a network so that other components can stay efficient in environments subject to rapid configuration changes such as the cloud or microservices.

DNS for Service Discovery is a feature that can update an HAProxy configuration during run time, such as changes in server status, IP addresses, ports, and weights. without making explicit changes to configuration files.

DNS SRV records

This is done using DNS SRV which are resource records used to identify computers that host specific services.

DNS SRV records allow HAProxy get a list of back-end servers from DNS records.

SRV records are contained in the ANSWER section of DNS responses and have the following structure:

_service._proto.name. TTL class SRV priority weight port target

where:

_service

Standard network service name (taken from /etc/services) or a port number

_proto

Standard protocol name ("tcp" or "udp")

name

Name of the service, i.e. the name used in the query

TTL

Validity period for the response (HAProxy ignores this field because it maintains its own expiry data defined in the configuration)

class

DNS class ("IN")

SRV

DNS record type ("SRV")

priority

Priority of the target host. Lower value = higher preference (HAProxy ignores this field but may use it later to indicate active / backup state)

weight

Relative weight in case of records with the same priority. Higher number = higher preference

port

Port where the service is configured

target

Hostname of the machine providing the service, ending in a dot

Note

Usually, the DNS server also returns the resolution for the targets mentioned, and it provides that information in the ADDITIONAL SECTION.

Retrieve a list of servers

To get the list of servers, HAProxy performs a DNS query like the following shell command, using as a service called red as an example:

dig -t srv _http._tcp.red.domain.local

The service discovery returns the following records:

;; QUESTION SECTION:
;_http._tcp.red.domain.local. IN SRV

;; ANSWER SECTION:
_http._tcp.red.domain.local. 30 IN SRV 10 25 8080 3963643338366463.red.domain.local.
_http._tcp.red.domain.local. 30 IN SRV 10 25 8080 3366376637306635.red.domain.local.
_http._tcp.red.domain.local. 30 IN SRV 10 25 8080 3464316362303933.red.domain.local.
_http._tcp.red.domain.local. 30 IN SRV 10 25 8080 3963326437356461.red.domain.local.

;; ADDITIONAL SECTION:
3963643338366463.red.domain.local. 30 IN A 10.1.29.2
3366376637306635.red.domain.local. 30 IN A 10.1.29.3
3464316362303933.red.domain.local. 30 IN A 10.1.71.2
3963326437356461.red.domain.local. 30 IN A 10.1.71.3

Upon receiving this response, HAProxy adjusts its configuration to the number of records returned. As more records are added/removed this will change, up to the maximum number of servers specified in the server-template line.

Resolve an SRV record

With an SRV record to resolve, add the following code to the bind zone file:

srv1    IN      A       192.168.0.1
srv2    IN      A       192.168.122.1
_test._tcp.example.com. SRV 0 100 80 srv1
_test._tcp.example.com. SRV 0 100 80 srv2

Set up the backend in HAProxy as follows:

resolvers test
   nameserver dns1 192.168.0.1:53

backend be_app
   balance            roundrobin
   cookie             SERVERID insert indirect nocache
   server-template srv 5 _test._tcp.example.com resolvers test check