# Nginx 高可用 - Keepalived

# 1. 高可用基本概述

# 1.1 什么是高可用
  • 简单理解:两台机器启动着相同的业务系统,当有一台机器宕机,另外一台服务器能快速的接管,对于访问的用户是无感知的;

  • 专业理解:高可用是分布式系统架构设计中必要的一环,主要目的:减少系统不能提供服务的时间。假设系统一直能够提供服务,我们说系统的可用性是 100%。如果系统每运行 100 个时间单位,会有 1 个时间单位无法提供服务,我们说系统的可用性是 99%;

  • 高可用的目的:减少系统 down 机时间,提高 SLA 服务等级;

# 1.2 高可用使用什么工具

通常服务高可用我们选择使用 keepalived 软件实现。

# 1.3 高可用是如何实现的
  • keepalived 软件是基于 VRRP 协议实现的。
  • VRRP 虚拟路由冗余协议,主要用于解决单点故障问题。
# 1.4 VRRP 诞生背景及原理

比如公司的网络是通过网关转换进行上网的,那如果该路由器故障了,网关无法转发报文了,此时所有人都将无法上网,这么时候怎么办呢?

1.jpg

通常做法是增加一个 Backup 路由,然后修改用户 PC 电脑网关指向为 Backup,但这里有几个问题

  • 1. 如果用户过多修改起来是不是会非常的麻烦;
  • 2. 如果用户将指向都修改为 Backup,那 Master 如果恢复了该怎么办?

那我们直接将 Backup 网关 IP 配置为 Master 网关 IP 不就可以了吗?(其实也不行,why)

  • 因为 PC 在第一次通信时,是通过 ARP 广播获取到 Master 网关的 Mac 地址、IP 地址,同时 PC 还会将 Master 网关对应 IP 与 MAC 地址存储至 ARP 缓存表中;
  • 所以当 PC 与网关进行通信时,会直接读取 ARP 缓存表中的 MAC 地址与 IP 地址,进行数据包转发,也就意味着当 Master 节点故障,将 Backup 节点 IP 修改为 Master 的 IP,最终 PC 的数据包还是会转发给 Master,不会转发给 Backup 节点。(除非 PC 的 ARP 缓存表过期,在次发起 ARP 广播的时候才能正确获取 Bakcup 的 Mac 地址与对应的 IP 地址。)

2.jpg

  • 那如何才能做到出现故障自动转移,此时 VRRP 就应运而生;
  • VRRP 其实是通过软件或硬件的形式在 Master 和 Backup 外层增加一个虚拟 MAC 地址(简称 VMAC)、以及虚拟 IP 地址(简称 VIP);
  • 那么在这种情况下,当 PC 请求 VIP 的时候,无论是 Master 处理还是 Backup 处理,PC 仅会在 ARP 缓存表中记录 VMAC 与 VIP 的对应关系。

3.jpg

# 2. 高可用 Keepalived

# 2.1 Keeplaived 基本介绍

Keepalived 基于 vrrp 实现,原生设计是为了高可用 lvs 服务。

  • 通过 vrrp 协议,可以完成地址漂移技术;
  • 为 vip 地址所在的节点生成 ipvs 规则(需要在配置文件中预先定义);
  • 为 ipvs 集群的 RS 节点做健康状态检测;

Keepalived 核心组件:

  • vrrp stack:用来实现 vrrp 协议重要组件之一;
  • Netlink 接口:设置和删除网络接口上的虚拟 IP 地址;
  • ipvs wrapper:使用 getsock 和 setsock 来建立 IPVS 规则;
  • checkers:监测 RS 节点的方式,支持 tcp、http、ssl 等;
  • system call:支持启动额外系统脚本的功能;
  • SMTP:为 当发生角色状态转换时,发送事件通知邮件;
  • WatchDog:监控进程

4.jpg

# 2.2 Keepalived 核心概念
  • 虚拟路由器:由一个 Master 路由器和多个 Backup 路由器组成;
  • Master 路由器:虚拟路由器中承担报文转发任务的路由器;
  • Backup 路由器:Master 路由器出现故障时,能够代替 Master 路由器工作的路由器;
  • VRID:虚拟路由器的标识,由相同 VRID 的一组路由器构成一个虚拟路由器;
  • 组播:组播是有特定的成员,是一种可控的广播,组播成员需要加入 “组播组” 才能收到该组播的信息。
  • 虚拟 IP 地址:虚拟路由器的 IP 地址,一个虚拟路由器可以拥有一个或多个 IP 地址;
  • 虚拟 MAC 地址:一个虚拟路由器拥有一个虚拟 MAC 地址;
  • 优先级:VRRP 根据优先级来确定虚拟路由器中每台路由器的地位;
  • 抢占式:如果 Master 故障,Backup 自动接管,当 Master 恢复了会将 VIP 地址抢回来;
  • 非抢占式:如果 Master 故障,Backup 自动接管,当 Master 恢复则自动转为 Backup,不会抢占 VIP;

5.jpg

# 2.3 Keeplaived 应用场景

当需要使用 Keepalived 时,通常是因为我们的业务系统需要保证 7x24 小时不 DOWN 机,也就是说作为企业的业务系统,要保证随时随地都可以使用,不可以中断。

  • 比如公司内部 OA 系统,每天公司人员都需要使用,则不允许 Down 机;
  • 比如公司对外发布的业务系统(单车),每天有大量的用户使用,是不可以出现故障的;
# 2.4 Keeplaived 安装配置
# 2.4.1 环境准备
主机名称eth0eth1角色
proxy0110.0.0.5172.16.0.5Master
proxy0210.0.0.6172.16.0.6Backup
VIP 地址10.0.0.100

在 Master 以及 Backup 节点分别安装 Keepalived

[root@proxy01 ~]# yum install keepalived -y
[root@proxy02 ~]# yum install keepalived -y
# 2.4.2 配置 Master
[root@proxy01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {     
    router_id lb01                  # 当前物理设备的标识名称
    vrrp_mcast_group4 224.0.0.18    # 组播地址,default 224.0.0.18
}
vrrp_instance VI_1 {
    state MASTER                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 200                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
}
[root@proxy01 ~]# systemctl enable keepalived && systemctl start keepalived
# 2.4.3 配置 Backup
[root@proxy02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {     
    router_id lb02                  # 当前物理设备的标识名称
    vrrp_mcast_group4 224.0.0.18   # 组播地址,default 224.0.0.18
}
vrrp_instance VI_1 {
    state BACKUP                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 100                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
}
[root@proxy02 ~]# systemctl enable keepalived && systemctl start keepalived
# 2.4.4 地址漂移测试

检查 keepalived 的 VIP 地址能否在两个节点间漂移。

1. 在 Master 上进行如下操作

# Master 存在 vip 地址
[root@proxy01 ~]# ip addr |grep 192.168.40.100
    inet 192.168.40.100/32 scope global eth0
    
[root@proxy01 ~]# systemctl stop keepalived

2. 在 Backup 上进行如下操作

# 发现地址已经漂移至 Backup 端
[root@proxy02 ~]# ip addr |grep 192.168.40.100
    inet 192.168.40.100/32 scope global eth0

3. 此时启动 Master 上的 Keepalived,会发现 VIP 被强行抢占

[root@proxy01 ~]# systemctl start keepalived
[root@proxy01 ~]# ip addr |grep 192.168.40.100
    inet 192.168.40.100/32 scope global eth0

4. 通过 windows 查看 arp 缓存表,验证地址漂移后是否会自动更新 MAC 地址。

接口: 192.168.40.1 --- 0xb
  Internet 地址         物理地址              类型
  192.168.40.5          00-0c-29-36-d2-b6     动态
  192.168.40.6          00-0c-29-14-f6-61     动态
  192.168.40.100        00-0c-29-36-d2-b6     动态
# 2.4.5 抓包分析切换过程

通过 抓包分析 keepalived 地址切换过程。

1.jpg

# 2.5 Keepalived 延迟抢占

延迟抢占指的是,当 Master 故障后,Backup 接管,当 Master 恢复后不立即抢占 VIP 地址,延迟一段时间在抢占 VIP。

配置延迟抢占式步骤如下:

1、两台节点的 state 都必须配置为 BACKUP;

2、在节点的 vrrp_instance 中添加 preempt_delay

#1. Master 配置
[root@proxy01 ~]# cat /etc/keepalived/keepalived.conf 
global_defs {     
    router_id lb01                  # 当前物理设备的标识名称
    vrrp_mcast_group4 224.0.0.18    # 组播地址,default 224.0.0.18
}
vrrp_instance VI_1 {
    state BACKUP                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 200                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    preempt_delay 10s               # 延迟 10s 后抢占
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
}
#2. Backup 配置
[root@proxy02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {     
    router_id lb02                  # 当前物理设备的标识名称
    vrrp_mcast_group4 224.0.0.18   # 组播地址,default 224.0.0.18
}
vrrp_instance VI_1 {
    state BACKUP                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 100                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    preempt_delay 10s               # 延迟 10s 后抢占
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
}
# 2.6 Keepalived 非抢占式

通常 master 服务故障后 backup 会变成 master,但是当 master 服务恢复后,master 会抢占 VIP,这样就会发生两次切换;对业务繁忙的网站来说并不是太友好,此时我们可以配置 keepalived 为非抢占式,(前提两台主机的硬件配置信息一致);

配置非抢占式步骤如下

1、两台节点的 state 都必须配置为 BACKUP;

2、两台节点都在 vrrp_instance 中添加 nopreempt 参数;

3、其中一个节点的优先级必须要高于另外一个节点的优先级;

#1. Master 配置
[root@proxy01 ~]# cat /etc/keepalived/keepalived.conf 
global_defs {     
    router_id lb01                  # 当前物理设备的标识名称
    vrrp_mcast_group4 224.0.0.18    # 组播地址,default 224.0.0.18
}
vrrp_instance VI_1 {
    state BACKUP                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 200                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #preempt_delay 10s               # 延迟 10s 后抢占
    nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
}
#2. Backup 配置
[root@proxy02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {     
    router_id lb02                  # 当前物理设备的标识名称
    vrrp_mcast_group4 224.0.0.18   # 组播地址,default 224.0.0.18
}
vrrp_instance VI_1 {
    state BACKUP                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 100                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #preempt_delay 10s               # 延迟 10s 后抢占
    nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
}
# 2.7 Keeplaived 邮件通知

1. 配置邮箱(所有节点都需要配置)

#1. 生成证书
sudo mkdir -p  /root/.certs
sudo bash -c "echo -n | openssl s_client -connect smtp.qq.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /root/.certs/qq.crt" 
sudo chmod +x /root/.certs/qq.crt
sudo bash -c 'certutil -A -n "GeoTrust Global CA" -t "C,," -d /root/.certs -i /root/.certs/qq.crt'
sudo bash -c 'certutil -A -n "GeoTrust SSL CA" -t "C,," -d /root/.certs -i /root/.certs/qq.crt'
sudo bash -c 'certutil -A -n "GeoTrust SSL CA - G3" -t "Pu,Pu,Pu" -d  /root/.certs -i /root/.certs/qq.crt'
#2. 配置 mailx
[root@proxy01 ~]# # yum install mailx -y
[root@proxy01 ~]# cat >> /etc/mail.rc <<EOF
set from=373370405@qq.com
set smtp=smtp.qq.com:587
set smtp-auth=login
set smtp-auth-user=373370405@qq.com
set smtp-auth-password=zmuthwvermvrbjgg
set smtp-use-starttls
set ssl-verify=ignore
set nss-config-dir=/root/.certs
EOF
#3. 邮箱测试
[root@proxy01 ~]# echo "这是邮件内容" | mailx -s "邮件主题" 373370405@qq.com
[root@proxy01 ~]# mail -s "test" "373370405@qq.com" < /etc/hosts

2. 通知脚本(所有节点都需要配置)

[root@proxy01 ~]# cat /etc/keepalived/notify.sh
#!/usr/bin/bash
# Author: Oldxu(E-mail: xuy@nf-leasing.com)
##Keepalived 故障切换邮件通知
# 定义收件人
Email='373370405@qq.com'
# 定义主机名称
Host=$(hostname)
Addr=$(ifconfig eth0|awk 'NR==2 {print $2}')
# 定义时间变量
Date=$(date +'%F %T')
#定义发送的消息
Message() {
	subject="${Host}-${Addr} 切换为 $1 状态"
	submsg="${Date}: ${Host}-${Addr} 成功切换为 $1 状态"
	echo "${submsg}" | mail -s "${subject}" "${Email}"
}
case $1 in
	master)
		Message master
		;;
	backup)
		Message backup
		;;
	fault)
		Message fault
		;;
	*)
		echo "Usage: $0 { master | backup | fault }"
		exit
esac		
[root@proxy01 ~]# chmod +x /etc/keepalived/notify.sh

3. 修改配置 (Master)

[root@proxy01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {     
    router_id lb01                  # 当前物理设备的标识名称
    vrrp_mcast_group4 224.0.0.18    # 组播地址,default 224.0.0.18
}
vrrp_instance VI_1 {
    state MASTER                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 200                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #preempt_delay 10s               # 延迟 10s 后抢占
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
    notify_master "/etc/keepalived/notify.sh master"  # 当前节点成为主节点时触发的脚本
    notify_backup "/etc/keepalived/notify.sh backup"  # 当前节点转为备节点时触发的脚本
    notify_fault "/etc/keepalived/notify.sh fault"    # 当前节点转为 “失败” 状态时触发的脚本
}

4. 修改配置 (Backup)

[root@proxy02 ~]# cat /etc/keepalived/keepalived.conf 
global_defs {     
    router_id lb02                  # 当前物理设备的标识名称
    vrrp_mcast_group4 224.0.0.18   # 组播地址,default 224.0.0.18
}
vrrp_instance VI_1 {
    state BACKUP                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 100                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #preempt_delay 10s               # 延迟 10s 后抢占
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
    notify_master "/etc/keepalived/notify.sh master"  # 当前节点成为主节点时触发的脚本
    notify_backup "/etc/keepalived/notify.sh backup"  # 当前节点转为备节点时触发的脚本
    notify_fault "/etc/keepalived/notify.sh fault"    # 当前节点转为 “失败” 状态时触发的脚本
}

5. 停止所有节点的 Keepalived,先启动 Backup 节点,然后启动 Master 节点;

# Backup
[root@proxy02 ~]# systemctl restart keepalived

# 等待邮件发送成功在启动 Master

# Master
[root@proxy01 ~]# systemctl start keepalived
# 2.8 Keepalived 双主模式

两个或以上 VIP 分别运行在不同的 keepalived 服务器;实现服务器并行访问 web 应用,提高服务器资源利用率。

1.jpg

# proxy01 配置
[root@proxy01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {     
    router_id lb01                  # 当前物理设备的标识名称
    vrrp_mcast_group4 224.0.0.18    # 组播地址,default 224.0.0.18
}
vrrp_instance VI_1 {
    state MASTER                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 200                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #preempt_delay 10s               # 延迟 10s 后抢占
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
    notify_master "/etc/keepalived/notify.sh master"  # 当前节点成为主节点时触发的脚本
    notify_backup "/etc/keepalived/notify.sh backup"  # 当前节点转为备节点时触发的脚本
    notify_fault "/etc/keepalived/notify.sh fault"    # 当前节点转为 “失败” 状态时触发的脚本
}
vrrp_instance VI_2 {
    state BACKUP                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 55            # 当前虚拟路由标识,VRID;
    priority 100                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #preempt_delay 10s               # 延迟 10s 后抢占
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    virtual_ipaddress {
        192.168.40.101        # VIP 地址
    }
    notify_master "/etc/keepalived/notify.sh master"  # 当前节点成为主节点时触发的脚本
    notify_backup "/etc/keepalived/notify.sh backup"  # 当前节点转为备节点时触发的脚本
    notify_fault "/etc/keepalived/notify.sh fault"    # 当前节点转为 “失败” 状态时触发的脚本
}
# proxy02
[root@proxy02 ~]# cat /etc/keepalived/keepalived.conf 
global_defs {     
    router_id lb02                  # 当前物理设备的标识名称
    vrrp_mcast_group4 224.0.0.18    # 组播地址,default 224.0.0.18
}
vrrp_instance VI_1 {
    state BACKUP                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 100                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #preempt_delay 10s               # 延迟 10s 后抢占
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
    notify_master "/etc/keepalived/notify.sh master"  # 当前节点成为主节点时触发的脚本
    notify_backup "/etc/keepalived/notify.sh backup"  # 当前节点转为备节点时触发的脚本
    notify_fault "/etc/keepalived/notify.sh fault"    # 当前节点转为 “失败” 状态时触发的脚本
}
vrrp_instance VI_2 {
    state MASTER                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 55            # 当前虚拟路由标识,VRID;
    priority 200                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #preempt_delay 10s               # 延迟 10s 后抢占
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    virtual_ipaddress {
        192.168.40.101        # VIP 地址
    }
    notify_master "/etc/keepalived/notify.sh master"  # 当前节点成为主节点时触发的脚本
    notify_backup "/etc/keepalived/notify.sh backup"  # 当前节点转为备节点时触发的脚本
    notify_fault "/etc/keepalived/notify.sh fault"    # 当前节点转为 “失败” 状态时触发的脚本
}
#验证测试
[root@proxy01 ~]# ip addr|grep 192.168.40.100
    inet 192.168.40.100/32 scope global eth0
[root@proxy02 ~]# ip addr|grep 192.168.40.101
    inet 192.168.40.101/32 scope global eth0
    
[root@proxy01 ~]# systemctl stop keepalived
[root@proxy02 ~]# ip addr|grep 192.168.40.101
    inet 192.168.40.101/32 scope global eth0
[root@proxy02 ~]# ip addr|grep 192.168.40.100
    inet 192.168.40.100/32 scope global eth0

# 3. 高可用 Nginx 实践

# 3.1 高可用 Nginx

1.Nginx 与 Keepalived 之间是什么关系?

没关系。Nginx 仅借助 Keepalived 的 VIP 地址漂移技术,从而实现的高可用;

2. 如果 Nginx 无法访问,keepalived 的 VIP 会自动漂移至 Backup 节点吗?

不能,因为 Keepalived 与 Nginx 之间没有关系;当 Nginx 不存活时,会导致用户请求失败,但 Keepalived 虚拟地址并不会进行漂移,所以需要编写一个 keepalived 辅助脚本,监 nginx;

  • 1. 当监控到 Nginx 处于非活动状态,则动态调整优先级状态,确保备节点能正常接管 VIP;
  • 2. 当监控到 Nginx 处于活动状,则重新抢占 VIP 地址
# 3.2 高可用 Nginx 实战
# 3.2.1 web01 配置
[root@web01 conf.d]# cat s.hmallleasing.com.conf 
server {
	listen 80;
	server_name s.hmallleasing.com;
	root /code;
	
	location / {
		index index.html;
	}
}
[root@web01 conf.d]# cat /code/index.html 
web01-https...
# 3.2.2 web02 配置
[root@web02 conf.d]# cat s.hmallleasing.com.conf 
server {
	listen 80;
	server_name s.hmallleasing.com;
	root /code;
	
	location / {
		index index.html;
	}
}
[root@web02 conf.d]# cat /code/index.html 
web02-https...
# 3.2.3 proxy01 配置
[root@proxy01 conf.d]# cat /etc/nginx/conf.d/s.hmallleasing.com.conf 
upstream site {
	keepalive 32;                       #最大的空闲连接数
	keepalive_timeout 100s;             #空闲连接的超时时间
	server 192.168.40.7:80 max_fails=2 fail_timeout=10s;
	server 192.168.40.8:80 max_fails=2 fail_timeout=10s;
}
# https 站点配置信息
server {
	listen 443 ssl;
	server_name s.hmallleasing.com;
	ssl_prefer_server_ciphers on;
	ssl_protocols TLSv1.2;
        ssl_certificate ssl_key/hmallleasing.com.pem;
        ssl_certificate_key  ssl_key/hmallleasing.com.key;
	
	ssl_session_cache shared:SSL:10m;
	ssl_session_timeout 1440m;
	location / {
		proxy_pass http://site;
		include proxy_params;
                #当其中一台返回错误 500,502,503,504 时,分配下一台服务器程序处理,提高平台访问成功率
		proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
		proxy_next_upstream_tries 2;
		proxy_next_upstream_timeout 3s;
	}
}
# 用户请求 http 协议,强制跳转至 https 协议
server {
	listen 80;
	server_name s.hmallleasing.com;
	return 302 https://$server_name$request_uri;
}
[root@proxy01 conf.d]# cat /etc/nginx/proxy_params 
proxy_http_version 1.1;
proxy_set_header Connectin "";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 120;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
proxy_temp_file_write_size 10240k;
proxy_max_temp_file_size 10240k;
[root@proxy01 conf.d]# mkdir /etc/nginx/ssl_key
[root@proxy01 conf.d]# ll /etc/nginx/ssl_key
-rw-r--r-- 1 root root 1675 Sep  8 17:43 hmallleasing.com.key
-rw-r--r-- 1 root root 4784 Sep  8 17:43 hmallleasing.com.pem
[root@proxy01 conf.d]# nginx -t
[root@proxy01 conf.d]# systemctl reload nginx
# 3.2.4 proxy01 配置
[root@proxy02 ~]# cat /etc/nginx/conf.d/s.hmallleasing.com.conf
upstream site {
	keepalive 32;                       #最大的空闲连接数
	keepalive_timeout 100s;             #空闲连接的超时时间
	server 192.168.40.7:80 max_fails=2 fail_timeout=10s;
	server 192.168.40.8:80 max_fails=2 fail_timeout=10s;
}
# https 站点配置信息
server {
	listen 443 ssl;
	server_name s.hmallleasing.com;
	ssl_prefer_server_ciphers on;
	ssl_protocols TLSv1.2;
        ssl_certificate ssl_key/hmallleasing.com.pem;
        ssl_certificate_key  ssl_key/hmallleasing.com.key;
	
	ssl_session_cache shared:SSL:10m;
	ssl_session_timeout 1440m;
	location / {
		proxy_pass http://site;
		include proxy_params;
                #当其中一台返回错误 500,502,503,504 时,分配下一台服务器程序处理,提高平台访问成功率
		proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
		proxy_next_upstream_tries 2;
		proxy_next_upstream_timeout 3s;
	}
}
# 用户请求 http 协议,强制跳转至 https 协议
server {
	listen 80;
	server_name s.hmallleasing.com;
	return 302 https://$server_name$request_uri;
}
[root@proxy02 ~]# cat /etc/nginx/proxy_params
proxy_http_version 1.1;
proxy_set_header Connectin "";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 120;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
proxy_temp_file_write_size 10240k;
proxy_max_temp_file_size 10240k;
[root@proxy02 ~]# mkdir /etc/nginx/ssl_key
[root@proxy02 ~]# ll /etc/nginx/ssl_key
-rw-r--r-- 1 root root 1675 Sep  8 17:44 hmallleasing.com.key
-rw-r--r-- 1 root root 4784 Sep  8 17:44 hmallleasing.com.pem
[root@proxy02 ~]# nginx -t.
[root@proxy02 ~]# systemctl reload nginx
# 3.2.5 proxy01 配置 keepalived
[root@proxy01 ~]# cat /etc/keepalived/keepalived.conf 
global_defs {     
    router_id lb01                  # 当前物理设备的标识名称
}
vrrp_script check_nginx {
        # 一条指令或者一个脚本文件,需返回 0 (成功) 或非 0 (失败),keepalived 以此为依据判断其监控的服务状态
	script "/usr/bin/killall -0 nginx &>/dev/null && exit 0 || exit 1"
	interval 3     # 指定脚本执行的间隔
	timeout 2      # 指定脚本执行的超时时间
	weight -150    # 当监控服务不存活则动态降权,确保 Backup 能接管成功
	fall 2         # 判定服务异常的检查次数
	rise 3         # 判定服务正常的检查次数
}
vrrp_instance VI_1 {
    state MASTER                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 200                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
 
	track_script {
		check_nginx
	}
       	notify_master "/etc/keepalived/notify.sh master"  # 当前节点成为主节点时触发的脚本
        notify_backup "/etc/keepalived/notify.sh backup"  # 当前节点转为备节点时触发的脚本
        notify_fault "/etc/keepalived/notify.sh fault"    # 当前节点转为 “失败” 状态时触发的脚本
}
[root@proxy01 ~]# systemctl restart keepalived
[root@proxy01 ~]# systemctl enable keepalived
[root@proxy01 ~]# ip addr |grep 192.168.40.100
    inet 192.168.40.100/32 scope global eth0
# 3.2.6 proxy02 配置 keepalived
[root@proxy02 ~]# cat /etc/keepalived/keepalived.conf 
global_defs {     
    router_id lb02                  # 当前物理设备的标识名称
}
vrrp_instance VI_1 {
    state BACKUP                    # 角色状态;
    interface eth0                  # 绑定当前虚拟路由使用的物理接口;
    virtual_router_id 50            # 当前虚拟路由标识,VRID;
    priority 100                    # 当前物理节点在虚拟路由中的优先级;
    advert_int 3                    # vrrp 通告时间间隔,默认 1s;
    #nopreempt
    authentication {
        auth_type PASS              # 密码类型,简单密码;
        auth_pass 1111              # 密码不超过 8 位字符;
    }
    
    virtual_ipaddress {
        192.168.40.100        # VIP 地址
    }
 
       	notify_master "/etc/keepalived/notify.sh master"  # 当前节点成为主节点时触发的脚本
        notify_backup "/etc/keepalived/notify.sh backup"  # 当前节点转为备节点时触发的脚本
        notify_fault "/etc/keepalived/notify.sh fault"    # 当前节点转为 “失败” 状态时触发的脚本
}
# **3.2.7 ** 抓包验证结果

1. 停止 Master 节点的 Nginx,然后抓包分析

[root@web01 conf.d]# tcpdump -i eth0 -nn host 224.0.0.18
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
18:07:36.633242 IP 192.168.40.5 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 200, authtype simple, intvl 3s, length 20
18:07:39.634496 IP 192.168.40.5 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 200, authtype simple, intvl 3s, length 20
18:07:42.635348 IP 192.168.40.5 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 200, authtype simple, intvl 3s, length 20
18:07:45.636681 IP 192.168.40.5 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 200, authtype simple, intvl 3s, length 20
18:07:48.638104 IP 192.168.40.5 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 200, authtype simple, intvl 3s, length 20
18:07:51.639280 IP 192.168.40.5 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 50, authtype simple, intvl 3s, length 20  #master 优先级降为 50
18:07:51.639458 IP 192.168.40.6 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 100, authtype simple, intvl 3s, length 20
18:07:54.640243 IP 192.168.40.6 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 100, authtype simple, intvl 3s, length 20
18:07:5

2. 恢复 Master 节点的 Nginx 服务,然后抓包分析

[root@web01 conf.d]# tcpdump -i eth0 -nn host 224.0.0.18
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
18:08:45.661885 IP 192.168.40.6 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 100, authtype simple, intvl 3s, length 20
18:08:48.662970 IP 192.168.40.6 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 100, authtype simple, intvl 3s, length 20
18:08:51.665076 IP 192.168.40.6 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 100, authtype simple, intvl 3s, length 20
18:08:54.665205 IP 192.168.40.6 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 100, authtype simple, intvl 3s, length 20
18:08:57.667054 IP 192.168.40.6 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 100, authtype simple, intvl 3s, length 20
18:09:00.668761 IP 192.168.40.6 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 100, authtype simple, intvl 3s, length 20
18:09:00.668923 IP 192.168.40.5 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 200, authtype simple, intvl 3s, length 20   #master 优先升降为 200
18:09:03.669999 IP 192.168.40.5 > 224.0.0.18: VRRPv2, Advertisement, vrid 50, prio 200, authtype simple, intvl 3s, length 20
此文章已被阅读次数:正在加载...更新于

请我喝[茶]~( ̄▽ ̄)~*

Xu Yong 微信支付

微信支付

Xu Yong 支付宝

支付宝