如何在 Ubuntu 14.04 上使用 Keepalived 和保留 IP 设置高可用网络服务器

介绍

高可用性是系统设计的一个功能,允许应用程序在失败的情况下自动重新启动或重定向工作到另一个可行的系统。在服务器方面,需要几个不同的技术来设置一个高度可用的系统。

在本指南中,我们将展示如何使用keepalived来设置高可用性网页服务,我们将配置一个 保留IP地址,可以在两个可行的网页服务器之间移动。如果主服务器出现故障,保留IP将自动移动到第二个服务器,允许服务恢复。

前提条件

要完成本指南,您需要在您的DigitalOcean帐户中创建两个Ubuntu 14.04服务器. 两个服务器必须位于同一个数据中心内,并应启用私人网络。

在每个服务器上,您需要一个非根用户配置sudo访问,您可以遵循我们的 Ubuntu 14.04初始服务器设置指南来学习如何设置这些用户。

当您准备好开始时,请与您的非根用户登录您的两个服务器。

安装和配置 Nginx

虽然keepalived通常用于监控和过错负载平衡器,但为了减少我们的操作复杂性,我们将在本指南中使用 Nginx 作为一个简单的 Web 服务器。

首先,更新您的每个服务器上的本地包索引,然后我们可以安装 Nginx:

1sudo apt-get update
2sudo apt-get install nginx

在大多数情况下,对于一个高度可用的设置,你希望两个服务器都能提供完全相同的内容,但为了澄清,在本指南中,我们将使用 Nginx 来指明哪一个服务器在任何时候为我们的请求提供服务。

1sudo nano /usr/share/nginx/html/index.html

在您的第一个服务器上,以此替换文件的内容:

1[label Primary server's /usr/share/nginx/html/index.html]
2<h1>Primary</h1>

在您的第二个服务器上,以此替换文件的内容:

1[label Secondary server's /usr/share/nginx/html/index.html]
2<h1>Secondary</h1>

保存并关闭文件,当你完成。

构建和安装 Keepalived

接下來,我們將在我們的伺服器上安裝「keepalived」的戴蒙. 在Ubuntu的默認儲存庫中有「keepalived」的版本,但它已經過時,並且患有幾個阻礙我們的配置工作的錯誤。

在我们开始之前,我们应该抓住我们需要构建软件的依赖性。构建必需的元包将提供我们所需要的编译工具,而libssl-dev包包含keepalived需要构建的SSL库:

1sudo apt-get install build-essential libssl-dev

一旦依赖性已经存在,我们可以下载keepalived的 tarball。 访问 此页面以查找软件的最新版本。 右键单击最新版本并复制链接地址。 回到您的服务器上,移动到您的主目录并使用wget捕捉您复制的链接:

1cd ~
2wget http://www.keepalived.org/software/keepalived-1.2.19.tar.gz

使用tar命令来扩展档案,然后移动到结果的目录:

1tar xzvf keepalived*
2cd keepalived*

通过键入构建和安装 DAEMON:

1./configure
2make
3sudo make install

Daemon 现在应该安装在系统上。

创建一个 Keepalived Upstart 脚本

keepalived安装将所有二进制和支持文件放置在我们的系统上,但是,一个未包含的部分是我们Ubuntu 14.04系统的Upstart脚本。

我们可以创建一个非常简单的Upstart脚本,可以处理我们的keepalived服务. 在/etc/init目录中打开名为keepalived.conf的文件来开始:

1sudo nano /etc/init/keepalived.conf

内部,我们可以从一个简单的描述keepalived提供的功能开始。我们将使用包含的页面的描述。接下来,我们将指定该服务应该启动和停止的运行级别。

1[label /etc/init/keepalived.conf]
2description "load-balancing and high-availability service"
3
4start on runlevel [2345]
5stop on runlevel [!2345]

由于这项服务是确保我们的网站服务仍然可用的一部分,我们希望在出现故障时重新启动此服务,然后我们可以指定实际的exec行,该行将启动该服务,我们需要添加--dont-fork选项,以便Upstart能够正确跟踪pid:

1[label /etc/init/keepalived.conf]
2description "load-balancing and high-availability service"
3
4start on runlevel [2345]
5stop on runlevel [!2345]
6
7respawn
8
9exec /usr/local/sbin/keepalived --dont-fork

保存并关闭文件,当你完成。

创建 Keepalived 配置文件

有了我们的Upstart文件,我们现在可以继续配置keepalived

该服务在/etc/keepalived目录中搜索其配置文件,现在在您的两个服务器上创建该目录:

1sudo mkdir -p /etc/keepalived

收集您的服务器的私人IP地址

在我们创建配置文件之前,我们需要找到我们两个服务器的私人IP地址。在DigitalOcean服务器上,您可以通过输入元数据服务获取我们的私人IP地址:

1curl http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address && echo
1[secondary_label Output]
210.132.7.107

这也可以通过键入iproute2工具来找到:

1ip -4 addr show dev eth1

您正在寻找的价值将在这里找到:

1[secondary_label Output]
23: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
3    inet 10.132.7.107/16 brd 10.132.255.255 scope global eth1
4       valid_lft forever preferred_lft forever

复制这两个系统的值,我们需要在下面的配置文件中引用这些地址。

创建主服务器配置

接下来,在您的主要服务器上,创建主keepalived配置文件. 戴蒙在/etc/keepalived目录中寻找一个名为keepalived.conf的文件:

1sudo nano /etc/keepalived/keepalived.conf

内部,我们将通过打开一个vrrp_script块来为我们的 Nginx 服务定义健康检查,这将允许keepalived监控我们的 Web 服务器的故障,以便它可以信号表明过程已停止并开始恢复措施。

每两秒钟,我们会检查一个名为nginx的过程是否仍然声称pid:

1[label Primary server's /etc/keepalived/keepalived.conf]
2vrrp_script chk_nginx {
3    script "pidof nginx"
4    interval 2
5}

接下来,我们将打开一个名为vrrp_instance的块,这是定义keepalived将实现高可用性的方式的主要配置部分。

我们将开始说keepalived通过eth1我们的私人接口与同行进行通信,因为我们正在配置我们的主要服务器,我们将状态配置设置为MASTER

在选举中,使用优先级选项来决定哪个会员被选中。 该决定仅取决于哪个服务器为此设置拥有最高的数目。

 1[label Primary server's /etc/keepalived/keepalived.conf]
 2vrrp_script chk_nginx {
 3    script "pidof nginx"
 4    interval 2
 5}
 6
 7vrrp_instance VI_1 {
 8    interface eth1
 9    state MASTER
10    priority 200
11
12}

接下来,我们将为这个集群组分配一个ID,将由两个节点共享。我们将为此示例使用33。我们需要将unicast_src_ip设置为我们先前检索到的主服务器的私人IP地址。

 1[label Primary server's /etc/keepalived/keepalived.conf]
 2vrrp_script chk_nginx {
 3    script "pidof nginx"
 4    interval 2
 5}
 6
 7vrrp_instance VI_1 {
 8    interface eth1
 9    state MASTER
10    priority 200
11
12    virtual_router_id 33
13    unicast_src_ip primary_private_IP
14    unicast_peer {
15        secondary_private_IP
16    }
17
18}

接下来,我们可以设置一些简单的身份验证,以便我们的keepalived魔鬼彼此通信。这只是一个基本的措施,以确保所涉及的服务器是合法的。 创建一个身份验证子块。 内部,通过设置auth_type来指定密码身份验证。 对于auth_pass参数,设置一个共享的秘密,将被两个节点使用。 不幸的是,只有前八个字符是重要的:

 1[label Primary server's /etc/keepalived/keepalived.conf]
 2vrrp_script chk_nginx {
 3    script "pidof nginx"
 4    interval 2
 5}
 6
 7vrrp_instance VI_1 {
 8    interface eth1
 9    state MASTER
10    priority 200
11
12    virtual_router_id 33
13    unicast_src_ip primary_private_IP
14    unicast_peer {
15        secondary_private_IP
16    }
17
18    authentication {
19        auth_type PASS
20        auth_pass password
21    }
22
23}

接下来,我们将告诉keepalived使用我们在文件顶部创建的例子,标记为chk_nginx,以确定本地系统的健康状况。 最后,我们将设置一个notify_master脚本,每次这个节点成为对的时,就会执行。

 1[label Primary server's /etc/keepalived/keepalived.conf]
 2vrrp_script chk_nginx {
 3    script "pidof nginx"
 4    interval 2
 5}
 6
 7vrrp_instance VI_1 {
 8    interface eth1
 9    state MASTER
10    priority 200
11
12    virtual_router_id 33
13    unicast_src_ip primary_private_IP
14    unicast_peer {
15        secondary_private_IP
16    }
17
18    authentication {
19        auth_type PASS
20        auth_pass password
21    }
22
23    track_script {
24        chk_nginx
25    }
26
27    notify_master /etc/keepalived/master.sh
28}

一旦设置了上述信息,保存并关闭文件。

创建二级服务器配置

接下来,我们将在我们的辅助服务器上创建伴侣脚本. 在您的辅助服务器上打开一个文件在 /etc/keepalived/keepalived.conf:

1sudo nano /etc/keepalived/keepalived.conf

内部,我们将使用的脚本将大致相当于主服务器的脚本。

  • state: 此应更改为BACKUP在二级服务器上,以便节点在选举发生前初始化为备份状态。
  • priority: 此应设置为低于主服务器的值. 我们将在本指南中使用值100
  • unicast_src_ip: 此应是二级服务器的私有IP地址。

当您更改这些值时,次要服务器的脚本应该是这样的:

 1[label Secondary server's /etc/keepalived/keepalived.conf]
 2vrrp_script chk_nginx {
 3    script "pidof nginx"
 4    interval 2
 5}
 6
 7vrrp_instance VI_1 {
 8    interface eth1
 9    state BACKUP
10    priority 100
11
12    virtual_router_id 33
13    unicast_src_ip secondary_private_IP
14    unicast_peer {
15        primary_private_IP
16    }
17
18    authentication {
19        auth_type PASS
20        auth_pass password
21    }
22
23    track_script {
24        chk_nginx
25    }
26
27    notify_master /etc/keepalived/master.sh
28}

一旦你输入了脚本并更改了相应的值,保存并关闭文件。

创建保留的 IP 过渡脚本

接下来,我们需要创建一对脚本,我们可以用来重新分配保留IP地址到当前的Droplet,每次本地的keepalived实例成为主服务器。

下载保留IP分配脚本

首先,我们将下载一个通用 Python 脚本(由 DigitalOcean 社区管理员编写)可以用来将保留的 IP 地址重新分配给使用 DigitalOcean API 的 Droplet。

1cd /usr/local/bin
2sudo curl -LO http://do.co/assign-ip

此脚本允许您通过运行重新分配现有保留IP:

1python /usr/local/bin/assign-ip reserved_ip droplet_ID

只有在您为您的帐户设置一个名为DO_TOKEN的环境变量为有效的DigitalOcean API代币的情况下才会起作用。

创建一个 DigitalOcean API 代币

为了使用上述脚本,我们需要在我们的帐户中创建一个DigitalOcean API代币。

在控制面板中,点击顶部的API链接;在API页面右侧,点击生成新代币:

DigitalOcean generate API token

在下一页上,选择你的代币的名称,然后点击生成代币按钮:

DigitalOcean make new token

在API页面上,你的新代币将显示:

DigitalOcean token

复制代币 现在. 为了安全目的,没有办法再显示此代币以后. 如果您丢失此代币,您将不得不摧毁它并创建另一个。

配置您的基础设施的保留IP

接下来,我们将创建并分配一个保留的IP地址,用于我们的服务器。

在DigitalOcean控制面板上,点击网络选项卡,然后选择保留的IP导航项目,从您指定为主要服务器的列表中选择Droplet:

DigitalOcean add Reserved IP

在您的帐户中将创建一个新的保留IP地址,并分配给指定的 Droplet:

DigitalOcean Reserved IP assigned

如果您在 Web 浏览器中访问保留 IP,您应该看到主要服务器index.html页面:

DigitalOcean primary index.html

将保留IP地址复制下来,您将在下面的脚本中需要此值。

创建 Wrapper 脚本

现在,我们有我们需要创建包装脚本的项目,这将叫我们的/usr/local/bin/assign-ip脚本与正确的凭证。

现在在 两个服务器上创建文件,键入:

1sudo nano /etc/keepalived/master.sh

在内部,开始分配并导出一个名为DO_TOKEN的变量,其中包含您刚刚创建的API代币。

1[label /etc/keepalived/master.sh]
2export DO_TOKEN='digitalocean_api_token'
3IP='reserved_ip_addr'

接下来,我们将使用curl来询问我们目前所处的服务器的Droplet ID的元数据服务,这将被分配给一个名为ID的变量,我们还会询问这个Droplet是否目前已分配到保留IP地址,我们将将该请求的结果存储在一个名为HAS_RESERVED_IP的变量中:

1[label /etc/keepalived/master.sh]
2export DO_TOKEN='digitalocean_api_token'
3IP='reserved_ip_addr'
4ID=$(curl -s http://169.254.169.254/metadata/v1/id)
5HAS_RESERVED_IP=$(curl -s http://169.254.169.254/metadata/v1/reserved_ip/ipv4/active)

现在,我们可以使用上述变量来调用assign-ip脚本. 我们只会调用脚本,如果保留的 IP 尚未与我们的 Droplet 相关联. 这将有助于最大限度地减少 API 调用,并有助于防止对 API 的冲突请求,在主状态在您的服务器之间快速切换的情况下。

为了处理已有预留IP事件的案例,我们将重试分配IP脚本几次。下文,我们将尝试运行脚本10次,每次调用间隔为3秒。

 1[label /etc/keepalived/master.sh]
 2export DO_TOKEN='digitalocean_api_token'
 3IP='reserved_ip_addr'
 4ID=$(curl -s http://169.254.169.254/metadata/v1/id)
 5HAS_RESERVED_IP=$(curl -s http://169.254.169.254/metadata/v1/reserved_ip/ipv4/active)
 6
 7if [ $HAS_RESERVED_IP = "false" ]; then
 8    n=0
 9    while [ $n -lt 10 ]
10    do
11        python /usr/local/bin/assign-ip $IP $ID && break
12        n=$((n+1))
13        sleep 3
14    done
15fi

保存并关闭文件,当你完成。

现在,我们只需要使脚本可执行,以便keepalived可以称之为:

1sudo chmod +x /etc/keepalived/master.sh

启动 Keepalived 服务和测试失败

现在,keepalived的戴蒙和所有伴随它的脚本都应该完全配置,我们可以通过键入:

1sudo start keepalived

该服务应该在每个服务器上启动,并与其同行联系,通过我们配置的共享秘密进行身份验证。

当两个服务器都健康时,如果您在您的 Web 浏览器中访问您的保留 IP,您应该被带到主服务器的 Nginx 页面:

DigitalOcean primary index.html

现在,我们已经准备好测试我们配置的失败能力。

失败应发生时,下列条件之一发生:

  • **当主服务器上的 Nginx 健康检查表明 Nginx 不再运行时,在这种情况下,主服务器的 keepalived 戴蒙将进入故障状态,它会通知次端服务器,它应该过渡到主状态,并声称保留 IP。

如果主服务器后来恢复,它将返回主状态并回收保留IP,因为它将启动新的选举(它仍然具有最高优先级数)。

测试 Nginx 失败

我们可以通过在主服务器上停止 Nginx 服务来测试第一个条件:

1sudo service nginx stop

如果您更新您的网页浏览器,您可能最初会收到一个响应,表明该页面不可用:

DigitalOcean page not available

然而,仅仅几秒钟后,如果您更新页面几次,您会看到二级服务器已经要求保留IP地址:

DigitalOcean secondary index.html

我们可以通过在主服务器上重新启动 Nginx Daemon 来恢复失败:

1sudo service nginx start

几秒钟后,如果您更新页面,您会发现主服务器已经重新夺回了保留IP的所有权:

DigitalOcean primary index.html

测试服务器故障

我们应该测试的另一个场景是,如果它无法连接到主服务器,二级服务器是否正确过渡到主状态。

1sudo reboot

再次,我们应该首先在保留IP地址中看到服务中断:

DigitalOcean page not available

几秒钟后,次要服务器会接收请求:

DigitalOcean secondary index.html

过了一会儿,当主服务器完成重新启动时,它会回收IP地址:

DigitalOcean primary index.html

这证实了我们的第二个失败场景。

结论

在本指南中,我们使用keepalived,DigitalOcean API和保留IP地址配置了高度可用的Web服务器环境。

Published At
Categories with 技术
comments powered by Disqus