高可用性是系统设计的一项功能,允许应用程序在发生故障时自动重新启动或将工作重新路由到另一个有能力的系统。就服务器而言,建立高可用系统需要几种不同的技术。必须有一个可以重定向工作的组件,并且必须有一种机制来监视故障并在检测到中断时转换系统。
The keepalived
守护进程可用于监视服务或系统,并在出现问题时自动故障转移到备用数据库。在本指南中,我们将演示如何使用keepalived
为您的负载均衡器设置高可用性。我们将配置一个保留IP地址可以在两个有能力的负载均衡器之间移动。这些都将配置为在两个后端 Web 服务器之间分配流量。如果主负载均衡器出现故障,保留的 IP 将自动移至第二个负载均衡器,从而允许服务恢复。
Note: DigitalOcean 负载均衡器是一种完全托管、高度可用的负载平衡服务。负载均衡器服务可以扮演与此处描述的手动高可用性设置相同的角色。关注我们的设置负载均衡器指南如果您想评估该选项。
为了完成本指南,您需要在 DigitalOcean 帐户中创建四个 Ubuntu 14.04 服务器。所有服务器必须位于同一数据中心内,并且应启用专用网络。
在每台服务器上,您都需要配置一个非 root 用户sudo
使用权。您可以关注我们的Ubuntu 14.04 初始服务器设置指南了解如何设置这些用户。
在开始实际配置基础设施组件之前,最好收集有关每台服务器的一些信息。
要完成本指南,您将需要获得有关服务器的以下信息:
-
网络服务器:私有IP地址
-
负载均衡器私有和锚定 IP 地址
查找 Droplet 的私有 IP 地址的最简单方法是使用curl
从 DigitalOcean 元数据服务获取私有 IP 地址。该命令应该从您的 Droplet 中运行。在每个 Droplet 上,键入:
-
curl 169.254.169.254/元数据/v1/接口/私有/0/ipv4/地址&& echo
正确的 IP 地址应打印在终端窗口中:
Output
10.132.20.236
“锚定 IP”是连接到 DigitalOcean 服务器时保留 IP 将绑定到的本地私有 IP 地址。它只是常规的别名eth0
地址,在虚拟机管理程序级别实现。
获取该值的最简单、最不容易出错的方法是直接从 DigitalOcean 元数据服务获取。使用curl
,您可以通过键入以下内容来访问每台服务器上的此端点:
-
curl 169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/地址&& echo
锚点 IP 将打印在自己的行上:
Output
10.17.1.18
收集完上述数据后,我们可以继续配置我们的服务。
Note
在此设置中,为 Web 服务器层选择的软件具有相当的互换性。本指南将使用 Nginx,因为它是通用的并且相当容易配置。如果您更喜欢 Apache 或(可生产的)特定于语言的 Web 服务器,请随意使用它。 HAProxy 将简单地将客户端请求传递到后端 Web 服务器,后端 Web 服务器可以像处理直接客户端连接一样处理请求。
我们将从设置后端 Web 服务器开始。这两个服务器将提供完全相同的内容。他们只接受通过其私有 IP 地址进行的 Web 连接。这将有助于确保流量定向通过我们稍后将配置的两个 HAProxy 服务器之一。
在负载均衡器后面设置 Web 服务器允许我们在一些数量相同的 Web 服务器之间分配请求负担。随着流量需求的变化,我们可以通过在这一层添加或删除 Web 服务器来轻松扩展以满足新的需求。
我们将在我们的网络服务机器上安装 Nginx 以提供此功能。
首先使用您的登录sudo
用户到您希望用作 Web 服务器的两台计算机。更新每个 Web 服务器上的本地包索引并通过键入以下内容安装 Nginx:
-
sudo apt-get update
-
sudo apt-get install nginx
接下来,我们将配置 Nginx 实例。我们想告诉 Nginx 只监听服务器私有 IP 地址上的请求。此外,我们将仅处理来自两个负载均衡器的私有 IP 地址的请求。
要进行这些更改,请打开每个 Web 服务器上的默认 Nginx 服务器块文件:
-
sudo nano/etc/nginx/sites-available/default
首先,我们将修改listen
指令。改变listen
监听当前指令Web 服务器的私有 IP 地址在端口 80 上。删除多余的listen
线。它应该看起来像这样:
/etc/nginx/sites-available/default
server {
listen web_server_private_IP:80;
. . .
之后我们会设置两个allow
指令以允许源自我们两个负载均衡器的私有 IP 地址的流量。我们将跟进此事deny all
禁止所有其他流量的规则:
/etc/nginx/sites-available/default
server {
listen web_server_private_IP:80;
allow load_balancer_1_private_IP;
allow load_balancer_2_private_IP;
deny all;
. . .
完成后保存并关闭文件。
通过键入以下内容来测试您所做的更改是否代表有效的 Nginx 语法:
如果没有报告问题,请通过键入以下内容重新启动 Nginx 守护程序:
要测试您的 Web 服务器是否受到正确限制,您可以使用以下命令发出请求curl
来自不同地点。
在您的网络服务器本身上,您可以通过键入以下内容来尝试本地内容的简单请求:
由于我们在 Nginx 服务器块文件中设置的限制,该请求实际上会被拒绝:
Output
curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused
这是预期的,反映了我们试图实现的行为。
现在,从任一负载均衡器,我们可以请求任意一个 Web 服务器的公共 IP 地址:
-
curl web_server_public_IP
再一次,这应该会失败。 Web 服务器不会监听公共接口,此外,当使用公共 IP 地址时,我们的 Web 服务器不会在负载均衡器的请求中看到允许的私有 IP 地址:
Output
curl: (7) Failed to connect to web_server_public_IP port 80: Connection refused
但是,如果我们修改调用以使用 Web 服务器的私有IP地址,它应该可以正常工作:
-
curl web_server_private_IP
默认的 Nginxindex.html
应返回页面:
Output
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
. . .
从两个负载均衡器到两个 Web 服务器进行测试。对私有 IP 地址的每个请求都应该成功,而对公共地址的每个请求都应该失败。
一旦证明了上述行为,我们就可以继续前进。我们的后端 Web 服务器配置现已完成。
接下来,我们将设置 HAProxy 负载均衡器。它们都位于我们的 Web 服务器前面,并在两个后端服务器之间分割请求。这些负载均衡器是完全冗余的。在任何给定时间只有一个会收到流量。
HAProxy 配置会将请求传递到两个 Web 服务器。负载均衡器将侦听其锚定 IP 地址上的请求。如前所述,这是保留 IP 地址在附加到 Droplet 时将绑定到的 IP 地址。这可确保仅转发源自保留 IP 地址的流量。
我们需要在负载均衡器上采取的第一步是安装haproxy
包裹。我们可以在默认的 Ubuntu 存储库中找到它。更新负载均衡器上的本地包索引并通过键入以下内容安装 HAProxy:
-
sudo apt-get update
-
sudo apt-get install哈代理
在处理 HAProxy 时我们需要修改的第一项是/etc/default/haproxy
文件。现在在编辑器中打开该文件:
该文件确定 HAProxy 是否会在引导时启动。由于我们希望该服务在每次服务器开机时自动启动,因此我们需要更改ENABLED
to “1”:
/etc/默认/haproxy
# Set ENABLED to 1 if you want the init script to start haproxy.
ENABLED=1
# Add extra flags here.
#EXTRAOPTS="-de -m 16"
进行上述编辑后保存并关闭文件。
接下来,我们可以打开主要的 HAProxy 配置文件:
-
sudo nano/etc/haproxy/haproxy.cfg
我们需要调整的第一项是 HAProxy 的运行模式。我们要配置 TCP(或第 4 层)负载平衡。为此,我们需要改变mode
线在default
部分。我们还应该立即更改处理日志的选项:
/etc/haproxy/haproxy.cfg
. . .
defaults
log global
mode tcp
option tcplog
. . .
在文件的末尾,我们需要定义前端配置。这将决定 HAProxy 如何侦听传入连接。我们将 HAProxy 绑定到负载均衡器锚点 IP 地址。这将允许它监听来自保留 IP 地址的流量。为了简单起见,我们将前端称为“www”。我们还将指定一个默认后端来将流量传递到(我们稍后将对其进行配置):
/etc/haproxy/haproxy.cfg
. . .
defaults
log global
mode tcp
option tcplog
. . .
frontend www
bind load_balancer_anchor_IP:80
default_backend nginx_pool
接下来,我们可以配置后端部分。这将指定 HAProxy 将传递其收到的流量的下游位置。在我们的例子中,这将是我们配置的两个 Nginx Web 服务器的私有 IP 地址。我们将指定传统的循环平衡,并将模式再次设置为“tcp”:
/etc/haproxy/haproxy.cfg
. . .
defaults
log global
mode tcp
option tcplog
. . .
frontend www
bind load_balancer_anchor_IP:80
default_backend nginx_pool
backend nginx_pool
balance roundrobin
mode tcp
server web1 web_server_1_private_IP:80 check
server web2 web_server_2_private_IP:80 check
完成上述更改后,保存并关闭文件。
通过键入以下内容检查我们所做的配置更改是否代表有效的 HAProxy 语法:
-
sudo哈代理-f/etc/haproxy/haproxy.cfg-c
如果没有报告错误,请通过键入以下内容重新启动服务:
我们可以通过测试来确保我们的配置有效curl
again.
从负载均衡器服务器中,尝试请求本地主机、负载均衡器自己的公共 IP 地址或服务器自己的私有 IP 地址:
-
curl 127.0.0.1
-
curl load_balancer_public_IP
-
curl load_balancer_private_IP
这些都应该失败并显示类似于以下内容的消息:
Output
curl: (7) Failed to connect to address port 80: Connection refused
但是,如果您向负载均衡器发出请求锚定IP地址,它应该成功完成:
-
curl load_balancer_anchor_IP
你应该看到默认的 Nginxindex.html
页面,从两个后端 Web 服务器之一路由:
Output
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
. . .
如果此行为与您的系统的行为相符,则您的负载均衡器配置正确。
我们的实际服务现已启动并运行。然而,我们的基础设施尚未高度可用,因为如果我们的主动负载均衡器遇到问题,我们无法重定向流量。为了纠正这个问题,我们将安装keepalived
我们的负载均衡器服务器上的守护进程。如果我们的主动负载均衡器不可用,该组件将提供故障转移功能。
有一个版本keepalived
在 Ubuntu 的默认存储库中,但它已经过时并且存在一些错误,这些错误会阻止我们的配置工作。相反,我们将安装最新版本的keepalived
从源头。
在开始之前,我们应该获取构建软件所需的依赖项。这build-essential
meta-package会提供我们需要的编译工具,而libssl-dev
软件包包含 SSL 开发库keepalived
需要针对:
-
sudo apt-get install构建必要的 libssl-dev
一旦依赖关系到位,我们就可以下载 tarballkeepalived
。访问这一页查找该软件的最新版本。右键单击最新版本并复制链接地址。返回您的服务器,移至您的主目录并使用wget
获取您复制的链接:
-
cd ~
-
wget http://www.keepalived.org/software/keepalived-1.2.19.tar.gz
Use the tar
扩展存档的命令。移至结果目录:
-
tarxzvf keepalived*
-
cd保持活动*
通过键入以下内容构建并安装守护程序:
- 。/配置
-
make
-
sudo make install
该守护程序现在应该安装在两个负载平衡器系统上。
The keepalived
安装将所有二进制文件和支持文件移动到我们的系统上。然而,没有包含在内的是我们的 Ubuntu 14.04 系统的 Upstart 脚本。
我们可以创建一个非常简单的 Upstart 脚本来处理我们的keepalived
服务。打开一个名为keepalived.conf
内/etc/init
开始目录:
-
sudo nano/etc/init/keepalived.conf
在里面,我们可以从功能的简单描述开始keepalived
提供。我们将使用随附的描述man
页。接下来,我们将指定应启动和停止服务的运行级别。我们希望该服务在所有正常条件下(运行级别 2-5)都处于活动状态,并在所有其他运行级别下停止(例如,当重新启动、关闭电源或启动单用户模式时):
/etc/init/keepalived.conf
description "load-balancing and high-availability service"
start on runlevel [2345]
stop on runlevel [!2345]
由于此服务对于确保我们的 Web 服务保持可用至关重要,因此我们希望在发生故障时重新启动此服务。然后我们可以指定实际的exec
将启动服务的行。我们需要添加--dont-fork
选项,以便 Upstart 可以跟踪pid
正确:
/etc/init/keepalived.conf
description "load-balancing and high-availability service"
start on runlevel [2345]
stop on runlevel [!2345]
respawn
exec /usr/local/sbin/keepalived --dont-fork
完成后保存并关闭文件。
Upstart 文件就位后,我们现在可以继续配置keepalived
.
该服务在以下位置查找其配置文件/etc/keepalived
目录。现在在两个负载均衡器上创建该目录:
-
sudo mkdir -p/etc/keepalived
接下来,在您希望用作负载平衡器的服务器上primary服务器,创建主keepalived
配置文件。该守护进程寻找一个名为keepalived.conf
里面的/etc/keepalived
目录:
-
sudo nano/etc/keepalived/keepalived.conf
在内部,我们将首先通过打开一个为 HAProxy 服务定义健康检查vrrp_script
堵塞。这将允许keepalived
监视我们的负载均衡器是否出现故障,以便它可以发出进程已关闭的信号并开始恢复措施。
我们的检查将非常简单。每两秒,我们将检查一个名为haproxy
仍然声称pid
:
主服务器的 /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {
script "pidof haproxy"
interval 2
}
接下来,我们将打开一个名为vrrp_instance
。这是定义方式的主要配置部分keepalived
将实现高可用性。
我们将首先讲述keepalived
与同行交流eth1
,我们的私有接口。由于我们正在配置主服务器,因此我们将设置state
配置为“主”。这是初始值keepalived
将使用直到守护进程可以联系其对等方并进行选举。
在选举期间,priority
option 用于决定选举哪位成员。该决定仅基于哪台服务器具有最高的此设置数量。我们将使用“200”作为我们的主服务器:
主服务器的 /etc/keepalived/keepalived.conf
vrrp_script chk_nginx {
script "pidof nginx"
interval 2
}
vrrp_instance VI_1 {
interface eth1
state MASTER
priority 200
}
接下来,我们将为该集群组分配一个由两个节点共享的 ID。本例中我们将使用“33”。我们需要设置unicast_src_ip
to our primary负载均衡器的私有IP地址。我们将设置unicast_peer
to our 中学负载均衡器的私有IP地址:
主服务器的 /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {
script "pidof haproxy"
interval 2
}
vrrp_instance VI_1 {
interface eth1
state MASTER
priority 200
virtual_router_id 33
unicast_src_ip primary_private_IP
unicast_peer {
secondary_private_IP
}
}
接下来,我们可以为我们的系统设置一些简单的身份验证keepalived
守护进程相互通信。这只是确保所联系的对等方合法的基本措施。创建一个authentication
子块。在里面,通过设置指定密码验证auth_type
。为了auth_pass
参数,设置两个节点将使用的共享秘密。不幸的是,只有前八个字符是重要的:
主服务器的 /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {
script "pidof haproxy"
interval 2
}
vrrp_instance VI_1 {
interface eth1
state MASTER
priority 200
virtual_router_id 33
unicast_src_ip primary_private_IP
unicast_peer {
secondary_private_IP
}
authentication {
auth_type PASS
auth_pass password
}
}
接下来我们就来说说keepalived
使用我们在文件顶部创建的检查,标记为chk_haproxy
,以确定本地系统的健康状况。最后,我们将设置一个notify_master
脚本,每当该节点成为该对的“主节点”时就会执行该脚本。该脚本将负责触发保留 IP 地址重新分配。我们将立即创建此脚本:
主服务器的 /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {
script "pidof haproxy"
interval 2
}
vrrp_instance VI_1 {
interface eth1
state MASTER
priority 200
virtual_router_id 33
unicast_src_ip primary_private_IP
unicast_peer {
secondary_private_IP
}
authentication {
auth_type PASS
auth_pass password
}
track_script {
chk_haproxy
}
notify_master /etc/keepalived/master.sh
}
设置完上述信息后,保存并关闭文件。
接下来,我们将在辅助负载均衡器上创建配套脚本。打开文件位于/etc/keepalived/keepalived.conf
在您的辅助服务器上:
-
sudo nano/etc/keepalived/keepalived.conf
在内部,我们将使用的脚本在很大程度上与主服务器的脚本相同。我们需要更改的项目是:
-
state
:应在辅助服务器上将其更改为“BACKUP”,以便节点在选举发生之前初始化为备份状态。
-
priority
:该值应设置为低于主服务器的值。我们将在本指南中使用值“100”。
-
unicast_src_ip
:这应该是私有IP地址中学 server.
-
unicast_peer
:这应该包含私有IP地址primary server.
当您更改这些值时,辅助服务器的脚本应如下所示:
辅助服务器的 /etc/keepalived/keepalived.conf
vrrp_script chk_haproxy {
script "pidof haproxy"
interval 2
}
vrrp_instance VI_1 {
interface eth1
state BACKUP
priority 100
virtual_router_id 33
unicast_src_ip secondary_private_IP
unicast_peer {
primary_private_IP
}
authentication {
auth_type PASS
auth_pass password
}
track_script {
chk_haproxy
}
notify_master /etc/keepalived/master.sh
}
输入脚本并更改适当的值后,保存并关闭文件。
接下来,我们需要创建一对脚本,每当本地运行时,我们都可以使用它们将保留的 IP 地址重新分配给当前的 Droplet。keepalived
实例成为主服务器。
首先,我们将下载一个通用的 Python 脚本(由数字海洋社区经理)可用于使用 DigitalOcean API 将保留的 IP 地址重新分配给 Droplet。我们应该将此文件下载到/usr/local/bin
目录:
-
cd/usr/local/bin
-
sudo curl -LOhttp://do.co/assign-ip
此脚本允许您通过运行以下命令重新分配现有的保留 IP:
- python /usr/local/bin/assign-ip reserved_ip droplet_ID
仅当您有一个名为的环境变量时,这才有效DO_TOKEN
设置为您帐户的有效 DigitalOcean API 令牌。
为了使用上面的脚本,我们需要在我们的帐户中创建一个 DigitalOcean API 令牌。
在控制面板中,单击顶部的“API”链接。在API页面右侧,点击“生成新令牌”:
在下一页上,为您的令牌选择一个名称,然后单击“生成令牌”按钮:
在API页面上,您的新令牌将显示:
复制令牌now。出于安全目的,以后无法再次显示此令牌。如果您丢失了该令牌,则必须销毁它并创建另一个令牌。
接下来,我们将创建并分配一个保留 IP 地址以供我们的服务器使用。
在 DigitalOcean 控制面板中,单击“网络”选项卡并选择“保留 IP”导航项。从菜单中选择您的主负载均衡器进行初始分配:
将在您的帐户中创建一个新的保留 IP 地址并将其分配给指定的 Droplet:
如果您在 Web 浏览器中访问保留 IP,您应该会看到由后端 Web 服务器之一提供的默认 Nginx 页面:
复制保留的 IP 地址。您将在下面的脚本中需要该值。
现在,我们有了创建包装脚本所需的项目,该脚本将调用我们的/usr/local/bin/assign-ip
具有正确凭据的脚本。
立即创建文件both通过键入以下内容来访问您的负载均衡器:
-
sudo nano/etc/keepalived/master.sh
在内部,首先分配并导出一个名为DO_TOKEN
其中包含您刚刚创建的 API 令牌。下面,我们可以分配一个名为IP
保存您的保留 IP 地址:
/etc/keepalived/master.sh
export DO_TOKEN='digitalocean_api_token'
IP='reserved_ip_addr'
接下来,我们将使用curl
向元数据服务询问我们当前所在服务器的 Droplet ID。这将被分配给一个名为的变量ID
。我们还将询问此 Droplet 当前是否分配有保留的 IP 地址。我们将该请求的结果存储在一个名为的变量中HAS_RESERVED_IP
:
/etc/keepalived/master.sh
export DO_TOKEN='digitalocean_api_token'
IP='reserved_ip_addr'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_RESERVED_IP=$(curl -s http://169.254.169.254/metadata/v1/reserved_ip/ipv4/active)
现在,我们可以使用上面的变量来调用assign-ip
脚本。仅当保留 IP 尚未与我们的 Droplet 关联时,我们才会调用该脚本。这将有助于最大限度地减少 API 调用,并有助于在主服务器状态在服务器之间快速切换的情况下防止对 API 的冲突请求。
为了处理预留 IP 已经有正在进行的事件的情况,我们将重试assign-ip
脚本几次。下面,我们尝试运行该脚本 10 次,每次调用之间间隔 3 秒。如果保留 IP 移动成功,循环将立即结束:
/etc/keepalived/master.sh
export DO_TOKEN='digitalocean_api_token'
IP='reserved_ip_addr'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_RESERVED_IP=$(curl -s http://169.254.169.254/metadata/v1/reserved_ip/ipv4/active)
if [ $HAS_RESERVED_IP = "false" ]; then
n=0
while [ $n -lt 10 ]
do
python /usr/local/bin/assign-ip $IP $ID && break
n=$((n+1))
sleep 3
done
fi
完成后保存并关闭文件。
现在,我们只需要使脚本可执行,这样keepalived
可以称之为:
-
sudo chmod+x /etc/keepalived/master.sh
The keepalived
守护进程及其所有配套脚本现在应该已完全配置。我们可以通过键入以下内容在两个负载均衡器上启动服务:
该服务应该在每台服务器上启动并联系其对等方,使用我们配置的共享密钥进行身份验证。每个守护进程都会监控本地HAProxy进程,并监听来自远程的信号keepalived
过程。
您的主负载均衡器当前应分配有保留的 IP 地址,它将依次将请求定向到每个后端 Nginx 服务器。通常会应用一些简单的会话粘性,使您在通过 Web 浏览器发出请求时更有可能获得相同的后端。
我们可以通过简单地关闭主负载均衡器上的 HAProxy 来测试故障转移:
如果我们在浏览器中访问保留的 IP 地址,我们可能会暂时收到一条错误消息,指示无法找到该页面:
http://reserved_IP_addr
如果我们刷新页面几次,过一会儿,我们的默认 Nginx 页面就会回来:
我们的 HAProxy 服务在主负载均衡器上仍然处于关闭状态,因此这表明我们的辅助负载均衡器已接管。使用keepalived
,辅助服务器能够确定发生了服务中断。然后它转换为“主”状态并使用 DigitalOcean API 声明保留 IP。
现在我们可以在主负载均衡器上再次启动 HAProxy:
主负载均衡器将立即重新获得对保留 IP 地址的控制,尽管这对用户来说应该是相当透明的。
为了更好地可视化负载均衡器之间的转换,我们可以在转换期间监视一些服务器日志。
由于有关正在使用的代理服务器的信息不会返回给客户端,因此查看日志的最佳位置是实际的后端 Web 服务器。这些服务器中的每一个都应该维护有关哪些客户端请求资产的日志。从 Nginx 服务的角度来看,客户端是代表真实客户端发出请求的负载均衡器。
在我们的每个后端 Web 服务器上,我们可以tail
the /var/log/nginx/access.log
地点。这将显示向服务器发出的每个请求。由于我们的负载均衡器使用循环方式均匀分配流量,因此每个后端 Web 服务器应该看到大约一半的请求。
幸运的是,客户端地址是访问日志中的第一个字段。我们可以使用简单的方法提取值awk
命令。运行以下命令both您的 Nginx Web 服务器数量:
-
sudo tail -f/var/log/nginx/access.log| awk '{打印$1;}'
这些可能主要显示一个地址:
Output
. . .
primary_lb_private_IP
primary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
如果您引用服务器 IP 地址,您会注意到这些地址大部分来自您的主负载均衡器。请注意,由于 HAProxy 实现的一些简单的会话粘性,实际的分布可能会有所不同。
保持tail
命令在您的两个 Web 服务器上运行。
现在,在您的本地计算机上,我们将每 2 秒请求一次保留 IP 地址的 Web 内容。这将使我们能够轻松地看到负载均衡器发生的变化。在您的本地终端中,输入以下内容(我们将丢弃实际响应,因为无论使用哪个负载均衡器,这都应该是相同的):
-
while true; do curl -s -o /dev/null reserved_IP; sleep 2; done
在您的 Web 服务器上,您应该开始看到新的请求传入。与通过 Web 浏览器发出的请求不同,简单curl
请求不会表现出相同的会话粘性。您应该会看到对后端 Web 服务器的请求分布更加均匀。
现在,我们可以再次关闭主负载均衡器上的 HAProxy 服务:
几秒钟后,在您的 Web 服务器上,您应该看到 IP 列表从主负载均衡器的私有 IP 地址转换为辅助负载均衡器的私有 IP 地址:
Output
. . .
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
所有新请求均由辅助负载均衡器发出。
现在,在主负载均衡器上再次启动 HAProxy 实例:
您将看到客户端请求在几秒钟内转换回主负载均衡器的私有 IP 地址:
Output
. . .
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
主服务器已重新获得对保留 IP 地址的控制,并恢复其作为基础设施的主要负载平衡器的工作。
正如您所看到的,Nginx 访问日志显示所有客户端请求都来自当前负载均衡器的私有 IP 地址,而不是最初发出请求的客户端(即您的本地计算机)的实际 IP 地址。记录原始客户端的 IP 地址(而不是负载均衡器服务器)通常很有用。通过对所有后端 Web 服务器上的 Nginx 配置进行一些更改,可以轻松实现此目的。
在两个 Web 服务器上,打开nginx.conf
在编辑器中的文件:
-
sudo nano/etc/nginx/nginx.conf
找到“日志记录设置”部分(在http
块),并添加以下行:
添加到/etc/nginx/nginx.conf
log_format haproxy_log 'ProxyIP: $remote_addr - ClientIP: $http_x_forwarded_for - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent "$http_referer" ' '"$http_user_agent"';
保存并退出。这指定了一种新的日志格式,称为haproxy_log
,这增加了$http_x_forwarded_for
value — 发出原始请求的客户端的 IP 地址 — 默认访问日志条目。我们还包括$remote_addr
,这是反向代理负载均衡器(即主动负载均衡器服务器)的 IP 地址。
接下来,要使用这种新的日志格式,我们需要在默认服务器块中添加一行。
在两个 Web 服务器上,打开default
服务器配置:
-
sudo nano/etc/nginx/sites-available/default
内server
块(正下方listen
指令是个好地方),添加以下行:
添加到 /etc/nginx/sites-available/default
access_log /var/log/nginx/access.log haproxy_log;
保存并退出。这告诉 Nginx 使用以下方式写入其访问日志haproxy_log
我们上面创建的日志格式。
在两台 Web 服务器上,重新启动 Nginx 以使更改生效:
现在,您的 Nginx 访问日志应该包含发出请求的客户端的实际 IP 地址。正如我们在上一节中所做的那样,通过跟踪应用程序服务器的日志来验证这一点。日志条目应如下所示:
新的 Nginx 访问日志:
. . .
ProxyIP: load_balancer_private_IP - ClientIP: local_machine_IP - - [05/Nov/2015:15:05:53 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
. . .
如果您的日志看起来不错,那么您就已经准备好了!
在本指南中,我们逐步完成了设置高可用、负载平衡基础设施的完整过程。此配置效果很好,因为活动 HAProxy 服务器可以将负载分配到后端的 Web 服务器池。随着您的需求增长或减少,您可以轻松扩展该池。
保留的IP和keepalived
配置消除了负载均衡层的单点故障,即使主负载均衡器完全故障,您的服务也可以继续运行。此配置相当灵活,可以通过在 HAProxy 服务器后面设置您首选的 Web 堆栈来适应您自己的应用程序环境。