Deploying HAProxy 1.5 from source
source link: http://www.linux-admins.net/2014/09/deploying-haproxy-15-from-source.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Deploying HAProxy 1.5 from source
In an older post I showed how to create highly available HAProxy load balancer and front-end it with Pound for SSL termination. With the release of HAProxy 1.5 the SSL termination is now built in, along with a nice set of new features, such as stick tables.
In this post I'll setup HAProxy with SSL offloading and load balance HTTP, MySQL and rabbitmq in an active/passive mode.
First lets install HAProxy from source (you can of course use a package, but I'll be using Debian Squeeze for this deployment):
[root@server ~] apt-get install libpcre3-dev libssl-dev [root@server ~] wget http://www.haproxy.org/download/1.5/src/haproxy-1.5.4.tar.gz [root@server ~] tar zxfv haproxy-1.5.4.tar.gz [root@server ~] cd haproxy-1.5.4/ [root@server haproxy-1.5.4] make TARGET=custom CPU=native USE_PCRE=1 USE_LIBCRYPT=1 USE_LINUX_SPLICE=1 USE_LINUX_TPROXY=1 USE_OPENSSL=yes [root@server haproxy-1.5.4] make install [root@server haproxy-1.5.4] useradd -M haproxy
[root@server ~] cat /etc/init.d/haproxy #!/bin/sh ### BEGIN INIT INFO # Provides: haproxy # Required-Start: $local_fs $network $remote_fs # Required-Stop: $local_fs $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: fast and reliable load balancing reverse proxy # Description: This file should be used to start and stop haproxy. ### END INIT INFO
# Author: Arnaud Cornet <[email protected]>
PATH=/sbin:/usr/local/sbin:/bin:/usr/bin PIDFILE=/var/run/haproxy.pid CONFIG=/etc/haproxy/haproxy.cfg HAPROXY=/usr/local/sbin/haproxy EXTRAOPTS= ENABLED=0
test -x $HAPROXY || exit 0 test -f "$CONFIG" || exit 0
if [ -e /etc/default/haproxy ]; then . /etc/default/haproxy fi
test "$ENABLED" != "0" || exit 0
[ -f /etc/default/rcS ] && . /etc/default/rcS . /lib/lsb/init-functions
haproxy_start() { start-stop-daemon --start --pidfile "$PIDFILE" \ --exec $HAPROXY -- -f "$CONFIG" -D -p "$PIDFILE" \ $EXTRAOPTS || return 2 return 0 }
haproxy_stop() { if [ ! -f $PIDFILE ] ; then # This is a success according to LSB return 0 fi for pid in $(cat $PIDFILE) ; do /bin/kill $pid || return 4 done rm -f $PIDFILE return 0 }
haproxy_reload() { $HAPROXY -f "$CONFIG" -p $PIDFILE -D $EXTRAOPTS -sf $(cat $PIDFILE) \ || return 2 return 0 }
haproxy_status() { if [ ! -f $PIDFILE ] ; then # program not running return 3 fi
for pid in $(cat $PIDFILE) ; do if ! ps --no-headers p "$pid" | grep haproxy > /dev/null ; then # program running, bogus pidfile return 1 fi done
return 0 }
case "$1" in start) log_daemon_msg "Starting haproxy" "haproxy" haproxy_start ret=$? case "$ret" in 0) log_end_msg 0 ;; 1) log_end_msg 1 echo "pid file '$PIDFILE' found, haproxy not started." ;; 2) log_end_msg 1 ;; esac exit $ret ;; stop) log_daemon_msg "Stopping haproxy" "haproxy" haproxy_stop ret=$? case "$ret" in 0|1) log_end_msg 0 ;; 2) log_end_msg 1 ;; esac exit $ret ;; reload|force-reload) log_daemon_msg "Reloading haproxy" "haproxy" haproxy_reload case "$?" in 0|1) log_end_msg 0 ;; 2) log_end_msg 1 ;; esac ;; restart) log_daemon_msg "Restarting haproxy" "haproxy" haproxy_stop haproxy_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; 2) log_end_msg 1 ;; esac ;; status) haproxy_status ret=$? case "$ret" in 0) echo "haproxy is running." ;; 1) echo "haproxy dead, but $PIDFILE exists." ;; *) echo "haproxy not running." ;; esac exit $ret ;; *) echo "Usage: /etc/init.d/haproxy {start|stop|reload|restart|status}" exit 2 ;; esac
:
[root@server ~] chmod u+x /etc/init.d/haproxy [root@server ~] cat /etc/default/haproxy # Set ENABLED to 1 if you want the init script to start haproxy. ENABLED=1
[root@server ~] mkdir /etc/haproxy [root@server ~] cat /etc/haproxy/haproxy.cfg
global log 127.0.0.1 local1 log-tag haproxy maxconn 4096 user haproxy group haproxy daemon stats socket /var/run/haproxy.sock mode 600 level admin stats timeout 2m tune.ssl.default-dh-param 2048
defaults log global mode http timeout connect 5000ms timeout client 50000ms timeout server 50000ms option dontlognull option http-server-close
peers HAPEERS peer haproxy-n01 10.13.238.51:5555 peer haproxy-n02 10.13.238.51:5555
frontend http bind 10.13.238.21:80 reqadd X-Forwarded-Proto:\ http default_backend http_nodes
frontend https-terminated bind 10.13.238.22:443 ssl crt /etc/ssl/certs/api.example.net.pem ciphers RC4+SHA:!aNULL:!MD5 no-sslv3 option httpclose option forwardfor option httplog clf reqadd X-Forwarded-Proto:\ https default_backend https-terminated_nodes
frontend mysql mode tcp bind 10.13.238.19:3306 timeout client 168h default_backend mysql_nodes log global option tcplog option logasap
frontend rabbitmq mode tcp bind 10.13.238.20:5672 timeout client 168h default_backend rabbitmq_nodes log global option tcplog option logasap
backend http_nodes mode http balance leastconn option httpclose option forwardfor option redispatch # This check will fail a node on codes that are not 2xx or 3xx option httpchk GET / # This check will fail a node on 5xx codes only # http-check expect ! rstatus ^5 cookie JSESSIONID prefix server apt-n01 10.13.238.39:80 check inter 5000
backend https-terminated_nodes mode http balance roundrobin cookie JSESSIONID prefix option redispatch option httpchk GET / server api-n01 10.13.238.37:8888 check inter 5000 server api-n02 10.13.238.38:8888 check inter 5000
backend mysql_nodes mode tcp balance roundrobin option mysql-check user haproxy_check stick-table type ip size 20k peers HAPEERS stick on dst timeout server 168h server mysql-n01 10.13.238.53:3306 check server mysql-n02 10.13.238.54:3306 check backup
backend rabbitmq_nodes mode tcp balance roundrobin stick-table type ip size 20k peers HAPEERS stick on dst timeout server 168h server rabbitmq-n01 10.13.238.35:5672 check server rabbitmq-n02 10.13.238.36:5672 check backup
[root@server ~] apt-get install socat [root@server ~] socat /var/run/haproxy.sock readline # Or on newer versions of socat: # socat /var/run/haproxy.sock stdio prompt
> show info Name: HAProxy Version: 1.5.4 Release_date: 2014/09/02 Nbproc: 1 Process_num: 1 Pid: 17066 Uptime: 0d 1h07m55s Uptime_sec: 4075 Memmax_MB: 0 Ulimit-n: 8248 Maxsock: 8248 Maxconn: 4096 Hard_maxconn: 4096 CurrConns: 313 CumConns: 1792 CumReq: 27874 MaxSslConns: 0 CurrSslConns: 0 CumSslConns: 537 Maxpipes: 0 PipesUsed: 0 PipesFree: 0 ConnRate: 1 ConnRateLimit: 0 MaxConnRate: 68 SessRate: 1 SessRateLimit: 0 MaxSessRate: 68 SslRate: 0 SslRateLimit: 0 MaxSslRate: 5 SslFrontendKeyRate: 0 SslFrontendMaxKeyRate: 6 SslFrontendSessionReuse_pct: 0 SslBackendKeyRate: 0 SslBackendMaxKeyRate: 0 SslCacheLookups: 0 SslCacheMisses: 0 CompressBpsIn: 0 CompressBpsOut: 0 CompressBpsRateLim: 0 Tasks: 345 Run_queue: 1 Idle_pct: 100 node: zxtm-n01 description:
> quit
[root@server ~] echo "show stat" | socat - /var/run/haproxy.sock | grep -E "^rabbit|pxname" | tr -s ',' ' ' | tr -d '#' | column -t pxname svname qcur qmax scur smax slim stot bin bout dreq dresp ereq econ eresp wretr wredis status weight act bck chkfail chkdown lastchg downtime qlimit pid iid sid throttle lbtot tracked type rate rate_lim rate_max check_status check_code check_duration hrsp_1xx hrsp_2xx hrsp_3xx hrsp_4xx hrsp_5xx hrsp_other hanafail req_rate req_rate_max req_tot cli_abrt srv_abrt comp_in comp_out comp_byp comp_rsp lastsess last_chk last_agt qtime ctime rtime ttime rabbitmq FRONTEND 194 194 2000 194 0 0 0 0 0 OPEN 1 6 0 0 0 0 44 0 0 0 0 0 0 0 rabbitmq_nodes rabbitmq-n01 0 0 194 194 194 0 0 0 0 0 0 0 UP 1 1 0 0 0 740 0 1 14 1 1 2 0 44 L4OK 0 0 0 0 592 0 0 0 0 rabbitmq_nodes rabbitmq-n02 0 0 0 0 0 0 0 0 0 0 0 0 UP 1 0 1 0 0 740 0 1 14 2 0 2 0 0 L4OK 0 0 0 0 -1 0 0 0 0 rabbitmq_nodes BACKEND 0 0 194 194 2000 194 0 0 0 0 0 0 0 0 UP 1 1 1 0 740 0 1 14 0 1 1 0 44 0 0 0 0 0 0 592 0 0 0 0
[root@server ~] echo "disable server http_nodes/apt-n01" | socat stdio /var/run/haproxy.sock
listen stats :8080 mode http stats enable stats hide-version stats realm Haproxy\ Statistics stats uri / stats auth admin:yourpassword
[root@server ~] apt-get install hatop [root@server ~] hatop -s /var/run/haproxy.sock
To setup MySQL and RabbitMQ in an active/passive mode, where only one of the servers will be accepting connections, and when the main server comes back up after a failure the connections will still stick to the backup server, you specify the "backup" option and define a stick-table on line 87 and line 83.
One more option worth mentioning is the MySQL health check specified on line 82. The check consists of sending two MySQL packets, one Client Authentication packet, and one QUIT packet, to correctly close the MySQL session, using the specified user - in this case haproxy_check - so make sure you create it first:
mysql> USE mysql; mysql> INSERT INTO user (Host,User) values ('10.13.238.51','haproxy_check'); mysql> FLUSH PRIVILEGES;
backend redis_nodes mode tcp option tcplog option tcp-check tcp-check send AUTH\ somepassword\r\n tcp-check expect string +OK tcp-check send PING\r\n tcp-check expect string +PONG tcp-check send info\ replication\r\n tcp-check expect string role:master tcp-check send QUIT\r\n tcp-check expect string +OK server redis_node1 192.168.1.10:6379 maxconn 4096 check inter 5s server redis_node2 192.168.1.20:6379 maxconn 4096 check inter 5s server redis_node3 192.168.1.30:6379 maxconn 4096 check inter 5s
In the example above HAProxy queries Redis nodes about their role, and it will fail-over only if a back-end became the new master. If Sentinel is controlling the cluster and a new master is elected HAProxy will fail-over traffic to it.
To allow HAProxy to send separate logs to rsyslog you can use a file similar to this:
[root@server ~] cat /etc/rsyslog.d/haproxy.conf $ModLoad imudp $UDPServerAddress 127.0.0.1 $UDPServerRun 514
if $syslogfacility-text == 'local1' and $msg contains 'rabbitmq' then /var/log/haproxy_rabbitmq.log if $syslogfacility-text == 'local1' and $msg contains 'http' then /var/log/haproxy_api.log if $syslogfacility-text == 'local1' and $msg contains 'mysql' then /var/log/haproxy_mysql.log if $syslogfacility-text == 'local1' and ($msg contains 'UP' or $msg contains 'DOWN') then /var/log/haproxy_backends.log
local1.* -/var/log/haproxy.log & ~
[root@server ~] /etc/init.d/rsyslog restart [root@server ~] /etc/init.d/haproxy start
Resources:
[1]. http://cbonte.github.io/haproxy-dconv/configuration-1.5.html
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK