为了提高系统的可用性,避免单点故障,在分布式系统中,我们可以使用Keepalived来实现站点的高可用,下面就稍微介绍一下Keepalived的配置和使用。

因为我并没有多台主机,所以目前所选择的方案是在本机上使用Docker构建多台容器来实现集群,这种方式成本低,实现起来也比较简单。如果你对Docker不太熟悉,可以看我之前的文章使用 Docker 来构建一个 Tomcat 服务来快速了解一下Docker。

1. 安装Keepalived和Nginx并创建为一个Docker镜像

我假设你已经有了一个Ubuntu的Docker镜像,如果你还没有可以通过以下命令安装

docker pull hub.c.163.com/public/ubuntu:16.04-tools

之所以选择网易的镜像是因为其在国内的访问速度比较快(很奇怪在deepin操作系统上只能使用Docker官方的镜像,163的镜像无法使用,目前还不知道为什么)。

在这里我们的Ubuntu镜像的ID是1196ea15dad6,我们让这个镜像以守护进程(-d)的方式运行,并且给这个运行的容器起名 keepalived

docker run -d --privileged=true --name=keepalived 1196ea15dad6

此时Ubuntu容器已经开始运行了,执行命令

docker ps

应该能够看到一个名为 keepalived 的容器在运行了。接下来我们使用以下命令进入keepalived容器的bash

docker exec -it --privileged=true keepalived bash

成功进入bash之后,执行以下命令来安装Keepalived和Nginx(如果安装速度慢可以考虑更换国内的镜像源)

apt-get update
apt-get install keepalived
apt-get install nginx

安装完毕后,创建文件 /etc/keepalived/keepalived.conf,并在文件中保存以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass MrUse
}
virtual_ipaddress {
172.17.0.99
}
}

文件修改完毕后执行 exit 命令退出bash,之后执行命令

docker stop keepalived

停止此容器,此时查看Docker运行中的容器已经看不到keepalived容器了,之后执行命令

docker commit keepalived keepalived

把容器keepalived提交为一个名叫keepalived的镜像,之后执行命令

docker images

可以看到已经创建了一个名为keepalived的镜像,接下来我们就可以直接使用这个镜像来执行我们想要的操作了。

PS: 如果你想要跳过搭建镜像这一步,可以直接选择使用我已经构建好的镜像,使用如下命令可以获取此镜像:

docker pull hub.c.163.com/derobuka1/keepalived:latest

如果你使用我这个镜像,那么在下面使用到这个镜像的时候,要注意镜像的名称应该为hub.c.163.com/derobuka1/keepalived:latest

2. 配置并启动Keepalived服务

在上面我们已经创建好了一个安装了Nginx和Keepalived的Docker镜像,下面我们就使用这个镜像来创建Keepalived服务。首先我们使用keepalived镜像创建一个名为master的容器并使其作为守护进程执行

docker run -d --privileged=true --name=master keepalived

之后通过命令

docker exec -it --privileged=true master bash

进入到master容器的bash中,然后使用以下命令来启动服务

service keepalived start
service nginx start

之后执行

ip addr

可以看到虚拟地址 172.17.0.99 已经被绑定到了此台机器上。

之后我们可以同样使用命令

docker run -d --privileged=true --name=backup keepalived

来创建一个名为backup的备用机器,以同样的方式进入备用机器的bash,修改 /etc/keepalived/keepalived.conf 文件中keepalived的优先级低于master机器,例如为该改优先级为90:

···
priority 90
···

备用机器上只需要做这一个改动即可。保存配置文件,之后启动备用机器上的Keepalived和Nginx。

如果需要,我们可以再创建更多的备用机器,只需要保证这些备用机器的 priority 比90还要低即可。priority 的取值范围是1 - 250,超出的数值会被当作是100,优先级最高的机器会被当作master机器。

3. 模拟单点故障以测试Keepalived的功能

为了更直观的查看,我把master机器上的Nginx主页内容改为master,backup的主页改为backup。之后在宿主机上执行docker命令

docker run -it 1196ea15dad6 bash

进入一台测试机器的bash,在测试机上执行命令

curl 172.17.0.99

看到如下结果

此时请求落在了master机器上。执行命令

docker stop master

停止master容器模拟主节点失去服务的情况,此时在测试机器上再执行一次请求,得到如下结果

该结果说明我们的请求在master失去服务的情况下自动发往了backup机器,此时在备用机器上执行命令

ip addr

可以发现虚拟IP已经绑定到了备用机器上,这一结果符合我们预期。执行命令

docker start master

启动master容器,之后再启动master上的Nginx和Keepalived服务,随后在测试机器再执行一次请求,发现新的请求自动的切回到了master上,这样模拟了master恢复服务时的场景。

参考:

  1. 使用keepalived搭建主备切换环境
  2. Nginx+Keepalived实现站点高可用
  3. 如果想要以守护进程的方式创建一个容器,那么对创建这个容器所使用到的镜像有一些要求。要求就是,这个镜像在被创建的时候,创建这个镜像所使用到的容器的COMMAND(使用docker ps命令可以看到)应该为 /usr/bin/supervisord,而不是 bash