UDP load balancing
Check the health of UDP servers
This page applies to:
- HAProxy Enterprise 2.8r1 and newer
The UDP module supports two ways to check the health of your backend servers. The default check sends a probe datagram and watches the socket error queue for ICMP Destination Unreachable replies. With send and expect actions, available since HAProxy Enterprise 3.4r1 and HAProxy ALOHA 18.5, the load balancer sends one or more probe datagrams and verifies that the server answers each probe with an expected response. The send and expect approach detects failures that the default check misses, such as a DNS resolver that is running but returns errors for every query, or a RADIUS server that accepts datagrams but rejects authentications because its database is down.
Default health check Jump to heading
With option udp-check and no udp-check directives, the load balancer sends a probe datagram to the server’s address and port. If the kernel reports an ICMP Destination Unreachable error for the probe, the server is marked as down. If no error arrives, the server is marked as up.
Because UDP has no connection handshake, a server that is running but not answering application traffic still passes this check. Firewalls on the path must also permit ICMP Unreachable messages to reach the load balancer. See the option udp-check reference for details.
Send and expect health checks Jump to heading
This section applies to:
- HAProxy Enterprise 3.4r1 and newer
- HAProxy ALOHA 18.5 and newer
You can define a sequence of udp-check directives that send probe datagrams and match the replies. The check passes only when every expect action matches a reply from the server within the check timeout. The udp-check directive gives you several ways to verify that the backend UDP server is up and running:
- Send a string in a datagram with
udp-check send, then check that the server returns a datagram with an expected string by usingudp-check expect string <pattern>. - Expect the reply to contain a certain number of bytes by adding
min-recv <n>to the expectation. - Send binary data with
udp-check send-binaryand match binary replies withudp-check expect binary <hexstring>orudp-check expect rbinary <regex>. - Invert a match by prefixing it with
!, so that the check fails when the reply matches the pattern.
For the full list of supported arguments, status values, and sequence rules, see the Reference.
In this example, the load balancer sends the datagram ping-check every 2 seconds. The server is marked as up only when it replies with a datagram that contains the string pong within 1 second.
haproxyudp-lb echodgram-bind 192.168.56.25:4000timeout check 1soption udp-checkudp-check send ping-checkudp-check expect string pongserver server1 10.10.10.10:4000 check inter 2s
haproxyudp-lb echodgram-bind 192.168.56.25:4000timeout check 1soption udp-checkudp-check send ping-checkudp-check expect string pongserver server1 10.10.10.10:4000 check inter 2s
Example: send and expect binary data Jump to heading
This example sends a DNS A query for example.com and expects a reply that carries the same transaction ID as the query. The transaction ID is the first two bytes of the query, so the reply must begin with 0001:
haproxyudp-lb dnsdgram-bind 192.168.56.25:53timeout check 1soption udp-checkudp-check send-binary 000101000001000000000000076578616d706c6503636f6d0000010001udp-check expect rbinary ^0001server ns1 10.10.10.10:53 check inter 2s
haproxyudp-lb dnsdgram-bind 192.168.56.25:53timeout check 1soption udp-checkudp-check send-binary 000101000001000000000000076578616d706c6503636f6d0000010001udp-check expect rbinary ^0001server ns1 10.10.10.10:53 check inter 2s
Breaking down the probe datagram:
| Bytes | Meaning |
|---|---|
0001 |
Transaction ID |
0100 |
Flags: recursion desired |
0001 |
One question |
0000 0000 0000 |
Zero answer, authority, and additional records |
07 6578616d706c65 03 636f6d 00 |
QNAME: example.com |
0001 |
QTYPE: A |
0001 |
QCLASS: IN |
Services that never reply Jump to heading
Some UDP services discard probe datagrams and never reply, for example a syslog collector used with proxy-responses 0. An expect rule requires the server to answer, so such a service fails every send and expect check. For these services, keep the default check: use option udp-check with no udp-check rules, and make sure the network path permits ICMP Unreachable messages to return to the load balancer. Alternatively, probe the service with a datagram it is known to answer.
Follow another server’s health check Jump to heading
This section applies to:
- HAProxy Enterprise 3.4r1 and newer
A udp-lb server can depend on the health of a server in the same section, or a different udp-lb section, or a different TCP or HTTP backend section instead of running a check itself. Add the track parameter to the server line and point it at the server to monitor:
haproxybackend service_tcpserver srv1 10.10.10.10:1111 checkudp-lb service_udpserver srv1 10.10.10.10:4444 track service_tcp/srv1
haproxybackend service_tcpserver srv1 10.10.10.10:1111 checkudp-lb service_udpserver srv1 10.10.10.10:4444 track service_tcp/srv1
The UDP server then runs no health check of its own. Its status mirrors the tracked server’s. When the tracked server fails its check, the UDP server reports as down, and when the tracked server comes back up, the UDP server reports as up.
This is useful when a service is exposed over both TCP and UDP. The TCP side gets an application-aware health check, and the UDP side follows it, so a failure on either transport removes both from rotation.
Rules to keep in mind:
- The tracked server must have a health check or an agent enabled. Otherwise the load balancer rejects the configuration at startup.
- A server can’t run a health check and track another server at the same time. Don’t add a
checkargument to a server that has atrackparameter; don’t addudp-checkdirectives to theudp-lbsection. - Any type of health check can be tracked: a TCP check, an HTTP check, or a
udp-checksend and expect sequence on anotherudp-lbserver.
See the track reference for the full syntax.