Domain Name Resolution (DNS)
This page is still in a WIP status
Domain Name Resolution or DNS is the naming system associating a human readable name to a network address that a computer can reach and the other way around. It actually does more than that, but for this page, this is the most useful information we need to know about DNS.
For example, the human readable name www.haproxy.org resolves to the IP address 51.15.8.218 (at the time of writing this page).
The main sections of this documentation are:
- the resolvers section
- Service discovery with SRV records
- Links
- Opened issues
- History of Name resolution in HAProxy
- TODO for this page
In order to enable "runtime DNS resolution" in HAProxy, you first must configure a resolvers section. This section allows you to configure the name servers themselves as well as various timers regarding server name resolution.
NOTE: multiple resolvers section can be set in a single HAProxy configuration. The right one should be linked wherever needed
The resolvers section below is the simplest you could use and should work everywhere. It instructs HAProxy to use the name servers found in /etc/resolv.conf:
resolvers mydns
parse-resolv-conf
The configuration snippet example below show how to configure multiple resolvers section to use different servernames:
resolvers local
parse-resolv-conf
resolvers public
nameserver ggl1 8.8.8.8:53
nameserver ggl2 8.8.4.4:53
When default values are not good, we can customize them in an "advanced configuration:
resolvers local
nameserver consul 127.0.0.1:8600
accepted_payload_size 8142
hold valid 60s
hold obsolete 60s
Use the directive resolvers on the server or default-server lines:
resolvers mydns
parse-resolv-conf
backend myapp
server srv1 srv1.foo.dom.com:8080 check resolvers mydns
Usually, consul agent listen on the loopback address and exposes its DNS service on port 8600. Furthermore, it is recommended to use SRV records with Consul, so we want to increase the accepted_payload_size to its maximum value. Finally, some timers may be adjusted, based on the use case:
resolvers local
nameserver consul 127.0.0.1:8600
accepted_payload_size 8142
hold valid 60s
hold obsolete 60s
In a dynamic environment such as AWS, it is recommended to parse resolv.conf file to discover the nameserver IP addresses. (if you use Consul on top of AWS, please apply the Consul recommendations). Depending on the size of the backend, the accepted_payload_size should be set too.
resolvers local
parse-resolv-conf
accepted_payload_size 8142
HAProxy supports DNS SRV records to perform Service Discovery. In this use case, HAProxy will update:
- the server FQDN with the SRV record target field
- the server port with the SRV record port field
- the server weight with the SRV record weight field All other fields from the SRV record are ignored
As stated in RFC 2782, the SRV query has a specific format, such as: "_Service._Proto.Name". You have to use the same format in your HAProxy configuration:
server-template myapp 10 _http._tcp.srv.hapro.xyz check resolvers mydns
NOTE: don't add a TCP port after the hostname, it will be ignored and replaced by the one provided in the SRV record.
You can observe the SRV record resolution in action through the runtime API. Run show servers state
, it will output something like:
3 be 1 www1 192.168.1.71 0 64 1 1 3 7 0 0 7 0 0 0 srv1.hapro.xyz 80 _http._tcp.srv.hapro.xyz 0
3 be 2 www2 192.168.1.122 0 64 1 1 3 7 0 0 7 0 0 0 srv2.hapro.xyz 80 _http._tcp.srv.hapro.xyz 0
3 be 3 www3 10.42.3.3 0 64 1 1 4 8 2 0 6 0 0 0 srv3.hapro.xyz 80 _http._tcp.srv.hapro.xyz 0
3 be 4 www4 37.187.96.49 2 64 1 1 7 6 3 4 6 0 0 0 srv4.hapro.xyz 80 _http._tcp.srv.hapro.xyz 0
You can see the fqdn associated to the server, the TCP port provided by the SRV record and the SRV hostname associated to the server.
In most cases, DNS servers return the SRV target resolution in the Additional section of the response. HAProxy can adapt itself to server's behavior:
- when the DNS server returns Additional Records, HAProxy will use them when they are relevant, or will trigger a separated DNS request for targeted fqdn
- When the server doesn't send any Additional records, then HAProxy will trigger A/AAAA resolutions automatically for each fqdn associated to a server
These third party resources provide useful information and use cases about HAProxy and DNS:
- Consul and HAProxy integration (documentation from 2019)
- DNS for Service discovery (blog from 2019)
- How to resolve AWS ALB / NLB in HAProxy (blog from 2019)
- HAProxy and consul with DNS for Service Discovery (blog from 2018)
Feature request in DNS subsystem
-
Until version 1.5:
- Use the DNS resolver provided by the libc at configuration parsing time only
-
version 1.6:
- First asynchronous resolver available at runtime and able to follow-up a server's IP address change. Main use case was for AWS ec2 instances or ELBs getting whose IP address can change over time
-
version 1.7:
- New
init-addr
parameter to "enforce" a server IP address at configuration parsing time (to avoid blocking, errors or latency introduced by non-asynchronous DNS resolver from the libc
- New
-
version 1.8:
- the ability to allow or prevent using the same IP multiple times in a backend
- the ability to use EDNS and announce a "large" payload size accepted by HAProxy
- support for SRV records, which can also change a server's weight and port
-
version 1.9:
- read /etc/resolve.conf file and to use name servers available in there
-
version 2.2:
- Parse Additional section provided with SRV responses and use A / AAAA records when useful