HAproxy 与 Keepalived 的行为不符合预期

HAproxy 与 Keepalived 的行为不符合预期

我在公共子网中拥有两台服务器,它们分别具有公有和私有 IP。我想HAproxy配置keepalived并使其server1充当master和。server2backup

如果server1出现下滑,我想server2接管。

我们将其分类如下:

server1: private_ip1 & public_ip1
server2: private_ip2 & public_ip2

virtual_public_ip

我在两台服务器上都有一个 Flask 应用程序,其代码如下:

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)

该代码基本上将显示服务器的主机名及其 IP 地址。

以下是每个服务器的 HAproxy 和 Keepalived 配置文件。

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
    }
}

如果我打开浏览器并输入http://public_ip1:5000URL,我可以看到 server1 的主机名和virtual_public_ip

如果我打开浏览器并输入http://public_ip2:5000URL,我可以看到 server2 的主机名,并且仍然可以看到virtual_public_ip

但是如果我尝试使用虚拟 IP 本身访问该应用程序,它是不起作用的http://virtual_public_ip

我究竟做错了什么 ?

答案1

我如何让我的 haproxy 监听我的公共 IP?

最简单的解决方案是不明确地将其绑定到特定的 IP 地址。而不是这样:

frontend main
    bind private_ip1:80
    default_backend app_servers

使用:

frontend main
    bind :80
    default_backend app_servers

这会将 haproxy 绑定到您主机上的所有可用地址。如果您确实不想在私有地址上使用端口 80,则可以将其明确绑定到公共 IP:

frontend main
    bind public_ip1:80
    default_backend app_servers

为了测试你的配置,我整理了一个docker compose 堆栈这将创建一个运行 haproxy 和 keepalived 的双节点环境。请随意使用它进行测试。

相关内容