Split-view DNS offers a simple way to split traffic up based on the IP address
of the client's source DNS server. In the case of ftp.osuosl.org
, we split
the DNS based on what IPs are routed via Internet2. When used in combination
with Round Robin DNS, it can be a simple and useful load balancing tool.
# Querying on campus gives us one server
$ host ftp.osuosl.org
ftp.osuosl.org has address 140.211.166.134
# Querying an OpenDNS server, gives us a RR DNS answer
$ host ftp.osuosl.org 208.67.222.222
Using domain server:
Name: 208.67.222.222
Address: 208.67.222.222#53
Aliases:
ftp.osuosl.org has address 64.50.233.100
ftp.osuosl.org has address 64.50.236.52
Taken from the HAProxy documentation
Asymmetric load | Ratio to be manually assigned to a backend server |
Priority Activation | Add or remove backend servers based on the load or other metrics |
SSL Offload & Acceleration | Specialized hardware to offload SSL CPU demand on high traffic sites |
DDoS attack protection | Mitigate DDoS attacks using SYN cookies and verifying a full TCP handshake before sending off to the backend server |
HTTP compression | Gzip compresses the HTTP objects to reduce bandwidth but can increase CPU usage |
TCP offload | Consolidate multiple HTTP requests from multiple clients into a single TCP socket to the backend servers |
Health checking | Balance pools the backend application server to see if its functioning correctly |
HTTP caching | Balancer stores the static content in memory to serve the content faster |
mod_proxy
module.
Provides an easy way to set up but tends to use more memory than the others.What else?
frontend http
maxconn 2000
bind 0.0.0.0:80
default_backend servers
frontend https
maxconn 2000
bind 0.0.0.0:443 ssl crt /etc/pki/tls/mycert.pem
default_backend servers
backend servers
server mybackendserver 10.0.0.1:80
# server <name> <ip>:<port> [options]
Check out the docs! http://www.haproxy.org/
frontend http
maxconn 2000
bind 0.0.0.0:80
acl cs312 hdr(host) cs312.osuosl.org
acl osl hdr(host) osuosl.org
use_backend cs312_servers if cs312
use_backend osl_servers if osl
default_backend unrecognized_site
backend cs312_servers
server cs312-1 10.0.0.1:80
server cs312-2 10.0.0.2:80
backend osl_servers
server osl-1 10.0.1.1:80
server osl-2 10.0.1.2:80
backend unrecognized_site
server others 10.0.255.1:80
Create a new VM
$ yum install haproxy
$ systemctl start haproxy
HAProxy by default sends logs to localhost so we need to change the config to send it directly to systemd.
Add the following to /etc/haproxy/haproxy.cfg
global
log /dev/log local0 info
global
log /dev/log local0 info
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout check 2s
timeout client 1m
timeout connect 10s
timeout http-keep-alive 10s
timeout http-request 10s
timeout queue 1m
timeout server 1m
maxconn 3000
This script sets up a set of simple Python web servers that serve a simple web page using systemd.
$ wget -O- http://cs312.osuosl.org/_static/hw/haproxy.sh | bash
Append the frontend and backend configuration to the haproxy.cfg
file.
Try accessing the website using your VM's IP, what do you see?
frontend http
bind 0.0.0.0:80
default_backend servers
backend servers
server www1 localhost:8003 check
server www2 localhost:8004 check
HAProxy provides a nice web page to display stats. To enable it, add the following to your config and reload haproxy.
It's best to secure this port. It can be used to generate graphs as well.
listen admin
bind 0.0.0.0:22002
mode http
stats uri /
Let's try taking down the www2
backend and see what happens.
$ systemctl stop cs312-www@8004
backend servers
balance roundrobin
server www1 localhost:8003 check
server www2 localhost:8004 check
backend servers
balance roundrobin
server www1 localhost:8003 weight 50 check
server www2 localhost:8004 weight 100 check
ACLs enable you to direct traffic based on incoming traffic.
frontend http
bind 0.0.0.0:80
acl url_www1 path_beg /www1
acl url_www2 path_beg /www2
default_backend servers
Let's send traffic for the sub directory /www1 to www1 and /www2 to www2.
frontend http
bind 0.0.0.0:80
acl url_www1 path_beg /www1
acl url_www2 path_beg /www2
use_backend www1 if url_www1
use_backend www2 if url_www2
default_backend servers
backend servers
balance roundrobin
server www1 localhost:8003 weight 50 check
server www2 localhost:8004 weight 100 check
backend www1
server www1 localhost:8003 weight 50 check
backend www2
server www2 localhost:8004 weight 50 check
reqrep
replaces a regular expression with a string in an HTTP request line.
reqrep <search> <string> [{if | unless} <cond>]
Replace /www1
with /
at the beginning of any request path:
<snip>
backend www1
reqrep ^([^\ :]*)\ /www1[/]?(.*) \1\ /\2
server www1 localhost:8003 weight 50 check
backend www2
reqrep ^([^\ :]*)\ /www2[/]?(.*) \1\ /\2
server www2 localhost:8004 weight 50 check
Let's add a health check.
backend servers
balance roundrobin
option httpchk GET /index.html
server www1 localhost:8003 weight 50 check
server www2 localhost:8004 weight 100 check
Also read up on http-check expect
.