文章目录
前言
我们通过访问nginx服务器去真正的web服务器正常的情况下一点问题都没有,但是一旦nginx服务器由于不可控的原因挂掉了,而且在生产环境上,那就是灾难性的故障,所以给nginx服务器做热备还是非常有必要的。此时我们就可以结合keepalived对前端nginx实现HA高可用。
在Keepalived + Nginx高可用负载均衡架构中,keepalived负责实现High-availability (HA) 功能控制前端机VIP(虚拟网络地址),当有设备发生故障时,热备服务器可以瞬间将VIP自动切换过来,实际运行中体验只有2秒钟切换时间,DNS服务可以负责前端VIP的负载均衡。
一、体系架构
nginx负责控制后端web服务器的负载均衡,将客户端的请求按照一定的算法转发给后端Real Server处理,而Real Server将响应直接返回给客户端。
NGINX_MASTER、NGINX_BACKUP两台服务器均通过keepalived软件把ens32网卡绑上一个虚拟IP(VIP)地址172.16.12.10,此VIP当前由谁承载着服务就绑定在谁的ens32上,当NGINX_MASTER发生故障时,NGINX_BACKUP会通过/etc/keepalived/keepalived.conf文件中设置的心跳时间advert_int 1检查,无法获取NGINX_MASTER正常状态的话,NGINX_BACKUP会瞬间绑定VIP来接替nginx_master的工作,当NGINX_MASTER恢复后keepalived会通过priority参数判断优先权将虚拟VIP地址172.16.12.10重新绑定给NGINX_MASTER的ens32网卡。
二、实现步骤
1.配置服务器环境
1)关闭防火墙:
systemctl stop firewalld
systemctl disable firewalld
systemctl status firewalld
1)时间同步
设置时区及时钟格式
timedatectl status
timedatectl set-timezone Asia/Shanghai
timedatectl set-time “YYYY-MM-DD HH:MM:SS”
timedatectl set-ntp yes
安装配置Chrony
yum -y install chrony
systemctl start chronyd
systemctl enable chronyd
配置Chrony
修改/etc/chrony.conf,指向内网时钟源
vi /etc/chrony.conf
server 172.16.12.12 iburst
安装openssl
yum install wget make gcc gcc-c++ openssl-devel
配置防火墙允许vrrp协议
firewall-cmd --permanent --add-rich-rule=“rule family=“ipv4” source address=“192.168.169.131” protocol value=“vrrp” accept”
firewall-cmd --reload
2.nginx安装及负载web服务器
nginx负载均衡服务器安装及web服务器(tomact)安装之前有写过,在此就不详细写了,附上连接
3.安装配置keepalived
1.安装keepalived(在两个节点上都安装)
yum install -y keepalived
2.修改keepalived
/etc/keepalived/keepalived.conf
Keepalive配置文件说明
# 全局配置
global_defs {
# 邮件通知信息
notification_email {
# 定义收件人
acassen@firewall.loc
}
# 定义发件人
notification_email_from Alexandre.Cassen@firewall.loc
# SMTP服务器地址
smtp_server 172.16.12.12
smtp_connect_timeout 30
# 路由器标识,一般不用改,也可以写成每个主机自己的主机名
router_id LVS_DEVEL
# VRRP的ipv4和ipv6的广播地址,配置了VIP的网卡向这个地址广播来宣告自己的配置信息,下面是默认值
vrrp_mcast_group4 172.16.12.10
vrrp_mcast_group6 ff01::10
}
# 定义用于实例执行的脚本内容,比如可以在线降低优先级,用于强制切换
vrrp_script SCRIPT_NAME {
}
# 一个vrrp_instance就是定义一个虚拟路由器的,实例名称
vrrp_instance VI_1 {
# 定义初始状态,可以是MASTER或者BACKUP
state MASTER
# 工作接口,通告选举使用哪个接口进行
interface ens33
# 虚拟路由ID,如果是一组虚拟路由就定义一个ID,如果是多组就要定义多个,而且这个虚拟
# ID还是虚拟MAC最后一段地址的信息,取值范围0-255
virtual_router_id 51
# 使用哪个虚拟MAC地址
use_vmac XX:XX:XX:XX:XX
# 监控本机上的哪个网卡,网卡一旦故障则需要把VIP转移出去
track_interface {
eth0
ens33
}
# 如果你上面定义了MASTER,这里的优先级就需要定义的比其他的高
priority 100
# 通告频率,单位为秒
advert_int 1
# 通信认证机制,这里是明文认证还有一种是加密认证
authentication {
auth_type PASS
auth_pass 1111
}
# 设置虚拟VIP地址,一般就设置一个,在LVS中这个就是为LVS主机设置VIP的,这样你就不用自己手动设置了
virtual_ipaddress {
# IP/掩码 dev 配置在哪个网卡
172.16.12.11/24 dev eth1
# IP/掩码 dev 配置在哪个网卡的哪个别名上
172.16.12.12/24 dev label eth1:1
}
# 虚拟路由,在需要的情况下可以设置lvs主机 数据包在哪个网卡进来从哪个网卡出去
virtual_routes {
172.16.12.10/24 dev eth2
}
# 工作模式,nopreempt表示工作在非抢占模式,默认是抢占模式 preempt
nopreempt|preempt
# 如果是抢占默认则可以设置等多久再抢占,默认5分钟
preempt delay 300
# 追踪脚本,通常用于去执行上面的vrrp_script定义的脚本内容
track_script {
}
# 三个指令,如果主机状态变成Master|Backup|Fault之后会去执行的通知脚本,脚本要自己写
notify_master ""
notify_backup ""
notify_fault ""
}
# 定义LVS集群服务,可以是IP+PORT;也可以是fwmark 数字,也就是防火墙规则
# 所以通过这里就可以看出来keepalive天生就是为ipvs而设计的
virtual_server 10.10.10.2 1358 {
delay_loop 6
# 算法
lb_algo rr|wrr|lc|wlc|lblc|sh|dh
# LVS的模式
lb_kind NAT|DR|TUN
# 子网掩码,这个掩码是VIP的掩码
nat_mask 255.255.255.0
# 持久连接超时时间
persistence_timeout 50
# 定义协议
protocol TCP
# 如果后端应用服务器都不可用,就会定向到那个服务器上
sorry_server 172.16.12.101 1358
# 后端应用服务器 IP PORT
real_server 172.16.12.102 1358 {
# 权重
weight 1
# MSIC_CHECK|SMTP_CHEKC|TCP_CHECK|SSL_GET|HTTP_GET这些都是
# 针对应用服务器做健康检查的方法
MISC_CHECK {}
# 用于检查SMTP服务器的
SMTP_CHEKC {}
# 如果应用服务器不是WEB服务器,就用TCP_CHECK检查
TCP_CHECK {
# 向哪一个端口检查,如果不指定默认使用上面定义的端口
connect_port <PORT>
# 向哪一个IP检测,如果不指定默认使用上面定义的IP地址
bindto <IP>
# 连接超时时间
connect_timeout 3
}
# 如果对方是HTTPS服务器就用SSL_GET方法去检查,里面配置的内容和HTTP_GET一样
SSL_GET {}
# 应用服务器UP或者DOWN,就执行那个脚本
notify_up "这里写的是路径,如果脚本后有参数,整体路径+参数引起来"
notify_down "/PATH/SCRIPTS.sh 参数"
# 使用HTTP_GET方法去检查
HTTP_GET {
# 检测URL
url {
# 具体检测哪一个URL
path /testurl/test.jsp
# 检测内容的哈希值
digest 640205b7b0fc66c1ea91c463fac6334d
# 除了检测哈希值还可以检测状态码,比如HTTP的200 表示正常,两种方法二选一即可
status_code 200
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
url {
path /testurl3/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334d
}
# 向哪一个端口检查,如果不指定默认使用上面定义的端口
connect_port <PORT>
# 向哪一个IP检测,如果不指定默认使用上面定义的IP地址
bindto <IP>
# 连接超时时间
connect_timeout 3
# 尝试次数
nb_get_retry 3
# 每次尝试之间间隔几秒
delay_before_retry 3
}
}
real_server 192.168.200.3 1358 {
weight 1
HTTP_GET {
url {
path /testurl/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
url {
path /testurl2/test.jsp
digest 640205b7b0fc66c1ea91c463fac6334c
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
3.配置Srv01和Srv02
1)配置VRRP部分
Srv01上的keepalived.conf
global_defs {
notification_email {
acassen@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id srv01
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.12.11/24 brd 172.16.12.11 dev ens33 label ens33:0
}
preempt delay 60
}
Srv02上的keepalived.conf,唯一不同的就是state、priority以及router_id。
global_defs {
notification_email {
acassen@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id srv02
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.12.12/24 brd 172.16.12.12 dev ens33 label ens33:0
}
preempt delay 60
}
启动2个节点,启动后会自动配置ens33:0这个子接口的虚拟IP
systemctl start keepalived
三、测试
1.查看Srv01启动状态
systemctl status keepalived
在主节点上你通过启动状态看不到它到底是什么角色,不过在BACKUP节点上你可以看到
2.查看Srv02的状态
systemctl status keepalived
如果停止Srv01上的keepalived服务就看到MASTER会被转移到Srv02上
3.查看启动日志
cat /var/log/message
在主节点日志中里可以看到Srv01进入到MASTER状态
3.查看VRRP通告
tcpdum -i ens33 -nn host 224.0.0.18
会在2台主机都会看到相同的信息
Srv01使用真实物理IP对该地址进行发送通告,那么Srv02也会收到,如果Srv01宕机,那么Srv02就会使用自己的物理IP向该地址发送通告,由于Srv01已经宕机那么此时Srv02的优先级就是最高的,所以Srv02就变成了MASTER。
4.通过虚拟IP访问项目
可以看到通过172.16.12.10:8080访问到的是三台不同的WEB服务器
5.keepalived关闭测试
关闭nginx-master机器上的keepalived服务
systemctl stop keepalived
发现虚IP被绑定到了备机上,服务也能正常访问
6.nginx关闭测试
systemctl stop nginx
发现虚IP被绑定到了备机上,服务也能正常访问,但是目前nginx不能自动重启,此问题可以引入docker容器解决
添加检查nginx状态的脚本
vim /etc/keepalived/nginx_pid.sh
#!/bin/bash
#version 0.0.1
#
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
systemctl restart docker
sleep 3
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
systemctl stop keepalived
fi
fi
脚本说明:当nginx进程不存在时,会自动重启docker服务,docker服务启动时会自动启动nginx容器;再次检查nginx进程,如果不存在,就停止keepalived服务,然后NGINX_BACKUP主机会自动接替NGINX_MASTER的工作。
chmod +x /etc/keepalived/nginx_pid.sh