如何在Ubuntu 14.04上利用Keepalived与Floating IP设置高可用性Web服务器

提供:ZStack云计算

内容简介

高可用性无疑是系统设计当中的关键性指标之一,其使得应用程序能够在遭遇故障时自动重新启动或者重新路由至其它系统当中。而着眼于服务器,我们需要运用多种不同技术以设置一套高可用系统。具体而言,其中需要一款能够对工作负载进行重新定向的组件,同时具备一套机制以监控故障并在检测到中断状况时进行系统转换。

立足于这样的场景,keepalived守护进程可用于监控服务或系统,同时在问题出现时自动实现故障转移。在今天的教程中,我们将演示如何利用keepalived设置一项高可用Web服务。我们还将配置一套 Floating IP地址,其能够在两台Web服务器之间顺畅往来。一旦主服务器发生故障,Floating IP将被自动迁移至副服务器,从而帮助服务恢复正常运行。

先决条件

为了完成这份教程,大家需要利用自己的DigitalOcean账户创建两套Ubuntu 14.04服务器。这两套服务器必须位于同一数据中心之内,同时启用专有网络功能。

在每台服务器上,我们还需要配置一个非root用户以实现sudo访问。大家可以参阅Ubuntu 14.04初始服务器设置指南一文以了解如何设置此类用户。

当大家准备就绪之后,即可利用自己的非root用户对服务器进行日志记录。

安装并配置Nginx

尽管keepalived常被用于执行监控及故障转移负载均衡器,从而降低日常运营复杂性,但我们在本教程中将使用Nginx作为简单Web服务器。

首先对每台服务器上的本地软件包索引进行更新。我们可以使用以下命令安装Nginx:

- sudo apt-get update   
- sudo apt-get install nginx

在多数情况下,为了构建高可用系统,我们可能需要确保两台服务器承载同样的内容。然而为了清晰起见,本教程中我们将利用Nginx指定特定时间段内由哪台服务器响应相关请求。为实现这一诉求,我们需要对每台主机上的默认index.html页面进行修改。现在打开该文件:

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

在第一台服务器上,利用以下内容替代该文件初始内容:

Primary server’s /usr/share/nginx/html/index.html

<h1>Primary</h1>

在第二台服务器上,利用以下内容替代该文件初始内容:

Secondary server’s /usr/share/nginx/html/index.html

<h1>Secondary</h1>

完成后保存并退出。

构建并安装Keepalived

接下来,我们需要在服务器上安装keepalived守护进程。Ubuntu的默认库中即直接提供keepalived,但其版本已经非常陈旧且存在多个bug,因此我们的配置将使用keepalived的最新版本。

在开始之前,我们应该需要提取构建该软件所必需的关联性。其中build-essential meta-package将提供我们需要的编译工具,而libssl-dev软件包则包含keepalived构建所必需的SSL库:

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

关联性就位后,我们可以下载keeaplived压缩包。参阅此页面以获取该软件的最新版本。右键点击其最新版本并复制链接地址。回到服务器,进入主目录并使用wget命令以使用刚刚复制的链接:

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

使用tar命令以释放该归档文件,而后进入生成的目录:

- tar xzvf keepalived*

- cd keepalived*

输入以下命令以构建并安装该守护进程:

- ./configure

- make

- sudo make install

该守护进程现在已经被安装在系统当中。

创建一套Keepalived Upstart脚本

Keepalived安装包将把全部二进制与支持文件移动到我们的系统当中。不过其中还缺少一套用于Ubuntu 14.04系统的Upstart脚本。

我们可以创建一套非常简单的Upstart脚本以处理keepalived服务。首先打开/etc/init目录当中的keepalived.conf文件:

- 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

完成后保存并退出。

创建Keepalived配置文件

Upstart脚本文件完成后,现在我们可以对keepalived进行配置了。

该服务会在/etc/keepalived目录中寻找其配置文件。现在在两台服务器上创建此目录:

- sudo mkdir -p /etc/keepalived
收集服务器的专有IP地址

在开始创建配置文件之前,我们还需要找出两台服务器的专有IP地址。在DigitalOcean服务器上,大家可以通过以下命令从metadata服务内获取专有IP地址:

- curl http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address && echo

Output

10.132.7.107

大家也可以输入以下命令利用iproute2工具获取结果:

- ip -4 addr show dev eth1

大家将看到以下返回值:

Output

3: eth1: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 10.132.7.107/16 brd 10.132.255.255 scope global eth1
   valid_lft forever preferred_lft forever

复制两套系统的上述值,供我们接下来在配置文件中进行引用。

创建主服务器配置

接下来在主服务器上创建主keepalived配置文件。该守护程序会在/etc/keepalived目录当中寻找keepalived.conf文件:

- sudo nano /etc/keepalived/keepalived.conf

在此文件中,我们将开启vrrp_script block以定义Nginx服务运行状态检查。通过这种方式,keepalived能够监控我们的Web服务器故障情况,并在进程被中止时发出通知且执行恢复举措。

我们的检查机制非常简单——每两秒对名为nginx的进程进行检查以确定其是否仍在发布pid:

Primary server's /etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
script "pidof nginx"
interval 2
}

接下来,我们将打开一个名为vrrp_insance的block。这部分正是配置的核心所在,用于定义keepalived实现高可用性的具体方式。

我们首先告知keepalived通过eth1(也就是我们的专有接口)同另一keepalived进程进行通信。由于我们正在配置主服务器,因此其状态配置可设置为“MASTER”。此将作为keepalived的初始值,直到该守护进程能够与另一keepalived进程通信并进行选定。

在选定过程中,priority选项用于决定选择哪个服务器成员。此决定完全取决于哪台服务器的设定数值更高。我们将主服务器的数值设定为“200”:

Primary server's /etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
script "pidof nginx"
interval 2
}

vrrp_instance VI_1 {
interface eth1
state MASTER
priority 200

}

接下来,我们将为该集群组分配一个ID,此ID将同两个节点进行共享。在本示例中,我们使用“33”作为ID。我们将unicast_src_ip设定为此前检索到的主服务器专有IP地址。而unicast_peer则为我们副服务器的专有IP地址:

Primary server's /etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
script "pidof nginx"
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子block,在其中设定auth_type以指定验证密码。而auth_pass参数则设定为两个节点共同使用的共享密码。遗憾的是,这里我们只能设定八位字符作为密码:

Primary server's /etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
script "pidof nginx"
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_nginx标签在文件中创建的路由以检测本地系统的运行状态。最后,我们设置一套notify_master脚本,其将在本节点成为“master”后加以执行。该脚本负责触发Floating IP地址分配。我们暂时将此脚本创建如下:

Primary server's /etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
script "pidof nginx"
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_nginx
}

notify_master /etc/keepalived/master.sh
}

以上信息设置完成后,保存文件并退出。

创建副服务器配置

下面为副服务器创建活动脚本。在副服务器上打开/etc/keepalived/keepalived.conf文件:

- sudo nano /etc/keepalived/keepalived.conf

这里使用的脚本与主服务器脚本基本一致。其中需要变更的条目包括:

  • state: 将其变更为“BACKUP”,这样此节点将在选定开始之前被初始化为bakcup状态。
  • priority: 将其值设定为低于主服务器。在本教程中,我们选择“100”数值。
  • unicast_src_ip: 此处应为副服务器的专有IP地址。
  • unicast_peer: 此处应为主服务器的专有IP地址。

在上述值变更完成后,副服务器脚本内容将如下所示:

Secondary server's /etc/keepalived/keepalived.conf

vrrp_script chk_nginx {
script "pidof nginx"
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_nginx
}

notify_master /etc/keepalived/master.sh
}

在完成了各项数值调整之后,保存文件并退出。

创建Floating IP转换脚本

接下来,我们需要创建两套脚本,负责在本地keepalived实例成为主服务器后为当前Droplet分配Floating IP地址。

下载Floating IP分配脚本

首先,我们需要下载一套通用型Python脚本(由一位DigitalOcean社区管理者) that can be used to reassign a floating IP address to a Droplet using the DigitalOcean API. We should download this file to the 编写而成,能够利用DigitalOcean API为Droplet分配Floating IP地址。我们需要将该文件下载至/usr/local/bin目录:

- cd /usr/local/bin

- sudo curl -LO http://do.co/assign-ip

此脚本允许我们通过运行以下命令对现有Floating IP进行重新分配:

- python /usr/local/bin/assign-ip floating_ipdroplet_ID

需要注意,只有我们在账户中将名为DO_TOKEN的环境变量设定为一条有效的DigitalOcean API令牌时,该脚本才能正常起效。

创建一条DigitalOcean API令牌

为了使用上述脚本,我们需要在账户中创建一条DIgitalOcean API令牌。

在控制面板当中,点击顶部的“API”链接。而后在API页面右侧点击“generate new token”:

在后续页面中,为我们的令牌选择一个名称并点击“Generate Token”按钮:

在API页面中,我们的新令牌将显示如下:

现在复制该令牌。出于安全考量,我们之后不应再显示该令牌内容。如果大家丢失了此令牌,则需要将其撤销并重新创建一条新令牌。

为基础设施配置一项Floating IP

接下来,我们将为服务器创建并分配一项Floating IP地址。

在DigitalOcean控制面板中,点击“Networking”标签并选定“Floating IPs”导航条目。从列表中选择我们分配为“primary”服务器的Droplet:

这时我们的账户中将新建一项Floating IP地址,并被分配至指定的Droplet,如下所示:

如果大家在浏览器中访问该Floating IP,则应看到“primary”服务器的index.html页面:

复制该Floating IP地址,我们之后需要在脚本中使用。

创建Wrapper脚本

现在,我们已经拥有了全部必要条目,接下来可以利用正确凭证创建伯劳per脚本以调用我们的/usr/local/bin/assign-ipscript了。

通过以下命令在两台服务器上创建该文件:

- sudo nano /etc/keepalived/master.sh

在文件内分配并导出名为DO_DOKEN的变量,其中包含我们刚刚创建的API令牌。下面我们再分配一个名为IP的变量,其中包含将要使用的Floating IP地址:

/etc/keepalived/master.sh

export DO_TOKEN='digitalocean_api_token'
IP='floating_ip_addr'

此后,我们将使用curl命令向metadata服务询问当前所在服务器的Droplet ID。结果会被分配至名为ID的变量。我们还需要查询当前Droplet是否拥有分配得到的Floating IP地址。相关查询结果将被保存在名为HAS_FLOATING_IP的变量当中:

/etc/keepalived/master.sh

export DO_TOKEN='digitalocean_api_token'
IP='floating_ip_addr'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_FLOATING_IP=$(curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/active)

现在,我们可以使用以上各变量调用assign-ip脚本了。只有在Floating IP尚未被分配至当前Droplet时,我们才需要调用该脚本。这种方式能帮助我们尽量减少API调用次数,从而避免master状态在不同服务器间快速切换时可能造成的API请求冲突。

如果Floating IP已经存在于进程事件内,我们可以多次重试assign-ip脚本。下面我们连续运行十次该脚本,每次间隔3秒钟。一旦Floating IP移动成功,该循环将立刻中止:

/etc/keepalived/master.sh

export DO_TOKEN='digitalocean_api_token'
IP='floating_ip_addr'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_FLOATING_IP=$(curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/active)

if [ $HAS_FLOATING_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

启动Keepalived服务并测试故障转移效果

到这里,keepalived守护进程及其全部相关脚本都已经配置完成。我们可以通过以下命令在两台服务器上启动该服务:

- sudo start keepalived

该服务应该在两台设备上正确启动并彼此通信,同时验证我们之前配置的共享密码。每个守护进程都将监控本地Nginx进程,并监听来自远程keepalived进程的信号。

当两台服务器皆处于正常运行状态时,如果大家通过浏览器访问Floating IP,则亦查看到主服务器的Nginx页面:

现在我们已经可以测试这套配置方案的故障转移效果了。

故障转移只会在以下两种状态之一出现时生效:

  • 当主服务器上的Nginx运行状态检查发现Nginx不再运行时。在这种情况下,主服务器的keepalived守护进程将进入“fault”状态。其将通知副服务器进行master状态转换,同时声明Floating IP。
  • 当副服务器与主服务器间的keepalived连接断开时。如果副服务器由于某种原因而无法与主服务器对接,其将直接转换为“master”状态并尝试声明Floating IP。

如果主服务器随后恢复正常,其将重新转换回master状态并再次声明Floating IP,这是因为其启动同时会初始化新的选定过程(且仍然拥有更高priority数值)。

测试Nginx故障

我们可以通过停止主服务器上的Nginx服务对第一种情况进行测试:

- sudo service nginx stop

如果大家刷新浏览器,那么即时响应可能表现为该页面不可用:

不过在几秒之后,再次刷新页面则会发现副服务器已经声明该Floating IP地址:

我们可以在主服务器上重启Nginx守护进程以实现故障恢复:

- sudo service nginx start

几秒钟之后,刷新页面即会显示主服务器再次声明对Floating IP的所有权:

测试服务器故障

我们需要测试的另一种场景是,一旦副服务器无法与主服务器相对接,其能否正确完成master状态转换。测试这一效果需要重启master服务器:

- sudo reboot

同样的,此时访问Floating IP地址会显示服务不可用:

几秒之后,副服务器将接手请求处理:

再过一会儿,主服务器重启完毕后将再次声明该IP地址:

至此,第二种故障场景验证完毕。

总结

在今天的教程中,我们利用keepalived、DigitalOcean PI以及Floating IP地址配置了一套高可用Web服务器环境。其实际基础设施结构非常简单,但已经足以证明其能够支持各类重视服务可用性与正常运行时间的基础设施场景。

本文来源自DigitalOcean Community。英文原文:How To Set Up Highly Available Web Servers with Keepalived and Floating IPs on Ubuntu 14.04 By Justin Ellingwood

翻译:diradw

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值