HAProxy Load balancer and proxy

Version 3.0 · source

Start here

haproxy -c -f <file>
Check the config
haproxy -f <file>
Run in foreground
haproxy -D -f <file>
Run as daemon
haproxy -W -f <file>
Master-worker mode
kill -USR2 <master-pid>
Reload the config
echo "show info" | socat /run/haproxy.sock stdio
Process status
echo "show stat" | socat /run/haproxy.sock stdio
Per-server stats
echo "disable server <be>/<srv>" | socat /run/haproxy.sock stdio
Drain for maintenance

Concepts

  1. frontend bind, ACLs
  2. backend balance, checks
  3. server app instance
A request flows through frontend rules to a backend
global process settings
defaults shared timeouts, mode
frontend / backend listen = both in one
Sections of haproxy.cfg

Process Control

haproxy -c -f <file>
Validate config and exit
haproxy -f <file>
Start with a config file
haproxy -f <dir>
Load all .cfg files in a directory
haproxy -D -f <file>
Fork into the background
haproxy -W -f <file>
Master-worker mode
haproxy -db -f <file>
Foreground, no master-worker
haproxy -d -f <file>
Debug mode, show events
haproxy -p <pidfile> -f <file>
Write PIDs to a file
haproxy -sf <pid>
Reload; old process stops gracefully
haproxy -st <pid>
Reload; old process killed at once
haproxy -v
Print version and build date
haproxy -vv
Build options and libraries
haproxy -S <bind> -W -f <file>
Open a master CLI socket
kill -USR2 <master-pid>
Reload in master-worker mode
kill -USR1 <pid>
Graceful stop
kill -TERM <pid>
Hard stop
haproxy -C <dir> -f <file>
Change directory first

Runtime API

stats socket /run/haproxy.sock mode 600 level admin
Enable the socket (global section)
echo "<command>" | socat /run/haproxy.sock stdio
Run one command via socat
echo "show info;show stat" | socat /run/haproxy.sock stdio
Several commands, semicolon-separated
socat /run/haproxy.sock readline
Interactive session
prompt
Toggle interactive mode
help
List the available commands
show info
Version, uptime, load, limits
show stat
CSV stats for all proxies
show stat typed
Typed output format
show stat json
Stats as JSON
show servers state <backend>
Server states and weights
show servers conn <backend>
Current and idle connections
show backend
List backends
show sess
List active streams
show errors
Last request/response errors
show pools
Memory pool usage
show activity
Internal event counters
show resolvers [<id>]
DNS resolver stats
set severity-output number
Add severity prefix to output

Servers and Limits

disable server <be>/<srv>
Put server in maintenance
enable server <be>/<srv>
Bring server back
set server <be>/<srv> state drain
Stop new sessions, keep persisted
set server <be>/<srv> state ready
Normal mode
set server <be>/<srv> state maint
Same as disable server
set server <be>/<srv> weight <n>[%]
Change load share
get weight <be>/<srv>
Show current and initial weight
set server <be>/<srv> addr <ip> [port <p>]
Change server address
set server <be>/<srv> health <up|stopping|down>
Force health state
set server <be>/<srv> agent <up|down>
Force agent state
shutdown sessions server <be>/<srv>
Kill all streams to a server
set maxconn global <n>
Change global maxconn
set maxconn frontend <fe> <n>
Change frontend maxconn
set maxconn server <be>/<srv> <n>
Change server maxconn
set rate-limit connections global <n>
Change connection rate limit

Tables, ACLs and Maps

show table
List stick-tables
show table <name>
Dump entries of one table
clear table <name> key <key>
Delete one table entry
set table <name> key <key> data.<type> <v>
Create or update an entry
show acl
List ACL files and IDs
add acl <acl> <pattern>
Add an ACL entry
del acl <acl> <key>
Remove an ACL entry
clear acl <acl>
Remove all entries
show map
List maps
add map <map> <key> <value>
Add a map entry
set map <map> <key> <value>
Change a map entry
del map <map> <key>
Remove a map entry

Master CLI and TLS

reload
Synchronous reload via master CLI
show proc
List master and worker processes
@<worker> <command>
Run a command on a worker
show ssl cert
List loaded certificates
set ssl cert <file> <payload>
Stage a new certificate
commit ssl cert <file>
Activate the staged certificate
show cli sockets
List CLI sockets

Config Basics

global
Process-wide settings section
defaults
Shared mode and timeouts
frontend <name>
Where clients connect
backend <name>
Pool of servers
listen <name>
Frontend and backend in one
bind :<port>
Accept connections on a port
mode http
Layer 7 proxying
mode tcp
Layer 4 proxying
server <name> <ip>:<port> check
Add a checked server
balance roundrobin
Rotate across servers
balance leastconn
Fewest connections wins
balance source
Pin clients by source IP
default_backend <name>
Fallback backend
use_backend <name> if <acl>
Route by condition
acl <name> <criterion> <value>
Define a named condition
http-request deny if <acl>
Reject matching requests
http-request redirect scheme https unless { ssl_fc }
Force HTTPS
http-request set-header <name> <value>
Set a request header
option forwardfor
Add X-Forwarded-For
option httpchk
HTTP health checks
http-check send meth GET uri <path>
Choose the check request
timeout client|server|connect <t>
Set timeouts
maxconn <n>
Connection limit
stats uri <path>
Serve the stats page
stats auth <user>:<pass>
Protect the stats page
option httplog
Detailed HTTP logs

Recipes

Minimal HTTP load balancer
frontend web  bind :80  default_backend appbackend app  balance roundrobin  option httpchk GET /health  server a1 10.0.0.11:8080 check  server a2 10.0.0.12:8080 check
Route by host and redirect to HTTPS
frontend web  bind :80  bind :443 ssl crt /etc/haproxy/site.pem  http-request redirect scheme https unless { ssl_fc }  acl is_api hdr(host) -i api.example.com  use_backend api if is_api  default_backend app
Drain a server, wait, then reload
echo "set server app/a1 state drain" | socat /run/haproxy.sock stdioecho "show stat" | socat /run/haproxy.sock stdio | cut -d, -f1,2,8haproxy -c -f /etc/haproxy/haproxy.cfg \  && kill -USR2 $(cat /run/haproxy.pid)
Stats page
listen stats  bind 127.0.0.1:8404  mode http  stats enable  stats uri /stats  stats refresh 10s