利用Docker+keepalived+nginx搭建高可用
1.在生产环境下,nginx可作为负载均衡服务器。那么当单节点的情况下,nginx或此服务器是有可能挂掉的,那么为了保证高可用性,首先想到的就是再布置一台nginx服务器。但是两台nginx在不同服务器上ip地址是不一样的,那么如何保证当一台服务器挂掉,自动使用另一台服务器呢?解决办法是使用keepalived。
keepalived是基于VRRP协议(虚拟路由冗余协议)的一个服务软件,VRRP协议就是将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的vip(虚拟ip),master会发组播,当backup收不到vrrp包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master。这样的话就可以及时将业务切换到其他设备。
2.本人使用Docker环境来模拟多服务器环境。
docker run -d --name web1 --privileged=true centos /usr/sbin/init
docker exec -it web1 /bin/bash
提示:因为本人在运行docker时总会发生无法绑定vip的错误,所以加入这两个参数
- --privileged=true:可以docker内真正拥有root权限
- /usr/sbin/init:可以在docker内使用systemctl命令
按照上部操作,启动3个容器,分别为web1、web2、webtest。两个用于搭建高可用,一个作为客户端连接测试用。
3.分别进入到web1与web2容器中,执行:
yum install -y nginx keepalived vim net-tools initscripts
- vim:docker启动的centos容器不带vim,所以需要自己安装
- net-tools:可以使用ifconfig命令,来查看网卡
- initscripts:可以使用service命令
4.修改nginx默认index.html文件,目的是可以区分目前访问的是哪一台nginx。可以标记一台为MASTER,一台为BACKUP。
cd /usr/share/nginx/html
vim index.html
5.分别在两个容器中的/etc/keepalived目录下,建立check_nginx.sh文件。并添加执行权限:chmod +x check_nginx.sh(这里不需要,因为是root权限下,保险起见还是贴出来了)。check_nginx.sh脚本文件,是用来检查niginx是否启动的。
cd /etc/keepalived
touch check_nginx.sh
chmod +x check_nginx.sh
vim check_nginx.sh
check_nginx.sh脚本文件内容:
#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
/usr/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
killall keepalived
fi
fi
6.分别在两个容器中配置keepalived.conf文件。文件在/etc/keepalived目录下。配置内容如下:
MASTER中配置:
global_defs {
router_id LVS_DEVEL #节点名,一般使用默认的就可以
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh" #检测nginx脚本的路径
interval 2 #运行脚本的间隔时间
weight -20 #变更的权重
}
vrrp_instance VI_1 {
state MASTER #此节点为MASTER,如果此节点down掉,再重启时,会立即抢占回主节点
#mcast_src_ip 172.17.0.2 本机ip,不声明则默认绑定本机ip
interface eth0 #绑定的网卡,可以通过ifconfig查看网卡信息
virtual_router_id 70 #虚拟路由标识,同一组的必须相同
priority 100 #权重
nopreempt #定义为非抢占式,因为多次主备切换对请求量大的服务器不太好
advert_int 1 #与组内其他节点发送心跳的间隔:s
virtual_ipaddress {
172.17.0.200
} #绑定的虚拟ip组
track_script {
chk_nginx
} #执行前面声明的脚本
}
BACKUP中配置:
global_defs {
router_id LVS_DEVEL #节点名,一般使用默认的就可以
}
vrrp_script chk_nginx {
script "/etc/keepalived/check_nginx.sh" #检测nginx脚本的路径
interval 2 #运行脚本的间隔时间
weight -20 #变更的权重
}
vrrp_instance VI_1 {
state BACKUP #此节点为backup
# mcast_src_ip 172.17.0.3 本机ip,不声明则默认绑定本机ip
interface eth0 #绑定的网卡,可以通过ifconfig查看网卡信息
virtual_router_id 70 #虚拟路由标识,同一组的必须相同
priority 90 #权重,备节点的权重要比主节点小
advert_int 1 #与组内其他节点发送心跳的间隔:s。组内间隔必须相同
virtual_ipaddress {
172.17.0.200
} #绑定的虚拟ip组
track_script {
chk_nginx
} #执行前面声明的脚本
}
提示:其中的interface项需要自行ifconfig查看,我的都是eth0。(注释部分自行删除哈哈哈哈)
7.开始测试
分别启动两容器中nginx:
nginx
分别启动两容器中keepalived:
systemctl start keepalived.service
在MASTER中查看是否绑定vip,可以发现已绑定172.17.0.200:
ip a
此时使用第三台docker,即webtest,进行测试:
curl 172.17.0.200
可以发现,目前访问的是MASTER。
此时在web1中关闭keepalived,即关闭主节点,然后再在webtest中curl:
systemctl stop keepalived.service
curl 172.17.0.200
Ok!大功告成!