Three-node HAProxy with Keepalived
1. Configure servers
2. Configure HAProxy on all three nodes
3. Configure keepalived
4. Bind to non-local interfaces
5. Syslog config
6. Configure postfix on all three to just send email
I am using these three-node configuration with HAProxy as LB and reverse proxy for SMTP, IMAP, MariaDB Galera Cluster.
- srv10 is master for SMTP
- srv11 is master for mariadb galera cluster02
- srv27 is master for IMAP
All servers - CentOS 7
1. Configure servers
yum install epel-release
yum update
/etc/sysconfig/selinux
permissive
systemctl disable NetworkManager
systemctl disable firewalld
systemctl enable network.service
yum install iptables-services
systemctl enable iptables.service
yum install haproxy
yum install keepalived
systemctl enable haproxy
systemctl enable keepalived
/etc/hosts
192.168.122.144 srv20.domain.dom srv20
192.168.122.145 srv21.domain.dom srv21
192.168.122.146 srv10.domain.dom srv10
192.168.122.147 srv11.domain.dom srv11
192.168.122.128 srv27.domain.dom srv27
2. Configure HAProxy on all three nodes
On node srv10:
/etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# HAProxy statistics backend
#---------------------------------------------------------------------
listen srv10-stats 192.168.122.142:80
mode http
stats enable
stats show-legends
stats refresh 5s
stats uri /
stats realm Haproxy\ Statistics
stats auth username:password
stats admin if TRUE
#---------------------------------------------------------------------
# Frontend for mariadb galera cluster
#---------------------------------------------------------------------
frontend srv10-cluster02
bind 192.168.122.143:3306
mode tcp
log global
option tcplog
default_backend srv10-galera-cluster02
#---------------------------------------------------------------------
# Backend for mariadb galera cluster
#---------------------------------------------------------------------
backend srv10-galera-cluster02
balance leastconn
option httpchk
mode tcp
option log-health-checks
option tcplog
server srv20 192.168.122.144:3306 check port 9200 inter 300s weight 1 maxconn 5000 rise 2 fall 2
server srv21 192.168.122.145:3306 check port 9200 inter 300s weight 1 maxconn 5000 rise 2 fall 2
#---------------------------------------------------------------------
# SMTP postfix
#---------------------------------------------------------------------
listen srv10-smtp 192.168.122.139:25
mode tcp
log global
option tcplog
option log-health-checks
no option http-server-close
balance roundrobin
option smtpchk HELO srv10.domain.dom
server srv14 192.168.122.140:25 send-proxy check inter 900s
server srv15 192.168.122.141:25 send-proxy check inter 900s
#---------------------------------------------------------------------
# Dovecot IMAP and IPMAS
#---------------------------------------------------------------------
listen srv10-imaps 192.168.122.122:993
timeout client 1m
no option http-server-close
option log-health-checks
stick store-request src
stick-table type ip size 200k expire 30m
mode tcp
option tcplog
server srv31 192.168.122.123:10993 check send-proxy-v2 inter 1900s
On node srv11:
/etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# HAProxy statistics backend
#---------------------------------------------------------------------
listen srv11-stats 192.168.122.142:80
mode http
stats enable
stats show-legends
stats refresh 5s
stats uri /
stats realm Haproxy\ Statistics
stats auth username:password
stats admin if TRUE
#---------------------------------------------------------------------
# Frontend for mariadb galera cluster
#---------------------------------------------------------------------
frontend srv11-cluster02
bind 192.168.122.143:3306
mode tcp
log global
option tcplog
default_backend srv11-galera-cluster02
#---------------------------------------------------------------------
# Backend for mariadb galera cluster
#---------------------------------------------------------------------
backend srv11-galera-cluster02
balance leastconn
option httpchk
mode tcp
option log-health-checks
option tcplog
server srv20 192.168.122.144:3306 check port 9200 inter 300s weight 1 maxconn 5000 rise 2 fall 2
server srv21 192.168.122.145:3306 check port 9200 inter 300s weight 1 maxconn 5000 rise 2 fall 2
#---------------------------------------------------------------------
# SMTP postfix
#---------------------------------------------------------------------
listen srv11-smtp 192.168.122.139:25
mode tcp
log global
option tcplog
option log-health-checks
no option http-server-close
balance roundrobin
option smtpchk HELO srv11.domain.dom
server srv14 192.168.122.140:25 send-proxy check inter 900s
server srv15 192.168.122.141:25 send-proxy check inter 900s
#---------------------------------------------------------------------
# Dovecot IMAP and IPMAS
#---------------------------------------------------------------------
listen srv11-imaps 192.168.122.122:993
timeout client 1m
no option http-server-close
option log-health-checks
stick store-request src
stick-table type ip size 200k expire 30m
mode tcp
option tcplog
server srv31 192.168.122.123:10993 check send-proxy-v2 inter 1900s
On node srv27:
/etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# HAProxy statistics backend
#---------------------------------------------------------------------
listen srv27-stats 192.168.122.142:80
mode http
stats enable
stats show-legends
stats refresh 5s
stats uri /
stats realm Haproxy\ Statistics
stats auth username:password
stats admin if TRUE
#---------------------------------------------------------------------
# Frontend for mariadb galera cluster
#---------------------------------------------------------------------
frontend srv27-cluster02 # change on 2nd HAProxy
bind 192.168.122.143:3306
mode tcp
log global
option tcplog
default_backend srv27-galera-cluster02
#---------------------------------------------------------------------
# Backend for mariadb galera cluster
#---------------------------------------------------------------------
backend srv27-galera-cluster02
balance leastconn
option httpchk
mode tcp
option log-health-checks
option tcplog
server srv20 192.168.122.144:3306 check port 9200 inter 300s weight 1 maxconn 5000 rise 2 fall 2
server srv21 192.168.122.145:3306 check port 9200 inter 300s weight 1 maxconn 5000 rise 2 fall 2
#---------------------------------------------------------------------
# SMTP postfix
#---------------------------------------------------------------------
listen srv27-smtp 192.168.122.139:25
mode tcp
log global
option tcplog
option log-health-checks
no option http-server-close
balance roundrobin
option smtpchk HELO srv10.domain.dom
server srv14 192.168.122.140:25 send-proxy check inter 900s
server srv15 192.168.122.141:25 send-proxy check inter 900s
#---------------------------------------------------------------------
# Dovecot IMAP and IPMAS
#---------------------------------------------------------------------
listen srv27-imaps 192.168.122.122:993
timeout client 1m
no option http-server-close
option log-health-checks
stick store-request src
stick-table type ip size 200k expire 30m
mode tcp
option tcplog
server srv31 192.168.122.123:10993 check send-proxy-v2 inter 1900s
3. Configure keepalived
On node srv10:
/etc/keepalived/keepalived.conf
! Configuration File for keepalived - srv10
global_defs {
notification_email {
admin@domain.dom
}
notification_email_from srv10@domain.dom
smtp_server 192.168.122.139
smtp_connect_timeout 30
router_id srv10
}
vrrp_script check_haproxy {
script "killall -0 haproxy"
interval 2 # every 2 seconds
weight 2 # add 2 points if OK
}
vrrp_instance cluster02 {
state BACKUP
interface ens160
virtual_router_id 51
priority 99
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.143
}
track_script {
check_haproxy
}
}
vrrp_instance haproxy-stats {
state BACKUP
interface ens160
virtual_router_id 52
priority 99
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.142
}
track_script {
check_haproxy
}
}
vrrp_instance mail {
state MASTER
interface ens160
virtual_router_id 53
priority 101
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.139
}
track_script {
check_haproxy
}
}
vrrp_instance imap {
state BACKUP
interface ens160
virtual_router_id 54
priority 100
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.122
}
track_script {
check_haproxy
}
}
On node srv11:
/etc/keepalived/keepalived.conf
! Configuration File for keepalived - srv11
global_defs {
notification_email {
admin@domain.dom
}
notification_email_from srv11@domain.dom
smtp_server 192.168.122.139
smtp_connect_timeout 30
router_id srv11
}
vrrp_script check_haproxy {
script "killall -0 haproxy"
interval 2 # every 2 seconds
weight 2 # add 2 points if OK
}
vrrp_instance cluster02 {
state MASTER
interface ens160
virtual_router_id 51
priority 101
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.143
}
track_script {
check_haproxy
}
}
vrrp_instance haproxy-stats {
state BACKUP
interface ens160
virtual_router_id 52
priority 100
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.142
}
track_script {
check_haproxy
}
}
vrrp_instance mail {
state BACKUP
interface ens160
virtual_router_id 53
priority 100
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.139
}
track_script {
check_haproxy
}
}
vrrp_instance imap {
state BACKUP
interface ens160
virtual_router_id 54
priority 99
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.122
}
track_script {
check_haproxy
}
}
On node srv27:
/etc/keepalived/keepalived.conf
! Configuration File for keepalived - srv27
global_defs {
notification_email {
admin@domain.dom
}
notification_email_from srv27@domain.dom
smtp_server 192.168.122.139
smtp_connect_timeout 30
router_id srv27
}
vrrp_script check_haproxy {
script "killall -0 haproxy"
interval 2 # every 2 seconds
weight 2 # add 2 points if OK
}
vrrp_instance cluster02 {
state BACKUP
interface ens160
virtual_router_id 51
priority 100
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.143
}
track_script {
check_haproxy
}
}
vrrp_instance haproxy-stats {
state BACKUP
interface ens160
virtual_router_id 52
priority 101
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.142
}
track_script {
check_haproxy
}
}
vrrp_instance mail {
state BACKUP
interface ens160
virtual_router_id 53
priority 99
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.139
}
track_script {
check_haproxy
}
}
vrrp_instance imap {
state MASTER
interface ens160
virtual_router_id 54
priority 101
smtp_alert
advert_int 1
virtual_ipaddress {
192.168.122.122
}
track_script {
check_haproxy
}
}
4. Bind to non-local interfaces
echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind
/etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
5. Syslog config
/etc/rsyslog.d/haproxy.conf
local2.=info /var/log/haproxy-access.log
local2.notice /var/log/haproxy-info.log
/etc/rsyslog.conf
# Provides UDP syslog reception
#$ModLoad imudp
#$UDPServerRun 514
### added
$ModLoad imudp
$UDPServerRun 514
6. Configure postfix on all three to just send email
on srv10:
mynetworks_style = host
# Setting postfix to only send email:
myhostname = srv10.domain.dom
myorigin = $mydomain
relayhost = $mydomain
inet_interfaces = loopback-only
mydestination =
on srv11:
mynetworks_style = host
# Setting postfix to only send email:
myhostname = srv11.domain.dom
myorigin = $mydomain
relayhost = $mydomain
inet_interfaces = loopback-only
mydestination =
on srv27:
mynetworks_style = host
# Setting postfix to only send email:
myhostname = srv27.domain.dom
myorigin = $mydomain
relayhost = $mydomain
inet_interfaces = loopback-only
mydestination =