如何在Ubuntu 16.04上使用心跳和浮动IP创建高可用性设置

Heartbeat是一个开放源代码程序,为高可用性(HA)服务器基础架构中的关键组件 - 客户端服务器提供群集基础架构功能 - 群集成员身份和消息传递。心跳通常与群集资源管理器(CRM)(如Pacemaker)一起使用,以实现完整的HA设置。但是,在本教程中,我们将演示如何使用Heartbeat和DigitalOcean浮动IP创建双节点HA服务器设置。

介绍

Heartbeat是一个开放源代码的程序,向客户端服务器提供集群基础架构功能 - 集群成员资格和消息传递。 这些功能是高可用性(HA)服务器基础架构中的关键组件。 在本教程中,我们将演示如何使用Heartbeat和DigitalOcean浮动IP创建双节点HA服务器设置。

心跳通常与群集资源管理器(CRM)(如Pacemaker)结合使用,以实现完整的HA设置。 如果您希望创建更强大的HA设置,请考虑使用Corosync和PacemakerKeepalived

目标

完成后,HA设置将包含两个主动/被动配置的Ubuntu 16.04服务器。 这将通过指向一个浮动IP来实现,这个IP就是你的用户访问你的服务或网站的方式,指向主服务器或者主动服务器,除非检测到失败。 如果心跳服务检测到主服务器不可用,辅助服务器将自动运行一个脚本,通过DigitalOcean API将浮动IP重新分配给自己。 因此,到浮动IP的后续网络流量将被定向到辅助服务器,辅助服务器将充当活动服务器,直到主服务器再次变为可用(此时,主服务器将重新分配浮动IP给自己)。

主动/被动图

注意:本教程仅用于演示目的,仅涵盖设置可靠HA解决方案的一些方面。 本文的主要内容是关于如何在网关级别安装主动/被动节点并将它们连接到浮动IP的细节。 为了简化教程,我们将配置它们以响应各自的主机名和公共IP地址,而不是在每个服务器上配置反向代理负载均衡器。

为了实现这个目标,我们将按照以下步骤进行:

  • 创建2个将接收流量的Droplet
  • 创建一个浮动IP并将其分配给其中一个Droplet
  • 创建一个指向浮动IP的DNS记录(可选)
  • 在飞沫上安装心跳
  • 配置心跳以运行浮动IP重新分配服务
  • 创建浮动IP重新分配服务
  • 测试故障转移

考虑到这个目标,我们可以开始设置我们的HA设置。

先决条件

为了实现浮动IP重新分配的自动化,我们必须使用DigitalOcean API。 这意味着您需要生成一个个人访问令牌(PAT),这是一个API令牌,可用于对您的DigitalOcean帐户进行身份验证,具有读取写入权限。 您可以按照API教程的“ 如何生成个人访问令牌”部分来实现此目的。 您的PAT将用于脚本中,该脚本将添加到群集中的两台服务器上。 请务必将其保存在安全的地方以便参考,因为它允许您完全访问DigitalOcean帐户。

除了API之外,本教程还使用以下DigitalOcean功能:

请阅读链接的教程,如果你想了解更多关于他们。

创建飞沫

第一步是在同一个数据中心内创建两个Ubuntu Droplets,它们将作为上述主服务器和辅助服务器。 在我们的示例设置中,我们将其命名为“主”和“次”以便于参考。 我们将在两个Droplet上安装Nginx,并用唯一标识它们的信息替换它们的索引页面。 这将使我们有一个简单的方法来证明HA设置正在工作。 对于生产设置,您的服务器应运行您选择的Web服务器或负载均衡器。

用这个bash脚本作为用户数据创建两个Ubuntu 16.04 Droplet, 主要的次要的

示例用户数据
#!/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 > /var/www/html/index.html

这将安装Nginx,并将index.html的内容替换为Droplet的主机名和IP地址(通过引用元数据服务)。 通过公共IP地址访问任何Droplet将会显示Droplet主机名和IP地址的基本网页,这对于测试浮动IP在任何给定时刻指向哪个Droplet都是有用的。

创建一个浮动IP

在DigitalOcean控制面板中,单击顶部菜单中的网络 ,然后单击子菜单中的浮动IP

没有浮动IP

将浮动IP分配到 Droplet,然后单击Assign Floating IP按钮。

在分配了浮动IP之后,通过在网络浏览器中访问它,检查是否能够到达分配的滴。

http://your_floating_ip

您应该看到您的主Droplet的索引页面。

配置DNS(可选)

如果您希望能够通过域名访问您的HA设置,请在您的DNS中创建一条A记录 ,将您的域指向您的浮动IP地址。 如果您的域使用DigitalOcean的Nameservers,请按照如何使用DigitalOcean教程设置主机名的第三步 一旦传播,您可以通过域名访问您的活动服务器。

我们将使用的示例域名是example.com 如果您现在没有域名,则应该使用浮动IP地址。

安装心跳

下一步是在两台服务器上安装Heartbeat。 安装Heartbeat最简单的方法是使用apt-get:

sudo apt-get update
sudo apt-get install heartbeat

Heartbeat现在已经安装,但它需要配置之前,它会做任何事情。

配置心跳

为了得到我们想要的集群并运行,我们必须在两个服务器的/etc/ha.d目录中创建和设置这些Heartbeat配置文件:

  1. ha.cf - 心跳集群的全局配置,包括其成员节点
  2. authkeys - 包含安全密钥,为节点提供对群集进行身份验证的方法
  3. haresources - 指定由群集管理的服务和作为服务首选所有者的节点。 请注意,这个文件没有在使用像Pacemaker这样的CRM的设置中使用

如果主Droplet的可用性发生变化,我们还需要提供一个脚本来执行浮动IP重新分配。

收集节点信息

在配置ha.cf之前,我们应该查找每个节点的名称。 Heartbeat要求每个节点名称与它们各自的uname -n输出相匹配。

两台服务器上 ,运行以下命令查找适当的节点名称:

uname -n

注意命令的输出。 示例节点名称是“主要”和“次要”,它与我们命名的“Droplet”相匹配。

为了确定哪些节点可用,我们还需要查找每个节点将用于与群集其余部分进行通信的网络接口和IP地址。 您可以使用任何网络接口,只要每个节点都可以到达集群中的其他节点。 我们将使用我们的Droplet的公共接口,这恰好是eth0

两台服务器上 ,使用此命令查找eth0接口的IP地址(或在DigitalOcean控制面板中查找):

ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 04:01:76:a5:45:01 brd ff:ff:ff:ff:ff:ff
    inet 198.51.100.5/24 brd 198.51.100.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.17.0.28/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::601:76ff:fea5:4501/64 scope link
       valid_lft forever preferred_lft forever

记下网络接口的IP地址(在本例中突出显示)。 一定要得到两个服务器的IP地址。

创建ha.cf文件

两台服务器上 ,在您最喜爱的编辑器中打开/etc/ha.d/ha.cf 我们将使用nano:

sudo nano /etc/ha.d/ha.cf

该文件应该是新的和空的。 我们需要添加群集中每个节点的网络接口和名称。

将该配置复制并粘贴到文件中,然后用我们前面查到的值替换相应的节点名称和IP地址。 在这个例子中, 主要的IP地址是198.51.100.5次要的IP地址是198.51.100.6

/etc/ha.d/ha.cf文件
node primary
ucast eth0 198.51.100.5
node secondary
ucast eth0 198.51.100.6

保存并退出该文件。 接下来,我们将设置集群的授权密钥。

创建authkeys文件

授权密钥用于允许集群成员加入集群。 我们可以简单地为此生成一个随机密钥。

节点上,运行以下命令以在名为AUTH_KEY的环境变量中生成合适的授权密钥:

if [ -z "${AUTH_KEY}" ]; then
  export AUTH_KEY="$(command dd if='/dev/urandom' bs=512 count=1 2>'/dev/null' \
      | command openssl sha1 \
      | command cut --delimiter=' ' --fields=2)"
fi

然后用这些命令写入/etc/ha.d/authkeys文件:

sudo bash -c "{
  echo auth1
  echo 1 sha1 $AUTH_KEY
} > /etc/ha.d/authkeys"

检查authkeys文件的内容是这样的:

sudo cat /etc/ha.d/authkeys

它应该看起来像这样(使用不同的授权密钥):

的/etc/ha.d/authkeys
auth1
1 sha1 d1e6557e2fcb30ff8d4d3ae65b50345fa46a2faa

确保文件只能由root用户读取:

sudo chmod 600 /etc/ha.d/authkeys

现在将/etc/ha.d/authkeys文件从您的主节点复制到您的辅助节点。 您可以手动或使用scp来执行此操作。

辅助服务器上,请确保设置authkeys文件的权限:

sudo chmod 600 /etc/ha.d/authkeys

在这一点上,两台服务器应该有一个相同的/etc/ha.d/authkeys文件。

创建haresources文件

haresources文件指定与集群管理的服务配对的首选主机 如果节点可用,则首选主机是运行相关服务的节点。 如果首选主机不可用,即集群无法访问,则其他节点之一将接管。 换句话说,如果主服务器停机,辅助服务器将接管。

两台服务器上 ,在您最喜爱的编辑器中打开haresources文件。 我们将使用nano:

sudo nano /etc/ha.d/haresources

现在将这一行添加到文件中,如果主节点的名称不同,则替换为:

的/etc/ha.d/haresources
primary floatip

保存并退出该文件。 这将服务器配置为当前未定义的floatip服务的首选主机。 接下来设置floatip服务。

创建浮动IP重新分配服务

我们的Heartbeat集群配置为维护floatip服务,节点可以使用floatip服务将浮动IP分配给自己,但是我们仍然需要创建服务。 然而,在我们建立服务之前,我们先创建一个脚本,通过DigitalOcean API将浮动IP分配给运行它的节点。 然后我们将创建floatip服务,它将运行浮动IP重新分配脚本。

创建assign-ip脚本

在我们的例子中,我们将使用DigitalOcean API下载一个基本的Python脚本,该脚本将一个浮动IP分配给给定的Droplet ID。

两台服务器上 ,下载assign-ip Python脚本:

sudo curl -L -o /usr/local/bin/assign-ip http://do.co/assign-ip

这两台服务器上 ,使其可执行:

sudo chmod +x /usr/local/bin/assign-ip

由于我们的脚本正在向API发出请求,因此我们需要安装Python 请求库:

sudo apt-get install python-requests

使用assign-ip脚本需要以下详细信息:

  • 浮动IP:脚本的第一个参数,即分配的浮动IP
  • Droplet ID:脚本的第二个参数,即浮动IP应该分配给的Droplet ID
  • DigitalOcean PAT(API令牌):作为环境变量DO_TOKEN ,您的读/写DigitalOcean PAT

在继续之前,请随意查看脚本的内容。

现在我们准备创建floatip服务。

创建floatip服务

为了创建floatip服务,我们只需要创建一个init脚本来调用我们之前创建的assign-ip脚本,并响应startstop子命令。 这个init脚本将负责通过Droplet元数据服务查找服务器的Droplet ID。 此外,它将需要重新分配浮动IP,以及DigitalOcean API令牌(前提部分中提到的个人访问令牌)。

两台服务器上 ,在编辑器中添加打开的/etc/init.d/floatip

sudo nano /etc/init.d/floatip

然后复制并粘贴这个初始化脚本,用你的DigitalOcean API密钥和应该重新分配的浮动IP替换突出显示的部分:

/etc/init.d/floatip
#!/bin/bash

param=$1

export DO_TOKEN='your_DO_API_token'
IP='your_floating_IP_address'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)

if [ "start" == "$param" ] ; then
  python /usr/local/bin/assign-ip $IP $ID
  exit 0
elif [ "stop" == "$param" ] ; then
  exit 0;
elif [ "status" == "$param" ] ; then
  exit 0;
else
  echo "no such command $param"
  exit 1;
fi

保存并退出该文件。

使脚本可执行:

sudo chmod u+x /etc/init.d/floatip

当这个floatip服务启动时,它将简单地调用assign-ip Python脚本并将指定的浮动IP分配给执行该脚本的Droplet。 这是由辅助服务器调用的脚本,如果服务器发生故障,将浮动IP重新分配给自己,。 同样,一旦服务器重新加入集群,相同的脚本将被服务器用来回收浮动IP。

开始心跳

现在心跳配置好了,它所依赖的所有脚本都被设置好了,我们准备启动Heartbeat集群了!

两台服务器上 ,运行以下命令启动Heartbeat:

sudo systemctl start heartbeat

我们的HA设置现在已经完成! 在继续之前,让我们测试它是否按预期工作。

测试高可用性

测试高可用性设置是否有效是非常重要的,所以我们现在就来做。

目前,浮动IP被分配给节点。 现在通过IP地址或指向它的域名来访问浮动IP,将只显示服务器的索引页。 如果您使用了示例用户数据脚本,它将如下所示:

Droplet: primary, IP Address: 198.51.100.5

这表明,浮动知识产权实际上被分配到主要的小Droplet。

现在,让我们打开一个本地终端,并使用curl在1秒循环中访问浮动IP。 使用此命令可以这样做,但一定要用您的域或浮动IP地址替换URL:

while true; do curl http://example.com; sleep 1; done

目前,这将输出主服务器相同的Droplet名称和IP地址。 如果我们导致主服务器发生故障,通过断电或停止Heartbeat服务,我们将看到浮动IP是否被重新分配到辅助服务器。

我们现在重新启动服务器。 通过DigitalOcean控制面板或通过在主服务器上运行此命令来完成此操作:

sudo reboot

一会儿之后,主服务器应该变得不可用。 请注意终端中运行的curl循环的输出。 你应该注意到输出如下所示:

Droplet: primary, IP Address: 198.51.100.5
...
curl: (7) Failed to connect to example.com port 80: Connection refused
Droplet: secondary, IP Address: 198.51.100.6
Droplet: secondary, IP Address: 198.51.100.6
...

也就是说,应该重新分配浮动IP地址以指向辅助服务器的IP地址。 这意味着您的HA设置正在运行,因为发生了成功的自动故障转移。

您可能会也可能不会看到Connection refused错误,如果您尝试访问主服务器故障和浮动IP重新分配完成之间的浮动IP,则可能发生此错误。

现在,您可以通过DigitalOcean控制面板打开Droplet。 由于Heartbeat配置了主Droplet作为运行Floating IP重新分配脚本的首选主机 ,因此浮动IP将在重新变为可用状态后立即自动回到主服务器。

结论

恭喜! 您现在拥有使用Heartbeat和DigitalOcean浮动IP的基本HA服务器设置。

如果您希望创建更强大的HA设置,请考虑使用Corosync和PacemakerKeepalived

在这个例子中,我们已经将Nginx作为一个基本的负载均衡器来安装,但是如果您想要改善使用反向代理负载均衡器的Heartbeat设置,您可以将Nginx配置为一个,或使用HAProxy来完成。

请记住,无论您选择使用哪种替代方案,您都需要将负载平衡器/反向代理绑定到定位IP地址,以便用户只能通过浮动IP地址访问您的服务器(而不是通过公共每个服务器的IP地址)。