I have two servers in a public subnet with both public and private IPs. I want to configure HAproxy
with keepalived
and make server1
act as the master
and server2
as backup
.
If server1
goes down, I want server2
to takeover.
Let’s classify it as follows:
server1: private_ip1 & public_ip1
server2: private_ip2 & public_ip2
virtual_public_ip
I have a flask app on both servers with the following code:
app.py
from flask import *
import socket
app = Flask(__name__)
@app.route("/")
def index():
hostname = socket.gethostname()
ip = socket.gethostbyname(hostname)
return f"<h1>Hello from computer {hostname} with ip {ip}</h1>"
if __name__ == "__main__":
app.run(debug=False)
The code will basically display the hostname of the server and its IP address.
Below is the config file for HAproxy and Keepalived for each servers.
server1 HAproxy
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
# utilize system-wide crypto-policies
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
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 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
frontend main
bind *:80
default_backend app_servers
backend app_servers
balance roundrobin
server haproxy-01 public_ip1:5000 check
server haproxy-02 public_ip2:5000 backup
server1 keepalived
global_defs {
enable_script_security
script_user th3pl4gu3
}
vrrp_script chk_haproxy {
script "pidof haproxy"
interval 2
weight 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 101
virtual_ipaddress {
virtual_public_ip
}
track_script {
chk_haproxy
}
}
server2 HAproxy
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
# utilize system-wide crypto-policies
ssl-default-bind-ciphers PROFILE=SYSTEM
ssl-default-server-ciphers PROFILE=SYSTEM
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 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
frontend main
bind *:80
default_backend app_servers
backend app_servers
balance roundrobin
server haproxy-01 public_ip1:5000 backup
server haproxy-02 public_ip2:5000 check
server2 keepalived
global_defs {
enable_script_security
script_user th3pl4gu3
}
vrrp_script chk_haproxy {
script "pidof haproxy"
interval 2
weight 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
virtual_ipaddress {
virtual_public_ip
}
track_script {
chk_haproxy
}
}
If i go on my browser and enter http://public_ip1:5000
in the URL, i can see the hostname for server1 and the virtual_public_ip
.
If i go on my browser and enter http://public_ip2:5000
in the URL, i can see the hostname for server2 and still the virtual_public_ip
.
But if i try to access the app. using the virtual IP itself, it doesn’t work http://virtual_public_ip
.
What am i doing wrong ?