介绍
本教程将向您展示如何在DigitalOcean上创建一个高可用性HAProxy负载平衡器设置,以备用IP和Corosync/Pacemaker群集堆栈的支持。HAProxy负载平衡器将各自配置为在两个后端应用程序服务器之间共享流量。
<$>[注] 注: DigitalOcean Load Balancers是一个完全管理的,高度可用的负荷平衡服务。 负荷平衡器服务可以填补与这里描述的手动高可用性设置相同的角色。 按照我们的 设置负荷平衡器的指南如果你想评估这个选项。 <$>
前提条件
为了完成此指南, 您需要完成 Ubuntu 14. 04 (https://andsky.com/tech/tutorials/how-to-create-a-high-availability-setup-with-corosync-pacemaker-and-floating-ips-on-ubuntu-14-04) 教程上的 [如何与 Corosync 、 Pacemaker 和 Reserved IP 创建高可用性设置 (您应该跳过可选的 Add Nginx Resource 段) 。 这将给你留下两个Droplets, 我们称之为** 初级** 和** 二级** , 并有一个保留IP,可以在它们之间过渡。 集体来说,我们将把这些服务器称为** 负载平衡器** . 这些是Droplets 我们要安装一个负载平衡器,HAProxy.
您还需要能够在同一个数据中心创建两个额外的Ubuntu 14.04 Droplets,具有私人网络启用,以证明HA负载平衡器的设置工作. 这些是由HAProxy负载平衡的服务器。
在每个服务器上,您需要一个非根用户配置为)来学习如何设置这些用户。
创建应用 Droplets
第一步是创建两个Ubuntu Droplets,并启用私人网络,其数据中心与您的负载平衡器相同,它将起到上述app-1 和** app-2** 服务器的作用。 我们将在两个Droplets上安装Nginx,并用能够独特识别它们的信息来替换它们的索引页. 这将让我们有一个简单的方法来证明HA负载平衡器的设置正在起作用. 如果您已经拥有要加载平衡的应用程序服务器, 请随意调整此教程中合适的部分, 以使此操作成功( 并跳过任何与您的设置无关的部分 ) .
如果您想遵循示例设置,请创建两个Ubuntu 14.04 Droplets, app-1 和** app-2** ,并使用此bash脚本作为用户数据:
1[label Example User Data]
2#!/bin/bash
3
4apt-get -y update
5apt-get -y install nginx
6export HOSTNAME=$(curl -s http://169.254.169.254/metadata/v1/hostname)
7export PUBLIC_IPV4=$(curl -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)
8echo Droplet: $HOSTNAME, IP Address: $PUBLIC_IPV4 > /usr/share/nginx/html/index.html
此用户数据将安装 Nginx 并用 droplet 的主机名和公共 IP 地址替换 index.html 的内容(通过引用 Metadata 服务)。
收集服务器网络信息
在我们开始实际配置基础设施组件之前,最好收集有关您的每个服务器的一些信息。
要完成本指南,您需要有以下有关您的服务器的信息:
应用服务器 :私人 IP 地址* 负载平衡器** 私人和 IP 地址
查找私人 IP 地址
查找您的Droplet的私人IP地址的最简单方法是使用curl
来从DigitalOcean元数据服务中获取私人IP地址。
1curl 169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address && echo
正确的 IP 地址应在终端窗口中打印:
1[secondary_label Private IP address:]
210.132.20.236
在所有四个 Droplets 上执行此步骤,并将私人 IP 地址复制到您可以轻松参考的地方。
查找的 IP 地址
anchor IP 是保留的IP在连接到DigitalOcean服务器时会绑定的本地私人IP地址,它只是一个常规的eth0
地址的代名词,在超视察器级别上实现。
获取此值的最简单、最不容易的方法是直接从DigitalOcean元数据服务中获取。
1curl 169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address && echo
IP 将打印在自己的线上:
1[secondary_label Output]
210.17.1.18
执行此步骤在您的负载平衡器滴片上,并复制焦点 IP 地址到您可以轻松参考的地方。
配置 App 服务器
在收集上述数据后,我们可以继续配置我们的服务。
<$>[注] [标签注] 在此设置中,为 Web 服务器层选择的软件是相当可互换的。本指南将使用 Nginx,因为它是通用的,并且很容易配置。如果您更舒适地使用 Apache 或(生产能力)特定语言的 Web 服务器,请自由使用它。
我们将通过设置我们的后端应用程序服务器开始。这两个服务器将简单地服务他们的名称和公共IP地址;在实际设置中,这些服务器将提供相同的内容。
设置负载平衡器后面的应用程序服务器使我们能够将请求负载分配到一些相同的应用程序服务器之间,随着流量需求的变化,我们可以通过添加或删除应用程序服务器来轻松扩展以满足新需求。
配置 Nginx 只允许从负载平衡器的请求
如果您遵循示例,并且在创建应用程序服务器时使用提供的 用户数据 ,您的服务器将已经安装了 Nginx。
此外,我们只会服务来自我们两个负载平衡器的私有 IP 地址的请求,这将迫使用户通过负载平衡器访问您的应用程序服务器(我们将配置为仅通过保留 IP 地址访问)。
要进行这些更改,请在每个应用程序服务器上打开默认的 Nginx 服务器封锁文件:
1sudo vi /etc/nginx/sites-available/default
首先,我们将修改倾听
指令. 更改倾听
指令,以便在端口 80 上倾听当前 app 服务器的私人 IP 地址 。
1[label /etc/nginx/sites-available/default (1 of 2)]
2server {
3 listen app_server_private_IP:80;
4
5 . . .
直接在倾听
指令下方,我们将设置两个允许
指令,允许来自我们两个负载平衡器的私人IP地址的流量。
1[label /etc/nginx/sites-available/default (2 of 2)]
2 allow load_balancer_1_private_IP;
3 allow load_balancer_2_private_IP;
4 deny all;
保存并关闭文件,当你完成。
通过键入测试您所做的更改是否代表有效的 Nginx 语法:
1sudo nginx -t
如果没有报告任何问题,请通过键入以下方式重新启动 Nginx 示例:
1sudo service nginx restart
请记住在两个应用程序服务器上执行所有这些步骤(使用相应的应用程序服务器私有 IP 地址)。
测试变化
要测试您的应用服务器是否受到正确的限制,您可以使用从不同位置的弯曲
来进行请求。
在应用程序服务器上,您可以通过键入简单的本地内容请求:
1curl 127.0.0.1
由于我们在我们的 Nginx 服务器封锁文件中设置了限制,此请求实际上将被拒绝:
1[secondary_label Output]
2curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused
这是预期的,反映了我们试图实施的行为。
现在,从任何一个负载平衡器中,我们可以对我们的应用服务器的任何一个公共IP地址提出请求:
1curl web_server_public_IP
应用程序服务器不会在公共界面上听取,此外,当使用公共IP地址时,我们的应用程序服务器不会在我们的负载平衡器的请求中看到允许的私人IP地址:
1[secondary_label Output]
2curl: (7) Failed to connect to app_server_public_IP port 80: Connection refused
但是,如果我们修改呼叫以使用应用程序服务器的 private IP address 进行请求,则该呼叫应该正常工作:
1curl app_server_private_IP
如果您使用了示例用户数据,该页面应该包含被访问的应用服务器的名称和公共IP地址:
1[secondary_label app server index.html]
2Droplet: app-1, IP Address: 159.203.130.34
测试这两个负载平衡器到两个应用程序服务器的每个请求私有IP地址应该成功,而每一个向公共地址的请求应该失败。
一旦上面的行为被证明,我们可以继续前进. 我们的后端应用程序服务器配置现在已经完成。
从负载平衡器中删除 Nginx
通过遵循先决条件 HA 设置与 Corosync、Pacemaker 和保留 IPs 教程,您的负载平衡服务器将安装 Nginx. 因为我们将使用 HAProxy 作为反向代理负载平衡器,我们应该删除 Nginx 和任何相关的集群资源。
删除 Nginx 集群资源
如果您在遵循前提教程时添加了 Nginx 集群资源,请在您的负载平衡器中使用以下命令停止和删除Nginx
资源:
1sudo crm resource stop Nginx
2sudo crm configure delete Nginx
这也应该删除任何依赖于Nginx
资源的集群设置,例如,如果您创建了引用Nginx
资源的克隆
或定位
,它们也将被删除。
删除 Nginx 包
现在我们已经准备好在负载平衡器服务器中的两台**上卸载 Nginx。
首先,停止 Nginx 服务:
1sudo service nginx stop
然后用这个命令清理包:
1sudo apt-get purge nginx
您可能还想删除 Nginx 配置文件:
1sudo rm -r /etc/nginx
现在我们已经准备好安装和配置 HAProxy。
安装和配置 HAProxy
接下来,我们将设置HAProxy负载平衡器,这些负载平衡器将分别坐在我们的Web服务器前面,并在两个后端应用程序服务器之间分割请求。
HAProxy 配置会将请求传递给两个 Web 服务器。负载平衡器会听取其锁 IP 地址的请求。如前所述,这是保留 IP 地址在附加到 Droplet 时将绑定的 IP 地址。
安装 HAProxy
此部分必须在 **两个负载平衡服务器上执行。
我们将安装HAProxy 1.6,这不是在默认的Ubuntu存储库中。然而,如果我们使用PPA,我们仍然可以使用包管理器来安装HAProxy 1.6,使用这个命令:
1sudo add-apt-repository ppa:vbernat/haproxy-1.6
更新负载平衡器上的本地包索引并通过键入安装 HAProxy:
1sudo apt-get update
2sudo apt-get install haproxy
HAProxy现在已安装,但我们现在需要配置它。
配置 HAProxy
打开主 HAProxy 配置文件:
1sudo vi /etc/haproxy/haproxy.cfg
查找默认
部分,并在其下方添加以下两行:
1[label /etc/haproxy/haproxy.cfg (1 of 3)]
2 option forwardfor
3 option http-server-close
forwardfor 选项将 HAProxy 设置为每个请求添加X-Forwarded-For
标题 - 如果您希望应用程序服务器知道最初发送请求的 IP 地址,则有用 - 并且 http-server-close 选项通过关闭连接而减少 HAProxy 和您的用户之间的延迟。
接下来,在文件的末尾,我们需要定义我们的前端配置。这将决定HAProxy如何聆听接入连接。我们将HAProxy绑定到负载平衡器的锁IP地址。这将允许它聆听来自保留IP地址的流量。我们将呼叫我们的前端):
1[label /etc/haproxy/haproxy.cfg (2 of 3)]
2frontend http
3 bind load_balancer_anchor_IP:80
4 default_backend app_pool
注:安克尔 IP 是 HAProxy 配置中唯一应该在负载平衡服务器之间有所区别的部分,也就是说,请确保指定您目前正在使用的负载平衡服务器的安克尔 IP。
接下来,我们可以定义后端配置,这将指定下游位置,HAProxy将通过它接收的流量。在我们的情况下,这将是我们配置的两种 Nginx 应用服务器的私人 IP 地址:
1[label /etc/haproxy/haproxy.cfg (3 of 3)]
2backend app_pool
3 server app-1 app_server_1_private_IP:80 check
4 server app-2 app_server_2_private_IP:80 check
完成上述更改后,保存并退出文件。
检查我们所做的配置更改是否代表有效的 HAProxy 语法,键入:
1sudo haproxy -f /etc/haproxy/haproxy.cfg -c
如果没有报告错误,请通过键入以下方式重新启动您的服务:
1sudo service haproxy restart
再次,请确保在两个负载平衡服务器上执行本节中的所有步骤。
测试变化
我们可以通过再次测试弯曲
来确保我们的配置有效。
从负载平衡器服务器中,尝试请求本地主机、负载平衡器自己的公共 IP 地址或服务器自己的私人 IP 地址:
1curl 127.0.0.1
2curl load_balancer_public_IP
3curl load_balancer_private_IP
这些都应该与看起来类似于此的消息失败:
1[secondary_label Output]
2curl: (7) Failed to connect to IP_address port 80: Connection refused
但是,如果您向负载平衡器的 _anchor IP 地址提出请求,则应成功完成:
1curl load_balancer_anchor_IP
你应该看到一个应用程序服务器的 Nginx index.html
页面:
1[secondary_label app server index.html]
2Droplet: app-1, IP Address: app1_IP_address
再次执行相同的 curl 请求:
1curl load_balancer_anchor_IP
您应该看到其他应用程序服务器的index.html
页面,因为HAProxy默认情况下使用了圆形罗宾负载平衡:
1[secondary_label app server index.html]
2Droplet: app-2, IP Address: app2_IP_address
如果这种行为与你的系统相匹配,那么你的负载平衡器配置正确;你已经成功地测试了你的负载平衡器服务器是否正在平衡两个后端应用程序服务器之间的流量。
下载HAProxy OCF资源代理
在此时,您有一个基本的,主机级别的故障转换,但我们可以通过添加HAProxy作为集群资源来改善设置。这样做将允许您的集群确保HAProxy在您的保留IP分配的服务器上运行。
Pacemaker 允许通过将它们放入特定目录来添加 OCF 资源代理。
在 两个负载平衡器服务器上 ,下载 HAProxy OCF 资源代理,使用以下命令:
1cd /usr/lib/ocf/resource.d/heartbeat
2sudo curl -O https://raw.githubusercontent.com/thisismitch/cluster-agents/master/haproxy
在 两个负载平衡器服务器上 ,使其可执行:
1sudo chmod +x haproxy
在继续之前,请自由查看资源的内容. 这是一个可用于管理HAProxy服务的壳脚本。
现在我们可以使用HAProxy OCF资源代理来定义我们的haproxy
集群资源。
添加 haproxy 资源
随着我们的 HAProxy OCF 资源代理安装,我们现在可以配置一个haproxy
资源,使群集能够管理 HAProxy。
在 或负荷平衡器服务器 上,使用此命令创建原始资源haproxy
:
1sudo crm configure primitive haproxy ocf:heartbeat:haproxy op monitor interval=15s
指定的资源告诉集群每 15 秒监控 HAProxy,并在不可用时重新启动。
通过使用sudo crm_mon
或sudo crm status
来检查群集资源的状态:
1[secondary_label crm_mon:]
2...
3Online: [ primary secondary ]
4
5 FloatIP (ocf::digitalocean:floatip): Started primary
6 Nginx (ocf::heartbeat:nginx): Started secondary
不幸的是,Pacemaker可能会决定在单独的节点上启动haproxy
和FloatIP
资源,因为我们没有定义任何资源限制,这是一个问题,因为保留的IP可能会指向一个Droplet,而HAProxy服务正在运行在另一个Droplet上。
要解决此问题,我们将创建一个 clone 资源,该资源将指定一个现有原始资源应该在多个节点上启动。
使用此命令创建一个名为haproxy-clone
的haproxy
资源克隆:
1sudo crm configure clone haproxy-clone haproxy
集群状态现在应该看起来像这样:
1[secondary_label crm_mon:]
2Online: [ primary secondary ]
3
4FloatIP (ocf::digitalocean:floatip): Started primary
5 Clone Set: haproxy-clone [Nginx]
6 Started: [ primary secondary ]
正如你所看到的,克隆资源haproxy-clone
现在已经在我们的两个节点上开始了。
最后一步是配置一个对话限制,以指定‘FloatIP’资源应在具有活跃‘haproxy-clone’资源的节点上运行。
1sudo crm configure colocation FloatIP-haproxy inf: FloatIP haproxy-clone
您不会在 crm 状态输出中看到任何差异,但您可以看到使用此命令创建了对话资源:
1sudo crm configure show
现在,您的两个服务器都应该运行 HAProxy,而只有其中一个服务器运行了 FloatIP 资源。
尝试在负载平衡服务器服务器上停止 HAProxy 服务:
1sudo service haproxy stop
你会注意到它会在接下来的15秒内重新开始。
接下来,我们将通过重新启动您的活跃负载平衡服务器来测试您的HA设置(当前)。
测试负载平衡器的高可用性
有了新的高可用性 HAProxy 设置,您将想要测试一切按预期工作。
为了更好地可视化负载平衡器之间的过渡,我们可以在过渡期间监控应用程序服务器 Nginx 日志。
由于有关使用哪个代理服务器的信息不会返回客户端,所以查看日志的最佳地点是来自实际的后端 Web 服务器。
监控集群状态
在进行即将到来的测试时,您可能希望查看集群节点和资源的实时状态. 您可以使用此命令在负载平衡服务器上(只要运行):
1sudo crm_mon
输出应该像这样的东西:
1[secondary_label crm_mon output:]
2Last updated: Thu Nov 5 13:51:41 2015
3Last change: Thu Nov 5 13:51:27 2015 via cibadmin on primary
4Stack: corosync
5Current DC: secondary (2) - partition with quorum
6Version: 1.1.10-42f2063
72 Nodes configured
83 Resources configured
9
10Online: [ primary secondary ]
11
12FloatIP (ocf::digitalocean:floatip): Started primary
13 Clone Set: haproxy-clone [haproxy]
14 Started: [ primary secondary ]
这将显示哪些负载平衡节点在线,以及在哪些节点启动了FloatIP
和haproxy
资源。
请注意,在上面的示例中,FloatIP
资源是启动
的节点是负载平衡服务器,目前被分配给了保留IP。
自动请求到保留的 IP
在您的本地计算机上,我们将每2秒一次在保留IP地址上请求网页内容,这将使我们能够轻松地看到活跃负载平衡器如何处理流量。
1while true; do curl reserved_IP_address; sleep 2; done
它可能会在 app-1 和** app-2** 之间交替,因为HAProxy的默认平衡算法,我们没有指定,设置为** round-robin** 。
1[secondary_label curl loop output:
2Droplet: app-1, IP Address: app_1_IP_address
3Droplet: app-2, IP Address: app_2_IP_address
4...
保持这个终端窗口打开,以便请求不断发送到您的服务器,它们将在我们的下一个测试步骤中有所帮助。
在 Web 服务器上拼接日志
在我们的每个后端应用服务器上,我们可以尾巴
到/var/log/nginx/access.log
的位置,这将显示每个向服务器提出的请求。
客户端地址是访问日志中的第一个字段,所以很容易找到,在您的 Nginx 应用程序服务器(在单独的终端窗口中)上运行以下操作:
1sudo tail -f /var/log/nginx/access.log
第一个字段应该显示您的活跃负载平衡服务器的私人 IP 地址,每隔四秒钟(我们将假定它是 主要 负载平衡器,但它可能是** 次要** 在您的情况下):
1[secondary_label Output]
2. . .
3primary_loadbalancer_IP - - [05/Nov/2015:14:26:37 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
4primary_loadbalancer_IP - - [05/Nov/2015:14:26:37 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
5. . .
保持尾巴
命令在您的两个应用服务器上运行。
在主负载平衡器上中断 HAProxy 服务
现在,让我们重新启动 主要 负载平衡器,以确保保留 IP 故障转移工作:
1sudo reboot
现在要注意您的两个应用程序服务器上的 Nginx 访问日志. 您应该注意到,在保留 IP 故障发生后,访问日志显示应用程序服务器正在通过不同的 IP 地址访问。
1[secondary_label Output]
2. . .
3secondary_loadbalancer_IP - - [05/Nov/2015:14:27:37 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
4secondary_loadbalancer_IP - - [05/Nov/2015:14:27:37 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
5. . .
这表明,初级负载平衡器的故障被检测到,并成功将保留IP重新分配到次级负载平衡器。
您还可能需要检查本地终端的输出(每两秒钟访问保留IP),以验证二级负载平衡器正在向后端应用程序服务器发送请求:
1[secondary_label curl loop output:
2Droplet: app-1, IP Address: app_1_IP_address
3Droplet: app-2, IP Address: app_2_IP_address
4...
您也可以尝试在相反的方向错误转换,一旦另一个负载平衡器再次在线。
配置 Nginx 以记录实际客户端 IP 地址
正如您所看到的, Nginx 访问日志显示,所有客户端请求都来自当前负载平衡器的私人 IP 地址,而不是最初提出请求的客户端(即您的本地机器)的实际 IP 地址。
在两个 app 服务器上 ,在编辑器中打开nginx.conf
文件:
1sudo vi /etc/nginx/nginx.conf
找到),并添加以下行:
1[label add to /etc/nginx/nginx.conf]
2log_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地址。
接下来,要使用这个新的日志格式,我们需要将一行添加到我们的默认服务器块。
在 两个应用服务器上 ,打开默认
服务器配置:
1sudo vi /etc/nginx/sites-available/default
在),添加下面的行:
1[label add to /etc/nginx/sites-available/default]
2 access_log /var/log/nginx/access.log haproxy_log;
这告诉 Nginx 使用我们最近创建的haproxy_log
日志格式来编写其访问日志。
在 两个应用程序服务器上 ,重新启动 Nginx 以执行更改:
1sudo service nginx restart
现在您的 Nginx 访问日志应该包含提出请求的客户端的实际 IP 地址。 通过对应用程序服务器的日志进行尾声检查,就像我们在上一节所做的。
1[secondary_label New Nginx access logs:]
2. . .
3ProxyIP: 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"
4. . .
如果你的日志看起来很好,你都设定了!
结论
在本指南中,我们通过建立一个高度可用、负荷均衡的基础设施的完整过程进行研究,这种配置很好,因为活跃的HAProxy服务器可以将负荷分配到后端的应用服务器池中。
保留 IP 和 Corosync/Pacemaker 配置可以消除负载平衡层的单个故障点,使您的服务即使在主负载平衡器完全失败时也能继续运作。