介绍
本教程将向您展示如何在浮动IP和Corosync / Pacemaker群集的支持下,在DigitalOcean上创建高可用性HAProxy负载均衡器设置。 HAProxy负载均衡器将被配置为在两个后端应用程序服务器之间拆分流量。 如果主要负载平衡器关闭,浮动IP将自动移动到第二个负载平衡器,允许恢复服务。
先决条件
为了完成这个指南,你将需要完成的如何创建与Corosync,Pacemaker高可用性设置,在Ubuntu 14.04浮动IP地址教程(你应该跳过可选添加Nginx的资源部分)。 这会留下两个Droplet,我们将称之为原发性和继发性 ,带有浮动IP,可以在它们之间转换。 总的来说,我们将把这些服务器的负载平衡器 。 这些是我们将安装负载均衡器HAProxy的Droplet。
您还需要能够在同一个数据中心创建两个额外的Ubuntu 14.04 Droplets,启用专用网络,以演示HA负载均衡器设置工作。 这些是将由HAProxy负载平衡的服务器。 我们将把这些应用程序服务器,这我们将在安装Nginx的,以app-1和app-2。 如果您已经有要加载平衡的应用程序服务器,请随意使用它们。
在每台服务器,则需要使用配置的非root用户sudo
访问。 您可以按照我们的Ubuntu 14.04的初始服务器设置指南 ,了解如何设置这些用户。
创建应用程序Droplet
第一步是创建两个Ubuntu的Droplet,启用专用网络,在同一数据中心的负载平衡器,这将作为上述APP-1和APP-2服务器。 我们将在两个Droplets上安装Nginx,并用其唯一标识它们的信息替换它们的索引页面。 这将允许我们一个简单的方法来演示HA负载均衡器设置是否正常工作。 如果您已经具有要加载平衡的应用程序服务器,请随意调整本教程的相应部分以使其工作(并跳过与您的设置无关的任何部分)。
如果你想效仿设置,创建两个Ubuntu的14.04Droplet,APP-1和APP-2,并使用此bash脚本为用户的数据:
#!/bin/bash
apt-get -y update
apt-get -y install nginx
export HOSTNAME=$(curl -s http://169.254.169.254/metadata/v1/hostname)
export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)
echo Droplet: $HOSTNAME, IP Address: $PUBLIC_IPV4 > /usr/share/nginx/html/index.html
这个用户数据将安装Nginx,并将index.html的内容替换为Droplet的主机名和公共IP地址(通过引用元数据服务)。 访问Droplet将显示具有Droplet主机名和公共IP地址的基本网页,这将有助于测试负载均衡器将流量引导到哪个应用服务器。
收集服务器网络信息
在我们开始实际配置基础架构组件之前,最好收集有关每个服务器的一些信息。
要完成本指南,您需要有关于您的服务器的以下信息:
- 应用服务器 :私有IP地址
- 负载均衡私营和锚IP地址
查找专用IP地址
找到你的Droplet的私有IP地址的最简单方法是使用curl
从DigitalOcean元数据服务抢私网IP地址。 这个命令应该在你的Droplets中运行。 在每个Droplet上,键入:
curl 169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address && echo
应在终端窗口中打印正确的IP地址:
Private IP address:10.132.20.236
在所有四个Droplet上执行此步骤,并将私有IP地址复制到您可以轻松引用的地方。
查找锚点IP地址
锚IP是该浮动IP将结合时附着到DigitalOcean服务器到本地专用IP地址。 它只是为正规的别名eth0
地址,在管理程序层面实施。
获取这个值的最简单,最不容易出错的方法直接来自DigitalOcean元数据服务。 使用curl
,你可以接触到这个端点上的每台服务器通过键入:
curl 169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address && echo
锚IP将在其自己的行上打印:
Output10.17.1.18
在两个负载均衡器Droplet上执行此步骤,并将锚IP地址复制到您可以轻松引用的地方。
配置应用程序服务器
收集上述数据后,我们可以继续配置我们的服务。
我们将开始设置我们的后端应用服务器。 这两个服务器将简单地提供他们的名字和公共IP地址; 在实际设置中,这些服务器将提供相同的内容。 他们只接受通过其专用IP地址的Web连接。 这将有助于确保流量专门通过我们稍后将配置的两个HAProxy服务器之一。
在负载均衡器之后设置应用服务器允许我们在一些数量相同的应用服务器之间分配请求负载。 随着流量需求的变化,我们可以轻松扩展以满足新需求,方法是从此层添加或删除应用服务器。
将Nginx配置为仅允许来自负载平衡器的请求
如果你在下面的例子中,并创建应用程序服务器时使用你所提供的用户数据 ,您的服务器将已安装的Nginx。 下一步是进行一些配置更改。
我们想要配置Nginx只监听服务器的私有IP地址上的请求。 此外,我们只会处理来自我们两个负载均衡器的私有IP地址的请求。 这将强制用户通过您的负载均衡器访问应用服务器(我们将配置为只能通过浮动IP地址访问)。
要进行这些更改,请在每个应用服务器上打开默认的Nginx服务器块文件:
sudo vi /etc/nginx/sites-available/default
首先,我们将修改listen
指令。 改变listen
指令收听当前的应用程序服务器的专用IP地址,端口80上删除多余的listen
行。 它应该看起来像这样:
server {
listen app_server_private_IP:80;
. . .
直接跌破listen
指令,我们将设置两个allow
指令允许通信从我们的两个负载均衡的私有IP地址的。 我们将遵循这一了一个deny all
的规则,禁止所有其他通信:
allow load_balancer_1_private_IP;
allow load_balancer_2_private_IP;
deny all;
完成后保存并关闭文件。
通过键入以下内容来测试所做的更改是否代表有效的Nginx语法:
sudo nginx -t
如果没有报告问题,请通过键入以下命令重新启动Nginx守护程序:
sudo service nginx restart
请记住在两个应用程序服务器上执行所有这些步骤(使用适当的应用程序服务器专用IP地址)。
测试更改
要测试你的应用程序服务器是否正常限制,您可以用请求curl
从不同的位置。
在您的应用服务器上,您可以通过键入以下内容尝试简单的本地内容请求:
curl 127.0.0.1
由于我们在Nginx服务器块文件中设置的限制,此请求实际上将被拒绝:
Outputcurl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused
这是预期的,反映了我们试图实现的行为。
现在,无论从负载均衡器 ,我们可以为我们的任何应用服务器的公网IP地址,提出一个请求:
curl web_server_public_IP
再次,这应该失败。 应用服务器不在公共接口上侦听,此外,当使用公共IP地址时,我们的应用服务器在我们的负载均衡器的请求中不会看到允许的私有IP地址:
Outputcurl: (7) Failed to connect to app_server_public_IP port 80: Connection refused
但是,如果我们修改呼叫使用的应用程序服务器的私有IP地址发出请求,它应该正常工作:
curl app_server_private_IP
nginx的index.html
页应返回。 如果您使用示例用户数据,页面应包含正在访问的应用服务器的名称和公共IP地址:
app server index.htmlDroplet: app-1, IP Address: 159.203.130.34
从两个负载均衡器到两个应用程序服务器进行测试。 每个对私有IP地址的请求应该成功,而对公共地址的每个请求应该失败。
一旦上述行为被证明,我们可以继续。 我们的后端应用服务器配置现已完成。
从负载平衡器中删除Nginx
按照与Corosync,Pacemaker的前提HA设置,和浮动IP的教程,你的负载均衡服务器将安装Nginx的。 因为我们要使用HAProxy作为反向代理负载均衡器,我们应该删除Nginx和任何相关的群集资源。
删除Nginx群集资源
如果您在以下前提条件教程添加了Nginx的群集资源,停止和删除Nginx
与你的负载平衡器之一这些命令的资源:
sudo crm resource stop Nginx
sudo crm configure delete Nginx
这也应该删除依赖于任何群集设置Nginx
资源。 例如,如果您创建了一个clone
或colocation
引用Nginx
资源,他们也将被删除。
删除Nginx软件包
现在,我们准备卸载Nginx的两个负载平衡器服务器 。
首先,停止Nginx服务:
sudo service nginx stop
然后使用此命令清除包:
sudo apt-get purge nginx
您可能还想删除Nginx配置文件:
sudo rm -r /etc/nginx
现在我们准备好安装和配置HAProxy。
安装和配置HAProxy
接下来,我们将设置HAProxy负载平衡器。 这些都将位于我们的Web服务器前面,并在两个后端应用程序服务器之间拆分请求。 这些负载平衡器将完全冗余,处于主动 - 被动配置; 在任何给定时间只有一个将接收流量。
HAProxy配置将请求传递到两个Web服务器。 负载平衡器将监听其锚IP地址上的请求。 如前所述,这是浮动IP地址连接到Droplet时将绑定的IP地址。 这确保只有源自浮动IP地址的流量将被转发。
安装HAProxy
此部分需要被两个负载平衡器服务器上执行。
我们将安装HAProxy 1.6,它不在默认的Ubuntu存储库。 但是,如果我们使用PPA,我们仍然可以使用包管理器安装HAProxy 1.6,使用此命令:
sudo add-apt-repository ppa:vbernat/haproxy-1.6
更新负载平衡器上的本地软件包索引,然后键入以下命令安装HAProxy:
sudo apt-get update
sudo apt-get install haproxy
HAProxy现已安装,但我们现在需要配置它。
配置HAProxy
打开主HAProxy配置文件:
sudo vi /etc/haproxy/haproxy.cfg
找到defaults
部分,其下添加两个以下行:
option forwardfor
option http-server-close
该forwardfor选项设置HAProxy的增加X-Forwarded-For
头到每个请求,这是有用的,如果你想你的应用程序服务器,以了解哪些IP地址最初发送一个请求和HTTP服务器,关闭选项降低HAProxy的和等待您的用户通过关闭连接但维护保持活动。
接下来,在文件的末尾,我们需要定义我们的前端配置。 这将决定HAProxy如何侦听传入连接。 我们将HAProxy绑定到负载均衡器锚点IP地址。 这将允许它侦听源自浮动IP地址的流量。 为了简单起见,我们将称为前端“http”。 我们还将指定一个默认后端, app_pool
,通信传递给(我们将在稍后进行配置其中):
frontend http
bind load_balancer_anchor_IP:80
default_backend app_pool
注意:锚IP是HAProxy的配置应的负载平衡器服务器之间不同的唯一部分。 也就是说,请确保指定您当前正在处理的负载平衡器服务器的锚IP。
接下来,我们可以定义后端配置。 这将指定HAProxy将通过其接收的流量的下游位置。 在我们的示例中,这将是我们配置的两个Nginx应用服务器的私有IP地址:
backend app_pool
server app-1 app_server_1_private_IP:80 check
server app-2 app_server_2_private_IP:80 check
完成上述更改后,保存并退出文件。
通过键入以下内容来检查我们所做的配置更改是否代表有效的HAProxy语法:
sudo haproxy -f /etc/haproxy/haproxy.cfg -c
如果没有报告错误,请键入以下内容重新启动服务:
sudo service haproxy restart
同样,请务必在两个负载均衡器服务器上执行本节中的所有步骤。
测试更改
我们可以确保我们的配置是通过测试有效的curl
一次。
从负载均衡器服务器,尝试请求本地主机,负载均衡器自己的公用IP地址或服务器自己的专用IP地址:
curl 127.0.0.1
curl load_balancer_public_IP
curl load_balancer_private_IP
这些都应该失败,消息看起来类似于:
Outputcurl: (7) Failed to connect to IP_address port 80: Connection refused
但是,如果您对负载平衡器的锚IP地址的请求,应该成功完成:
curl load_balancer_anchor_IP
您应该看到的Nginx index.html
应用程序服务器中的一个页面:
app server index.htmlDroplet: app-1, IP Address: app1_IP_address
再次执行相同的curl请求:
curl load_balancer_anchor_IP
您应该看到index.html
其他应用服务器的页面,因为HAProxy的缺省使用循环负载平衡:
app server index.htmlDroplet: app-2, IP Address: app2_IP_address
如果此行为与您的系统匹配,则您的负载平衡器配置正确; 您已成功测试了负载均衡器服务器在两个后端应用程序服务器之间平衡流量。 此外,您的浮动IP应该已经分配给负载平衡器服务器中的一个,因为这是在HA的先决条件安装程序与Corosync,Pacemaker和浮动IP地址教程成立。
下载HAProxy OCF资源代理
此时,您有一个基本的主机级故障转移,但我们可以通过将HAProxy作为群集资源添加来改进设置。 这样做将允许您的群集确保HAProxy在您的浮动IP分配到的服务器上运行。 如果Pacemaker检测到HAProxy没有运行,它可以重新启动服务或分配浮动IP到其他节点(应该运行HAProxy)。
Pacemaker允许通过将OCF资源代理放置在特定目录中来添加OCF资源代理。
在这两个负载均衡的服务器 ,下载使用这些命令HAProxy的OCF资源代理:
cd /usr/lib/ocf/resource.d/heartbeat
sudo curl -O https://raw.githubusercontent.com/thisismitch/cluster-agents/master/haproxy
在这两个负载均衡的服务器 ,使其可执行:
sudo chmod +x haproxy
在继续之前,请自由地查看资源的内容。 它是一个shell脚本,可用于管理HAProxy服务。
现在,我们可以使用HAProxy的OCF资源代理来定义我们haproxy
群集资源。
添加haproxy资源
安装了我们的HAProxy的OCF资源代理,我们现在可以配置haproxy
资源,使集群管理HAProxy的。
在任意一个负载均衡的服务器 ,创建haproxy
使用此命令原始资源:
sudo crm configure primitive haproxy ocf:heartbeat:haproxy op monitor interval=15s
指定的资源告诉集群每15秒监视一次HAProxy,如果它不可用,则重新启动它。
通过检查群集资源的状态sudo crm_mon
或sudo crm status
:
crm_mon:...
Online: [ primary secondary ]
FloatIP (ocf::digitalocean:floatip): Started primary
Nginx (ocf::heartbeat:nginx): Started secondary
不幸的是,Pacemaker可能会决定启动haproxy
和FloatIP
因为我们还没有定义的任何资源限制在单独的节点资源。 这是一个问题,因为浮动IP可能指向一个Droplet,而HAProxy服务正在另一个Droplet上运行。 访问浮动IP将指向没有运行应该高度可用的服务的服务器。
要解决此问题,我们将创建一个克隆的资源,它指定一个现有的原始资源应该在多个节点上启动。
创建的克隆haproxy
名为“HAProxy的克隆”使用此命令的资源:
sudo crm configure clone haproxy-clone haproxy
集群状态现在应该如下所示:
crm_mon:Online: [ primary secondary ]
FloatIP (ocf::digitalocean:floatip): Started primary
Clone Set: haproxy-clone [Nginx]
Started: [ primary secondary ]
正如你所看到的,克隆资源, haproxy-clone
,现在开始我们两个节点。
最后一步是配置一个托管克制,以指定FloatIP
资源与积极的节点上运行haproxy-clone
资源。 要创建名为“FloatIP-haproxy”的共置约束,请使用以下命令:
sudo crm configure colocation FloatIP-haproxy inf: FloatIP haproxy-clone
您不会看到crm状态输出的任何差异,但您可以看到colocation资源是使用此命令创建的:
sudo crm configure show
现在,您的两个服务器应该运行HAProxy,而只有其中一个,FloatIP资源正在运行。
尝试在负载平衡器服务器上停止HAProxy服务:
sudo service haproxy stop
你会注意到,它将在未来15秒内的某个时间再次启动。
接下来,我们将通过重新启动您的主动负载均衡服务器(即在一个测试你的HA设置FloatIP
资源目前的“启动”)。
测试负载平衡器的高可用性
使用新的高可用性HAProxy设置,您将需要测试一切正常工作。
为了更好地可视化负载平衡器之间的转换,我们可以在转换期间监视应用程序服务器Nginx日志。
由于关于使用哪个代理服务器的信息未返回到客户端,查看日志的最佳位置来自实际的后端Web服务器。 这些服务器中的每一个应该维护有关哪些客户端请求资产的日志。 从Nginx服务的角度来看,客户端是代表真实客户端请求的负载均衡器。
监视群集状态
在执行即将到来的测试时,您可能需要查看集群节点和资源的实时状态。 您可以使用此命令,在任何负载平衡器服务器(只要它正在运行):
sudo crm_mon
输出应该看起来像这样:
crm_mon output:Last updated: Thu Nov 5 13:51:41 2015
Last change: Thu Nov 5 13:51:27 2015 via cibadmin on primary
Stack: corosync
Current DC: secondary (2) - partition with quorum
Version: 1.1.10-42f2063
2 Nodes configured
3 Resources configured
Online: [ primary secondary ]
FloatIP (ocf::digitalocean:floatip): Started primary
Clone Set: haproxy-clone [haproxy]
Started: [ primary secondary ]
这将显示出哪些负载平衡器节点联机,以及哪些节点的FloatIP
和haproxy
资源开始。
需要注意的是,该节点FloatIP
资源Started
上,在上述的例子主要是,流动的IP当前被分配给负载平衡器服务器。 我们将把此服务器作为活动的负载均衡服务器 。
自动请求浮动IP
在本地计算机上,我们将每2秒请求浮动IP地址的Web内容。 这将允许我们很容易地看到活动负载均衡器如何处理传入流量。 也就是说,我们将看到它向其发送流量的后端应用服务器。 在本地终端中,输入以下命令:
while true; do curl floating_IP_address; sleep 2; done
每两秒钟,您应该会看到一个后端应用服务器的响应。 这将APP-1和APP-2之间交替可能因为HAProxy的默认平衡算法,我们没有指定,被设置为循环 。 所以,你的终端应该显示如下:
[secondary_label curl loop output:
Droplet: app-1, IP Address: app_1_IP_address
Droplet: app-2, IP Address: app_2_IP_address
...
保持此终端窗口打开,以便请求不断发送到您的服务器。 他们将有助于我们的下一个测试步骤。
尾随Web服务器上的日志
在每一个我们的后端应用服务器,我们可以的tail
的/var/log/nginx/access.log
位置。 这将显示对服务器发出的每个请求。 由于我们的负载平衡器使用循环轮流均匀分配流量,因此每个后端应用服务器应该看到大约一半的请求。
客户端地址是访问日志中的第一个字段,因此很容易找到。 运行在两个 Nginx的的应用服务器的以下(在单独的终端窗口):
sudo tail -f /var/log/nginx/access.log
第一个字段应该表现出你的积极负载均衡服务器的私有IP地址,每四秒(我们假设它的主要负载平衡器,但它可能是你的情况次要的):
Output. . .
primary_loadbalancer_IP - - [05/Nov/2015:14:26:37 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
primary_loadbalancer_IP - - [05/Nov/2015:14:26:37 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
. . .
保持tail
两个您的应用程序服务器上运行命令。
中断主负载平衡器上的HAProxy服务
现在,让我们重新启动主负载平衡器,确保浮动IP故障切换工作原理:
sudo reboot
现在注意两个应用程序服务器上的Nginx访问日志。 您应该注意到,在浮动IP故障转移后,访问日志显示应用程序服务器正由不同的IP地址访问。 日志应指示二次负载均衡服务器发送请求:
Output. . .
secondary_loadbalancer_IP - - [05/Nov/2015:14:27:37 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
secondary_loadbalancer_IP - - [05/Nov/2015:14:27:37 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
. . .
这表明检测到主负载平衡器的故障,并且浮动IP已成功重新分配给辅助负载平衡器。
您还可能要检查本地终端(每两秒钟访问浮动IP)的输出,以验证辅助负载平衡器是否正在向两个后端应用程序服务器发送请求:
[secondary_label curl loop output:
Droplet: app-1, IP Address: app_1_IP_address
Droplet: app-2, IP Address: app_2_IP_address
...
您也可以尝试在其他方向上的故障转移,一旦其他负载平衡器再次联机。
配置Nginx日志实际客户端IP地址
如您所见,Nginx访问日志显示所有客户端请求都来自当前负载均衡器的私有IP地址,而不是原始发出请求的客户端(即本地计算机)的实际IP地址。 记录原始请求者的IP地址而不是负载平衡器服务器通常很有用。 这很容易通过对所有后端应用程序服务器上的Nginx配置进行一些更改来实现。
在这两个应用服务器 ,打开nginx.conf
在编辑器中的文件:
sudo vi /etc/nginx/nginx.conf
查找(在内部的“日志记录设置”部分http
块),并添加以下行:
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
价值的IP,使得原来的请求的默认访问日志条目的客户端地址。 我们也正在包括$remote_addr
,这是反向代理负载均衡器(即有效负载均衡服务器)的IP地址。
接下来,要使用这个新的日志格式,我们需要在默认服务器块中添加一行。
在这两个应用服务器 ,打开default
服务器配置:
sudo vi /etc/nginx/sites-available/default
内的server
模块(右下面listen
指令是个好地方),添加以下行:
access_log /var/log/nginx/access.log haproxy_log;
保存并退出。 这告诉Nginx的使用写的访问日志haproxy_log
,我们最近创建的日志格式。
在这两个应用服务器 ,请重新启动Nginx的以使更改生效:
sudo service nginx restart
现在您的Nginx访问日志应该包含发出请求的客户端的实际IP地址。 通过拖动应用服务器的日志来验证此操作,如上一节中所述。 日志条目应如下所示:
New Nginx access logs:. . .
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服务器可以将负载分发到后端应用程序服务器池。 您可以根据需求增长或缩小轻松扩展此池。
浮动IP和Corosync / Pacemaker配置消除了负载均衡层上的单点故障,使您的服务能够继续运行,即使主要负载均衡器完全失败。 此配置相当灵活,可以通过在HAProxy服务器后面设置首选应用程序栈来适应您自己的应用程序环境。