Layer 7 (HAProxy)
Load balance UDP with the LB Layer7 tab
This page applies to:
- HAProxy ALOHA 17.0 and newer
You can load balance UDP (User Datagram Protocol) by using HAProxy ALOHA’s UDP module.
What is UDP? Jump to heading
Applications employ UDP when they need a fire-and-forget transport of messages over a network, with minimal overhead. Because UDP lacks the message delivery guarantees that TCP has, it can be ideal for some situations but not others. For example, when sending syslog messages over a network, you might prefer TCP if you require delivery of all messages. Or you might choose UDP if it’s acceptable to lose some messages, but allow the sender to continue sending messages without waiting for confirmation they’ve been received. Under some network conditions, such as where there’s significant packet loss, UDP can have better throughput. But it can perform worse in congested networks, since it lacks TCP’s congestion control.
How does the UDP module work? Jump to heading
The UDP module adds support for a new section in your LB Layer7 configuration called udp-lb
. The udp-lb
section defines the IP address and UDP port at which to accept datagrams. Also in this section, you’ll define the backend servers to load balance datagrams across. The module supports health checking servers and logging traffic too.
Multiple ways to support UDP
HAProxy ALOHA also supports UDP load balancing on its LB Layer4 tab, which uses LVS. You might prefer LVS if you require the utmost speed, since it routes UDP packets without any overhead. You might prefer this LB Layer7 UDP module for better session tracking, logging, and statistics.
Installation Jump to heading
To install the UDP module on HAProxy ALOHA:
-
On the LB Layer7 tab, add the
module-load
directive to theglobal
section. Add theglobal
section if it doesn’t exist.haproxyglobal...module-load hapee-lb-udp.sohaproxyglobal...module-load hapee-lb-udp.so -
Add one or more
udp-lb
sections to configure listening UDP ports and backend servers. See Examples.
Enable logging Jump to heading
You can enable logging of UDP traffic through the load balancer. HAProxy ALOHA will log a message each time it receives a request datagram and forwards it to the backend server, or when the response datagram is sent back to the client. The log output format contains the source and destination addresses, bytes received or sent, the instance name, and the server if available.
-
Add the
log global
directive to yourudp-lb
section to send log messages to the syslog server declared in theglobal
section:haproxyglobalmaxconn 10000log 127.0.0.1 local0log 127.0.0.1 local1 notice...udp-lb dnsdgram-bind 192.168.56.25:53log globalproxy-requests 1balance roundrobinoption udp-checkserver dns1 10.10.10.10:53 checkserver dns2 10.10.10.20:53 checkhaproxyglobalmaxconn 10000log 127.0.0.1 local0log 127.0.0.1 local1 notice...udp-lb dnsdgram-bind 192.168.56.25:53log globalproxy-requests 1balance roundrobinoption udp-checkserver dns1 10.10.10.10:53 checkserver dns2 10.10.10.20:53 checkExample log messages:
logNov 7 20:40:54 hapee hapee-lb[1254]: UDP: request received (58 bytes) from 192.168.56.1:50806 to 192.168.56.25:53 (dns/dns2) Nov 7 20:40:54 hapee hapee-lb[1254]: UDP: response sent (181 bytes) from 192.168.56.25:53 to 192.168.56.1:50806 (dns/dns2)
logNov 7 20:40:54 hapee hapee-lb[1254]: UDP: request received (58 bytes) from 192.168.56.1:50806 to 192.168.56.25:53 (dns/dns2) Nov 7 20:40:54 hapee hapee-lb[1254]: UDP: response sent (181 bytes) from 192.168.56.25:53 to 192.168.56.1:50806 (dns/dns2)
Alternatively, you can define a
log
directive directly in theudp-lb
section to set target syslog servers, facility code, and severity level there. For details, see log reference. -
Optional: Set
log-tag
to indicate in the logs which load balancer server proxied the traffic. On the rsyslog side, this sets the$programname
variable. It defaults tohaproxy
.haproxyudp-lb dnsdgram-bind 192.168.56.25:53log globallog-tag aloha1proxy-requests 1balance roundrobinoption udp-checkserver dns1 10.10.10.10:53 checkserver dns2 10.10.10.20:53 checkhaproxyudp-lb dnsdgram-bind 192.168.56.25:53log globallog-tag aloha1proxy-requests 1balance roundrobinoption udp-checkserver dns1 10.10.10.10:53 checkserver dns2 10.10.10.20:53 checkExample log messages on the Logs tab
traffic logs
:logFeb 28 17:14:06 ALOHA1 local0.info aloha1[6149]: UDP: request received (58 bytes) from 192.168.56.1:55604 to 192.168.56.45:53 (udp-dns/dns1) Feb 28 17:14:06 ALOHA1 local0.info aloha1[6149]: UDP: response sent (181 bytes) from 192.168.56.45:53 to 192.168.56.1:55604 (udp-dns/dns1)
logFeb 28 17:14:06 ALOHA1 local0.info aloha1[6149]: UDP: request received (58 bytes) from 192.168.56.1:55604 to 192.168.56.45:53 (udp-dns/dns1) Feb 28 17:14:06 ALOHA1 local0.info aloha1[6149]: UDP: response sent (181 bytes) from 192.168.56.45:53 to 192.168.56.1:55604 (udp-dns/dns1)
Examples Jump to heading
In this section, you’ll see examples of using the UDP module to load balance different types of applications. This will give you an understanding of the syntax, in case you want to load balance an application not shown here.
Load balance syslog Jump to heading
You can use the UDP module to load balance syslog traffic. The UDP module listens on the configured port and will load balance incoming messages to the list of configured servers. Consider the example configuration below:
haproxy
udp-lb syslog-exampledgram-bind 192.168.56.25:3516proxy-requests 1proxy-responses 0balance roundrobinoption udp-checkserver srv1 10.10.10.10:1514 checkserver srv2 10.10.10.20:1514 checkserver srv3 10.10.10.30:1514 check
haproxy
udp-lb syslog-exampledgram-bind 192.168.56.25:3516proxy-requests 1proxy-responses 0balance roundrobinoption udp-checkserver srv1 10.10.10.10:1514 checkserver srv2 10.10.10.20:1514 checkserver srv3 10.10.10.30:1514 check
- We declare a UDP section using the
udp-lb
directive and name itsyslog-example
. - We specify a
dgram-bind
on localhost port3516
. This is where we expect to receive the UDP syslog traffic.Listen port
Use caution when specifying a port for listening for syslog messages. The default rsyslog configuration for HAProxy Enterprise listens for traffic on localhost port
514
. If you try to specify the same interface and port, the load balancer will be unable to bind on that interface and will receive no messages. - We set
proxy-requests
to1
. This specifies that the load balancer should load balance on each datagram it receives, since each syslog message will fit into a single datagram. - We set
proxy-responses
to0
. This specifies that the load balancer shouldn’t expect a response from the server. - We set the load balancing algorithm to
roundrobin
. - We enable health checks over ICMP with
option udp-check
. Be sure to enable ICMP traffic in your network to allow this behavior.- Note that you could also enable health checks over TCP using
option tcp-check
.
- Note that you could also enable health checks over TCP using
- We list three servers that will receive the load balanced syslog traffic. These servers have been configured via rsyslog to expect UDP log traffic on port
1514
.
Note that for the best performance for load balancing syslog, it’s recommended that proxy-requests
is set to 1
and proxy-responses
is set to 0
.
Load balance DNS Jump to heading
You can use the UDP module to load balance DNS traffic over UDP. However, in cases where the DNS response may be larger than one datagram, it’s better to load balance DNS over TCP because TCP supports larger responses. This scenario may occur with DNS-based service discovery. In most cases, a DNS request fits within one datagram, and UDP is sufficient.
Consider the example configuration below:
haproxy
udp-lb udp-dnsdgram-bind 192.168.56.25:53proxy-requests 1balance roundrobinoption udp-checkserver dns1 10.10.10.10:53 checkserver dns2 10.10.10.20:53 checkfrontend tcp-dnsmode tcpbind 192.168.56.25:53default_backend tcp-dns-backendbackend tcp-dns-backendmode tcpbalance roundrobinserver srv1 10.10.10.10:53 checkserver srv2 10.10.10.20:53 checkserver srv3 10.10.10.30:53 check
haproxy
udp-lb udp-dnsdgram-bind 192.168.56.25:53proxy-requests 1balance roundrobinoption udp-checkserver dns1 10.10.10.10:53 checkserver dns2 10.10.10.20:53 checkfrontend tcp-dnsmode tcpbind 192.168.56.25:53default_backend tcp-dns-backendbackend tcp-dns-backendmode tcpbalance roundrobinserver srv1 10.10.10.10:53 checkserver srv2 10.10.10.20:53 checkserver srv3 10.10.10.30:53 check
- UDP
- We declare a UDP section using the
udp-lb
directive and name itudp-dns
. - We specify a
dgram-bind
on192.168.56.25:53
. - We set
proxy-requests
to1
. This specifies that the load balancer should load balance on each datagram it receives, since each DNS request will fit into a single datagram.proxy-responses
Unlike our other examples which explicitly set a value for
proxy-responses
, in the case for DNS, we leave this option unset. By leaving it unset, this specifies that the load balancer should expect an unlimited number of responses from the DNS server. It will forward all responses back to the client. - We set the load balancing algorithm to
roundrobin
. - We enable health checks over ICMP with
option udp-check
. Be sure to enable ICMP traffic in your network to allow this behavior.- Note that you could also enable health checks over TCP using
option tcp-check
.
- Note that you could also enable health checks over TCP using
- We list two servers that will receive and provide responses for the load-balanced DNS requests.
- We declare a UDP section using the
- TCP
- We define a frontend named
tcp-dns
and a backend namedtcp-dns-backend
. This frontend and backend will load balance DNS traffic over TCP. - We enable TCP healthchecks using
check
. - We list three servers that will receive and provide responses for the load-balanced DNS requests.
- We define a frontend named
For more information, see DNS service discovery.
Alternative configuration
If the port on the dgram-bind
line in the udp-lb
section is the same as the port you specified on the server
lines, you can omit the port from the server lines. Consider the previous example where the load balancer will listen via dgram-bind
on 192.168.56.25 on port 53 and then forward requests to servers, also on port 53. You can configure your udp-lb
section as follows instead, leaving off the ports on the server lines:
haproxy
udp-lb udp-dnsdgram-bind 192.168.56.25:53proxy-requests 1balance roundrobinoption udp-checkserver dns1 10.10.10.10 checkserver dns2 10.10.10.20 check
haproxy
udp-lb udp-dnsdgram-bind 192.168.56.25:53proxy-requests 1balance roundrobinoption udp-checkserver dns1 10.10.10.10 checkserver dns2 10.10.10.20 check
Load balance NTP Jump to heading
You can use the UDP module to load balance NTP traffic. The UDP module listens on the configured port and will load balance incoming NTP requests to the list of configured NTP servers. It will then return the response to the appropriate client.
Consider the example configuration below:
haproxy
udp-lb ntpdgram-bind 192.168.56.25:123proxy-requests 1proxy-responses 1balance roundrobinoption udp-checkserver srv1 10.10.10.10:123 checkserver srv2 10.10.10.20:123 checkserver srv2 10.10.10.30:123 check
haproxy
udp-lb ntpdgram-bind 192.168.56.25:123proxy-requests 1proxy-responses 1balance roundrobinoption udp-checkserver srv1 10.10.10.10:123 checkserver srv2 10.10.10.20:123 checkserver srv2 10.10.10.30:123 check
- We declare a UDP section using the
udp-lb
directive and name itntp
. - We specify a
dgram-bind
on all interfaces on port123
. This is the standard NTP port where we expect to receive NTP requests.NTP servers
UDP Port
123
is the standard port for NTP and most implementations don’t allow you to change it. As such, your load balancer and NTP server(s) should not be the same server. The load balancer must bind on port123
to load balance the NTP requests, which it would be unable to do if the server it runs on is also running as an NTP server (and therefore is already using UDP port123
). - We set
proxy-requests
to1
. This specifies that the load balancer should load balance on each datagram it receives, since each NTP request will fit into a single datagram. - We set
proxy-responses
to1
. This specifies that the load balancer should expect one response from the NTP server. It will then relay the response back to the client. - We set the load balancing algorithm to
roundrobin
. - We enable health checks over ICMP with
option udp-check
. Be sure to enable ICMP traffic in your network to allow this behavior.- Note that you could also enable health checks over TCP using
option tcp-check
.
- Note that you could also enable health checks over TCP using
- We list three servers that will receive the load balanced NTP traffic. These servers have been configured as NTP servers and will respond to requests on the standard UDP NTP port
123
.
Alternative configuration
If the port on the dgram-bind
line is the same as the port you specified on the server
lines, you can omit the port from the server lines. Consider the previous example where the load balancer will listen via dgram-bind
on 192.168.56.25 on port 123 and then forward requests to servers, also on port 123. You can configure your udp-lb
section as follows instead, leaving off the ports on the server lines:
haproxy
udp-lb ntpdgram-bind 192.168.56.25:123proxy-requests 1proxy-responses 1balance roundrobinoption udp-checkserver srv1 10.10.10.10 checkserver srv2 10.10.10.20 checkserver srv2 10.10.10.30 check
haproxy
udp-lb ntpdgram-bind 192.168.56.25:123proxy-requests 1proxy-responses 1balance roundrobinoption udp-checkserver srv1 10.10.10.10 checkserver srv2 10.10.10.20 checkserver srv2 10.10.10.30 check
Load balance RADIUS Jump to heading
You can use the UDP module to load balance RADIUS authentication traffic. The UDP module listens on the configured ports and will load balance incoming requests to the list of configured RADIUS servers. It will then return the responses to the appropriate client.
Consider the example configuration below where the load balancer is configured to route traffic to both RADIUS authentication (1812) and accounting (1813) ports:
haproxy
udp-lb radius-authdgram-bind 192.168.56.25:1812balance sourceserver srv1 10.10.10.10:1812server srv2 10.10.10.20:1812server srv3 10.10.10.30:1812udp-lb radius-accountingdgram-bind 192.168.56.25:1813balance sourceserver srv1 10.10.10.10:1813server srv2 10.10.10.20:1813server srv3 10.10.10.30:1813
haproxy
udp-lb radius-authdgram-bind 192.168.56.25:1812balance sourceserver srv1 10.10.10.10:1812server srv2 10.10.10.20:1812server srv3 10.10.10.30:1812udp-lb radius-accountingdgram-bind 192.168.56.25:1813balance sourceserver srv1 10.10.10.10:1813server srv2 10.10.10.20:1813server srv3 10.10.10.30:1813
- We declare two UDP sections using the
udp-lb
directive and name themradius-auth
andradius-accounting
. - We specify a
dgram-bind
on all interfaces on port1812
forradius-auth
and port1813
forradius-accounting
.- Ensure that the ports you specify match the ports defined in your RADIUS configuration (1812 and 1813 are the RADIUS defaults).
- We set the load balancing algorithm to
source
. This is required so that requests from the same client are routed to the same server. - We don’t set
proxy-requests
. There will be multiple requests from the client, and we want all requests from the same client to be routed to the same server. This applies regardless of any timeout value specified since we have also setbalance
tosource
. - We don’t set
proxy-responses
. There will be multiple responses from the RADIUS server. - We list three servers that will receive the load balanced RADIUS traffic. These servers have been configured as RADIUS servers and will respond to requests on the default RADIUS ports 1812 and 1813.
Alternative configuration
If the ports on the dgram-bind
lines in the udp-lb
sections are the same as the ports you specified on the server
lines, you can omit the ports from the server lines. Consider the previous example where the load balancer will listen via dgram-bind
on 192.168.56.25 on ports 1812 and ports 1813 and then forward requests to servers, either on port 1812 or 1813, depending on what port the load balancer received the request. You can configure your udp-lb
section as follows instead, leaving off the ports on the server lines and combining the two udp-lb
sections:
haproxy
udp-lb radiusdgram-bind 192.168.56.25:1812dgram-bind 192.168.56.25:1813balance sourceserver srv1 10.10.10.10server srv2 10.10.10.20server srv3 10.10.10.30
haproxy
udp-lb radiusdgram-bind 192.168.56.25:1812dgram-bind 192.168.56.25:1813balance sourceserver srv1 10.10.10.10server srv2 10.10.10.20server srv3 10.10.10.30
Reference Jump to heading
Configuring udp-lb sections
udp-lb
sections don’t inherit settings from defaults
sections. You must define the following directives explicitly within each appropriate udp-lb
section.
The UDP module uses the following directives for configuration.
accepted-payload-size Jump to heading
Sets the maximum UDP datagram payload size in bytes. The default value is 1472
, and the maximum value allowed is 65507
.
Syntaxtext
accepted-payload-size <number>
Syntaxtext
accepted-payload-size <number>
acl Jump to heading
This section applies to:
- HAProxy Enterprise 3.2r1 and newer
- Not available in HAProxy ALOHA
Configure an ACL (Access Control List). See ACLs for more implementation details.
Syntaxtext
acl <name> <criterion> [<ACL flags>] [<operator>] <value>
Syntaxtext
acl <name> <criterion> [<ACL flags>] [<operator>] <value>
balance Jump to heading
Sets the load balancing algorithm.
Syntaxtext
balance <algorithm>
Syntaxtext
balance <algorithm>
The UDP module supports the following algorithms for balance
:
static-rr
roundrobin
leastconn
first
source
random
default-server Jump to heading
Sets default parameters that will apply to all server
lines within the same section. For a list of supported parameters, see default-server options.
Syntaxtext
default-server [param*]
Syntaxtext
default-server [param*]
dgram-bind Jump to heading
Configures a datagram listener to receive messages to forward. Addresses must be in IPv4 or IPv6 form, optionally followed by a port.
Syntaxtext
dgram-bind <addr> [param*]
Syntaxtext
dgram-bind <addr> [param*]
The dgram-bind
directive supports these bind parameters:
maxconn
namespace
nice
shards
thread
transparent
hash-balance-factor Jump to heading
This section applies to:
- HAProxy ALOHA 17.0 and newer
- HAProxy Enterprise 3.1r1 and newer
Specifies the balancing factor for bounded-load consistent hashing. See hash-balance-factor for more details.
Syntaxtext
hash-balance-factor <factor>
Syntaxtext
hash-balance-factor <factor>
hash-type Jump to heading
This section applies to:
- HAProxy ALOHA 17.0 and newer
- HAProxy Enterprise 3.1r1 and newer
Specifies a method to use for mapping hashes to servers. See hash-type for more details.
Syntaxtext
hash-type <method> <function> <modifier>
Syntaxtext
hash-type <method> <function> <modifier>
log Jump to heading
This section applies to:
- HAProxy ALOHA 17.0 and newer
- HAProxy Enterprise 3.0r1 and newer
Enables per-instance logging of events. For requests, the source is the client’s IP/port, and the destination is the listener’s IP/port. For responses, the source is the listener, and the destination is the client.
For details, see log reference.
Syntaxtext
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>] <facility> [<level> [<minlevel>]]
Syntaxtext
log <target> [len <length>] [format <format>] [sample <ranges>:<sample_size>] <facility> [<level> [<minlevel>]]
log global Jump to heading
This section applies to:
- HAProxy ALOHA 17.0 and newer
- HAProxy Enterprise 3.0r1 and newer
Sets the instance’s logging parameters to be the same as the global ones.
Syntaxtext
log global
Syntaxtext
log global
log-tag Jump to heading
This section applies to:
- HAProxy ALOHA 17.0 and newer
- HAProxy Enterprise 3.0r1 and newer
Sets the log tag string to use for all outgoing logs.
Syntaxtext
log-tag <string>
Syntaxtext
log-tag <string>
maxconn Jump to heading
Sets the maximum number of concurrent connections. Once the limit is reached, all datagrams received initiating new UDP connection will be dropped.
Syntaxtext
maxconn <integer>
Syntaxtext
maxconn <integer>
option persist Jump to heading
This section applies to:
- HAProxy Enterprise 3.2r1 and newer
- Not available in HAProxy ALOHA
Enables forced persistence on downed servers by forcing the datagram to be sent to the downed server(s) first.
Syntaxtext
option persist
Syntaxtext
option persist
option tcp-check Jump to heading
Performs health checks using TCP connection attempts.
Syntaxtext
option tcp-check
Syntaxtext
option tcp-check
option udp-check Jump to heading
Performs health checks via ICMP.
Syntaxtext
option udp-check
Syntaxtext
option udp-check
proxy-requests Jump to heading
Sets the number of expected datagrams per client session. Since UDP isn’t a connection-oriented protocol, the UDP module must keep track of a client’s session such that it can route the response datagrams from an upstream server back to the correct client. Each session is indexed by the 4-tuple consisting of source IP/port and destination IP/port corresponding to the datagram.
-
If this option isn’t set, then the load balancer will forward all datagrams from the client to the same backend server as long as the client is considered alive. If the client becomes inactive, their session expires, and the next time they send a datagram, the load balancer will again choose a server based on the load balancing algorithm.
-
If this option is set to a value greater than 0, then session stickiness is disabled and the load balancer will choose the backend server on every
<number>
datagrams received. For example, if set toproxy-requests 1
, then a destination server will be rotated after each datagram received from the client.
Syntaxtext
proxy-requests <number>
Syntaxtext
proxy-requests <number>
proxy-responses Jump to heading
Sets the number of expected responses from the server. Sessions last until the timeout is reached or the expected number of responses has been received. If a zero value is specified, all responses from the server will be ignored and not forwarded back to the client. If a value isn’t specified, the number of expected responses is set to unlimited.
Syntaxtext
proxy-responses <number>
Syntaxtext
proxy-responses <number>
server Jump to heading
Configures a target server.
Syntaxtext
server <name> <address>[:[port]] [param*]
Syntaxtext
server <name> <address>[:[port]] [param*]
source Jump to heading
Sets the source address for outgoing connections. The <addr>
and optional <port>
will be used for binding before connecting to the server. The <addr2>
and <port2>
are presented to the server when connections are forwarded in full transparent proxy mode. If client
or clientip
is set, the load balancer will present the client’s IP address and port, or the client’s IP address only.
Syntax for setting source addresstext
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
Syntax for setting source addresstext
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | client | clientip } ]
Syntax for setting interface nametext
source <addr>[:<port>] [interface <name>]
Syntax for setting interface nametext
source <addr>[:<port>] [interface <name>]
tcp-check Jump to heading
Configures TCP health checking.
Syntaxtext
tcp-check <option> [param*]
Syntaxtext
tcp-check <option> [param*]
Supported options are:
comment
connect
send
send-lf
send-binary
send-binary-lf
expect
set-var
set-var-fmt
unset-var
timeout client Jump to heading
Sets the maximum inactivity time on the client side. The default is 10 seconds, but the ideal setting depends on your traffic and application. For example, if you have a large amount of traffic and a large number of client IP addresses and ports, you can lower the value in order to avoid tracking a high number of connections unnecessarily.
Syntaxtext
timeout client <timeout>
Syntaxtext
timeout client <timeout>
timeout server Jump to heading
Sets the maximum inactivity time on the server side.
Syntaxtext
timeout server <timeout>
Syntaxtext
timeout server <timeout>
use-server Jump to heading
This section applies to:
- HAProxy Enterprise 3.2r1 and newer
- Not available in HAProxy ALOHA
Assign a specified server if/unless a condition is matched. For example, use a target UDP server based on the source IP.
If there is more than one use-server
directive configured, they are evaluated in their declaration order. The first use-server
directive that matches a condition will assign the specified server, unless the current session has already assigned that server. If no condition is valid, the unassigned servers will use other load balancing mechanisms.
When <server>
is a simple name, the load balancer is checks it against existing servers in the configuration and reports an error if the specified server doesn’t exist. If <server>
is in a custom log format, no check is performed when parsing the configuration. If the load balancer can’t resolve a valid server name at runtime, but a use-server
was condition was met, no other use-server
directive is applied, and the load balancer will fall back to load balancing.
Syntaxtext
use-server <server> { if | unless } <condition>
Syntaxtext
use-server <server> { if | unless } <condition>
Do you have any suggestions on how we can improve the content of this page?