场景说明:
在实际的生产项目中,我们对服务要实现高可用,这种效果可以用nginx实现;
但是nginx只有一台,若nginx的服务器宕了,高可用也就无法实现;
所以可以通过keepalived实现nginx的高可用。
1)当主节点Nginx服务无法启动,或者主节点服务器宕机,VIP将漂移到备用节点;
2)当主节点服务恢复(服务器启动、KeepAlived和Nginx服务正常运行),备用节点将会进行备用状态,并移除VIP,VIP将漂移回主节点。(其中vip的漂移是通过主机keepalived的关闭才会漂移到备机上的。所以主机的nginx服务重新启动时,需要先启动nginx,再启动keepalived)
本文通过虚拟机模拟实现该场景:
服务器A安装nginx和keepalived实现服务的主备切换。
服务器B安装nginx和keepalived实现服务的主备切换。
服务器C和D分别为应用服务。
服务器 | IP地址 | 端口 | 服务 |
A | 192.168.108.27 | 9001 | Keepalived+nginx(主) |
B | 192.168.108.22 | 9001 | Keepalived+nginx(备) |
C | 192.168.108.10 | 8080 | Nginx模拟主服务 |
D | 192.168.108.12 | 8080 | Nginx模拟备服务 |
服务器C、D安装nginx模拟应用
首先在服务器C和D上安装nginx模拟生产要用的服务,
使用服务器C,D的8080端口模拟实际的应用服务:
访问http://192.168.108.10:8080
访问http://192.168.108.12:8080
服务器A、B安装keepalived和nginx
A/B两个nginx的配置文件
upstream server_HA{
server 192.168.108.10:8080;
server 192.168.108.12:8080 backup;
}
server {
listen 9001;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
proxy_pass http://server_HA;
}
启动A、B的nginx后访问效果是一样的,因为本来就是主备嘛:
A:http://192.168.108.27:9001
B:http://192.168.108.22:9001
此时kill掉应用的主服务,kill掉C (192.168.108.10)的nginx效果:
会自动指向备服务D (192.168.108.12)上
但是,此时如果把A(192.168.108.27)的nginx kill掉,那么是没有高可用效果的,所以需要通过keepalived来实现!
Keepalived的安装
下载地址:Keepalived for Linux
离线安装:
tar -zxvf keepalived-2.2.7.tar.gz
进行编译安装:
./configure --prefix=/usr/local/keepalived --sysconf=/etc
增加--sysconf=/etc后,配置文件会安装在/etc目录下
make && make install
安装后的目录如下:
keepalived的etc配置文件通过编译时的指向,已经到/etc目录下
这样在编辑keepalived.conf配置文件后,可以通过systemctl start keepalived 的命令来启动keepalived。
A主机配置文件为:
! Configuration File for keepalived
global_defs { #全局变量
router_id nginx #路由器标识,可以不改,也可以自定义
}
vrrp_script check_nginx { #监控脚本,名称和下面脚本模块的名称一致即可
script "/etc/keepalived/nginx_check.sh"
interval 2
weight -20
}
#一个vrrp_instance就是定义一个虚拟路由器的,实例名称
vrrp_instance VI_1 {
state MASTER
interface ens33 #当前使用的网卡名
virtual_router_id 51 #虚拟路由id号
priority 100 #当前服务器优先级,数字越大越优先
advert_int 1 #检测心跳时间为1秒
authentication { #身份验证方式通信认证机制,这里是明文认证还有一种是加密认证
auth_type PASS
auth_pass 1111
}
#VIP地址
virtual_ipaddress {
192.168.108.30
}
track_script{
# 脚本模块,这里可以指定多个脚本
check_nginx
}
}
通过priority 表示优先级,如果想设置非强制模式用参数:
nopreempt #非抢占模式,即主故障后切到备机,主在起来,VIP还在备机上
!!!需要注意的是主从节点的virtual_router_id 需要一致,但是同一网段内不同的keepalived集群的virtual_router_id 不能相同。
B备机的配置文件只需改以下两处即可:
nginx_check.sh监控脚本为:
#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
# 判断nginx是否宕机,如果宕机了,尝试重启
if [ $A -eq 0 ];then
# nginx位置
/usr/local/nginx/sbin/nginx
# 等待3秒再次检查nginx,如果没有启动成功,则停止keepalived,使其启动备用机
sleep 3
echo 'Failed: nginx is down'> /etc/keepalived/log
if [ 'ps -C nginx --no-header | wc -l' -eq 0 ]; then
killall keepalived
fi
fi
最终效果:
访问虚拟VIP:http://192.168.108.30:9001
若手动把主机A的nginx给kill掉,监控脚本会自动启动nginx;
若手动把主机A的keepalived和nginx给kill掉,查看A的ip地址,vip已经不见了
查看备机B的ip地址情况:
访问虚拟VIP:http://192.168.108.30:9001 还是正常
如果此时,把A主机的keepalived启动,那么vip会漂浮到主机A上,因为我们在keepalived.conf中设置A的优先级更高
查看A主机的ip地址,可以看到vip已经漂浮回主机上: