Nginx + Keepalived 实现双机主备高可用

前言

负载均衡的实现

  • TCP 层实现的负载均衡,例如:LVS(调度性能强悍)
  • 应用层实现的负载均衡,例如:Nginx、Haproxy、Apache、Varnish、Squid、Ribbon

Keepalived 概述

Keepalived 简介

  Keepalived 是 Linux 下一个轻量级别的高可用开源解决方案,高可用 (High Avalilability),其实两种不同的含义:广义来讲,是指整个系统的高可用行,狭义的来讲就是之主机的冗余和接管,它与 HeartBeat RoseHA 实现相同类似的功能,都可以实现服务或者网络的高可用;但是又有差别,HeartBeat 是一个专业的、功能完善的高可用软件,它提供了 HA 软件所需的基本功能,比如:心跳检测、资源接管、检测集群中的服务、在集群节点转移共享 IP 地址的所有者等等。HeartBeat 功能强大,但是部署和使用相对比较麻烦,与 HeartBeat 相比,Keepalived 主要是通过虚拟路由冗余来实现高可用功能,虽然它没有 HeartBeat 功能强大,但是 Keepalived 部署和使用非常的简单,所有配置只需要一个配置文件即可以完成。Keepalived 实现了轻量级的高可用,一般用于前端高可用,且不需要共享存储,一般常用于两个节点的高可用。而 Heartbeat 用于服务的高可用,且需要共享存储,一般用于多节点的高可用。

  Keepalived 起初是专为 LVS 设计的,用来管理并监控 LVS 集群系统中各个服务节点的状态,后来又加入了可以实现高可用的 VRRP 功能。因此,Keepalived 除了能够管理 LVS 软件外,还可以实现任意两台主机之间,例如 Master 和 Backup 主机之间的故障转移和自动切换,这个主机可以是普通的不能停机的业务服务器,也可以是 LVS 负载均衡、Nginx 反向代理这样的服务器。Keepalived 软件主要是通过 VRRP 协议实现高可用功能的,VRRP 是 Virtual Router Redundancy Protocol(虚拟路由冗余协议)的缩写,VRRP 出现的目的就是为了解决静态路由的单点故障问题的,它能保证当个别节点宕机时,整个网络可以不间断、稳定地运行。所以,Keepalived 一方面具有配置管理 LVS 的功能,同时还具有对 LVS 下面节点进行健康检查的功能,另一方面也可以实现系统网络服务的高可用功能。

VRRP 协议与工作原理

  虚拟路由冗余协议 (Virtual Router Redundancy Protocol,简称 VRRP) 是由 IETF 提出的解决局域网中配置静态网关出现单点失效现象的路由协议,1998 年已推出正式的 RFC2338 协议标准。在现实的网络环境中,主机之间的通信都是通过配置静态路由或者 (默认网关) 来完成的,而主机之间的路由器一旦发生故障,通信就会失效,因此这种通信模式当中,路由器就成了一个单点瓶颈,为了解决这个问题,就引入了 VRRP 协议,它是一种主备模式的协议,通过 VRRP 可以在网络发生故障时透明的进行设备切换而不影响主机之间的数据通信,这其中涉及到两个概念:物理路由器和虚拟路由器。

  VRRP 可以将两台或者多台物理路由器设备虚拟成一个虚拟路由,这个虚拟路由器通过虚拟 IP(一个或者多个) 对外提供服务,而在虚拟路由器内部十多个物理路由器协同工作,同一时间只有一台物理路由器对外提供服务,这台物理路由设备被成为:主路由器(Master 角色),一般情况下 Master 是由选举算法产生,它拥有对外服务的虚拟 IP,提供各种网络功能,如:ARP 请求,ICMP 数据转发等,而且其它的物理路由器不拥有对外的虚拟 IP,也不提供对外网络功能,仅仅接收 MASTER 的 VRRP 状态通告信息,这些路由器被统称为 “BACKUP 的角色”,当主路由器失败时,处于 BACKUP 角色的备份路由器将重新进行选举,产生一个新的主路由器进入 MASTER 角色,继续提供对外服务,整个切换对用户来说是完全透明的。

  每个虚拟路由器都有一个唯一的标识号,称为 VRID,一个 VRID 与一组 IP 地址构成一个虚拟路由器,在 VRRP 协议中,所有的报文都是通过 IP 多播方式发送的,而在一个虚拟路由器中,只有处于 Master 角色的路由器会一直发送 VRRP 数据包,处于 BACKUP 角色的路由器只会接收 Master 角色发送过来的报文信息,用来监控 Master 运行状态,一般不会发生 BACKUP 抢占的情况,除非它的优先级更高,而当 MASTER 不可用时,BACKUP 也就无法收到 Master 发过来的信息,于是就认定 Master 出现故障,接着多台 BAKCUP 就会进行选举,优先级最高的 BACKUP 将称为新的 MASTER,这种选举角色切换非常之快(< 1s),因而保证了服务的持续可用性。

Keepalvied 的工作原理

  Keepalived 通过 VRRP 实现高可用,作为一个高性能集群软件,它还能实现对集群中服务器运行状态的监控以及故障隔离。Keepalived 工作在 TCP/IP 参考模型的 三层、四层、五层,也就是分别为:网络层,传输层和应用层,根据 TCP/IP 参数模型隔层所能实现的功能,Keepalived 运行机制如下:

  • 在网络层: 运行 4 个重要的协议:互联网络 IP 协议,互联网络可控制报文协议 ICMP、地址转换协议 ARP、反向地址转换协议 RARP,Keepalived 在网络层采用最常见的工作方式是通过 ICMP 协议向服务器集群中的每一个节点发送一个 ICMP 数据包 (有点类似与 Ping 的功能), 如果某个节点没有返回响应数据包,那么认为该节点发生了故障,Keepalived 将报告这个节点失效,并从服务器集群中剔除故障节点;

  • 在传输层: 提供了两个主要的协议:传输控制协议 TCP 和用户数据协议 UDP,传输控制协议 TCP 可以提供可靠的数据输出服务、 IP 地址和端口,代表 TCP 的一个连接端,要获得 TCP 服务,需要在发送机的一个端口和接收机的一个端口上建立连接,而 Keepalived 在传输层里利用了 TCP 协议的端口连接和扫描技术来判断集群节点的端口是否正常,比如对于常见的 WEB 服务器 80 端口,或者 SSH 服务 22 端口,Keepalived 一旦在传输层探测到这些端口号没有数据响应和数据返回,就认为这些端口发生异常,然后强制将这些端口所对应的节点从服务器集群中剔除掉;

  • 在应用层:可以运行 FTP,TELNET,SMTP,DNS 等各种不同类型的高层协议,Keepalived 的运行方式也更加全面化和复杂化,用户可以通过自定义 Keepalived 工作方式,例如:可以通过编写程序或者脚本来运行 Keepalived,而 Keepalived 将根据用户的设定参数检测各种程序或者服务是否允许正常,如果 Keepalived 的检测结果和用户设定的不一致时,Keepalived 将把对应的服务器从服务器集群中剔除;

  Keepalived 高可用服务对之间的故障切换转移,是通过 VRRP 来实现的。在 Keepalived 服务工作时,主 Master 节点会不断地向备节点发送(多播的方式)心跳消息,用来告诉备 Backup 节点自己还活着。当主节点发生故障时,就无法发送心跳的消息了,备节点也因此无法继续检测到来自主节点的心跳了。于是就会调用自身的接管程序,接管主节点的 IP 资源和服务。当主节点恢复时,备节点又会释放主节点故障时自身接管的 IP 资源和服务,恢复到原来的备用角色。

Keepalived 的体系结构

nginx-keepalived-1

简单模块介绍:

  • 1)SchedulerI/OMultiplexer 是一个 I/O 复用分发调度器,它负载安排 Keepalived 所有内部的任务请求
  • 2)Memory Mngt 是一个内存管理机制,这个框架提供了访问内存的一些通用方法
  • 3)Control Plane 是 Keepalived 的控制版面,可以实现对配置文件编译和解析
  • 4)Core componets 这部分主要包含了 5 个部分
    • a)看门狗 (Watchdog) :是计算机可靠领域中极为简单又非常有效的检测工具,Keepalived 正是通过它监控 Checkers 和 VRRP 进程的
    • b)检查者 (Checkers) : 是 Keepalived 最基础、最主要的功能,可以实现对服务器运行状态检测和故障隔离
    • c)VRRP 模块 (VRRP Stack) : 是 Keepalived 引用 VRRP 功能,可以实现 HA 集群中失败切换功能,负责负载均衡器之间的失败切换 FailOver
    • d)IPVS 模块 (IPVS wrapper) : 是 IPVS 功能的一个实现,IPVSwarrper 模块将可以设置好的 IPVS 规则发送的内核空间并且提供给 IPVS 模块,最终实现 IPVS 模块的负载功能
    • e)VIP 切换 (Netlink Reflector) :用来实现高可用集群 Failover 时虚拟 IP (VIP) 的设置和切换

由上图可知,两个子进程都被系统 WatchDog 看管,healthchecker 子进程实现检查各自服务器的健康程度,例如 HTTP、LVS 等等,如果 healthchecker 子进程检查到 MASTER 上服务不可用,就会通知本机上的兄弟 VRRP 子进程,让它删除通告,并且去掉虚拟 IP,转换为 BACKUP 状态

Nginx + Keepalived 搭建高可用集群

部署架构图

本文采用的是 Nginx + Keepalived 双机主备架构(主备模式),即使用一个 VIP 地址,Nginx 使用 2 台机器,一台做主节点(Master),一台做备节点(Backup),但同时只有一台机器工作,另一台备用机器在主机器不出现故障的时候,处于空闲状态,仅仅用于灾备。

nginx-keepalived-2

服务器规划

角色 IP 软件运行环境
Master 节点 192.168.1.163CentOS 7、Nginx、KeepalivedVbox 虚拟机
Backup 节点 192.168.1.109CentOS 7、Nginx、KeepalivedVBox 虚拟机

准备工作

在 Master 与 Backup 节点上都关闭防火墙

1
2
3
4
5
# 临时关闭
# systemctl stop firewalld

# 永久关闭
# systemctl disable firewalld

在 Master 与 Backup 节点上都关闭 SeLinux

1
2
3
4
5
# 临时关闭
# setenforce 0

# 永久关闭
# sed -i 's/enforcing/disabled/' /etc/selinux/config

软件安装

在 Master 与 Backup 节点上都安装好 Nginx 和 Keepalived,建议使用编译安装的方式。值得一提的是,在生产环境中,Nginx 和 Keepalived 可以分别安装在不同的物理机器上。

Nginx 编译安装

1
2
3
4
5
# 创建nginx用户组
# groupadd nginx

# 创建nginx用户(不允许远程登录)
# useradd -g nginx nginx -s /bin/false
1
2
# 安装依赖
# yum install -y gcc gdb strace gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs patch e2fsprogs-devel krb5-devel libidn libidn-devel openldap-devel nss_ldap openldap-clients openldap-servers libevent-devel libevent uuid-devel uuid openssl openssl-devel pcre pcre-devel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 下载
# wget http://nginx.org/download/nginx-1.17.1.tar.gz

# 解压
# tar -xvf nginx-1.17.1.tar.gz

# 进入解压目录
# cd nginx-1.17.1

# 配置
./configure \
--user=nginx \
--group=nginx \
--prefix=/usr/local/nginx \
--with-pcre \
--with-http_v2_module \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module

# 编译安装
# make && make install

# 后台启动Nginx
# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

# 验证访问Nginx
# curl -X GET 127.0.0.1

# 查看Nginx的运行状态
# ps -aux|grep nginx

Keepalived 编译安装

1
2
# 安装依赖
# yum -y install curl gcc libnl3-devel net-snmp-devel libnl libnl-devel libnfnetlink-devel openssl openssl-devel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
## Keepalived官网下载地址:https://www.keepalived.org/download.html

# 下载
# wget http://keepalived.org/software/keepalived-2.0.18.tar.gz

# 解压
# tar -xvf keepalived-2.0.18.tar.gz

# 进入解压目录
# cd keepalived-2.0.18

# 配置
# ./configure --prefix=/usr/local/keepalived

# 确保 "./configure" 命令执行完后,输出的以下支持项都为Yes
fwmark socket support : Yes
Use VRRP Framework : Yes
Use VRRP VMAC : Yes
Use VRRP authentication : Yes
With ip rules/routes : Yes

# 编译安装
# make && make install

# 创建存放Keepalived配置文件的目录
# mkdir -p /etc/keepalived

# 拷贝Keepalived默认的配置文件
# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived

# 设置Keepalived开机自启动
# systemctl enable keepalived.service

Keepalived 核心配置

在 Makster 和 Backup 节点分别创建检查 Nginx 健康状态的脚本 /etc/keepalived/nginx_check.sh

1
2
3
4
5
6
7
8
9
#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
sleep 2
if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
killall keepalived
fi
fi
1
2
# 脚本授权执行
# chmod +x /etc/keepalived/nginx_check.sh

Keepalived 是服务器级别的,只监控服务器,Nginx 宕机了,是没有办法接管的。比如,这里是用 Nginx 做负载均衡分发请求的数据包的,如果 Master 节点的 Keepalived 服务正常运行,而 Nginx 运行异常,那么将会出现 Nginx 负载均衡服务失灵,无法切换到 Nginx 备用的负载均衡器上,后端的 Web 服务器无法收到请求。所以,应该要检测 Nginx 的服务是否正常运行,如果不是正常运行,首先尝试启动 Nginx 的服务;若 Nginx 重启失败,就应该关闭掉该节点上的 Keepalived 的服务,这样才能自动切换到 Keepalived 的 Backup 节点上。


Keepalived 的配置示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
global_defs {
notification_email {
# acassen@firewall.loc # 指定收件人
}
# notification_email_from Alexandre.Cassen@firewall.loc # 指定发件人
# smtp_server 192.168.200.1 # SMTP服务器地址
# smtp_connect_timeout 30 # SMTP服务器连接超时时间

router_id LVS_1 # 必填,标识本节点的字符串,在不同的Keepalived服务器里唯一,通常为hostname,但不一定非得是hostname,故障发生时,发邮件通知时会用到
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}

vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh" # 检测服务健康状态的Shell脚本
interval 2 # 每隔多长时间探测一次
weight -20 # 如果条件成立的话,则权重-20
}

vrrp_instance VI_1 { # 定义虚拟路由,VI_1为虚拟路由的标示符,可以是自定义名称,允许定义多个虚拟路由
state MASTER # 必填,可以是MASTER或BACKUP,不过当其他节点Keepalived启动时会将Priority比较大的节点选举为MASTER
interface enp0s3 # 必填,节点固有IP(非VIP)的网卡,用来发VRRP包做心跳检测
mcast_src_ip 192.168.1.109 # 本机的IP
virtual_router_id 51 # 必填,虚拟路由ID,取值在0-255之间,用来区分多个Instance的VRRP组播,同一网段内ID不能重复,主备机器的该值必须为一样
priority 100 # 必填,用来选举Master的,要成为Master那么这个选项的值最好高于其他机器50个点,该项取值范围是1-255(在此范围之外会被识别成默认值100)
advert_int 1 # 必填,检查间隔默认为1秒,即1秒进行一次Master选举(可以认为是健康查检时间间隔)
authentication { # 必填,认证区域,认证类型有PASS和HA(IPSEC),推荐使用PASS(密码只识别前8位),主备配置必须一样
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.186/24 # 必填,虚拟VIP地址,建议后缀加上"/24",允许有多个
}
track_script { # 检测服务健康状态的Shell脚本
chk_nginx
}
}

在 Makster 节点创建 Keepalived 的主配置文件 /etc/keepalived/keepalived.conf,配置文件的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
global_defs {
notification_email {
# acassen@firewall.loc
}
# notification_email_from Alexandre.Cassen@firewall.loc
# smtp_server 192.168.200.1
# smtp_connect_timeout 30

router_id LVS_1
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}

vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2
weight -20
}

vrrp_instance VI_1 {
state MASTER
interface enp0s3
mcast_src_ip 192.168.1.163
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.186/24
}
track_script {
chk_nginx
}
}

在 Backup 节点创建 Keepalived 的主配置文件 /etc/keepalived/keepalived.conf,配置文件的内容如下,与 Master 节点的最大参数区别是:router_id LVS_2state BACKUPmcast_src_ip 192.168.1.109

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
global_defs {
notification_email {
# acassen@firewall.loc
}
# notification_email_from Alexandre.Cassen@firewall.loc
# smtp_server 192.168.200.1
# smtp_connect_timeout 30

router_id LVS_2
vrrp_skip_check_adv_addr
vrrp_garp_interval 0
vrrp_gna_interval 0
}

vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2
weight -20
}

vrrp_instance VI_1 {
state BACKUP
interface enp0s3
mcast_src_ip 192.168.1.109
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.186/24
}
track_script{
chk_nginx
}
}

分别在 Master 节点和 Backup 节点启动 Keepalived 的服务

1
2
3
4
5
6
7
8
9
# 启动Keepalived
# service keepalived start

# 查看运行状态
# service keepalived status

# 查看启动的日志信息
# more /var/log/messages
# journalctl -u keepalived

测试虚拟 IP

Master 节点查看虚拟 IP

在 Master 节点执行以下命令,查看节点的 IP 状态

1
# ip addr

在 Master 节点可以看到已经生成了虚拟 IP 192.168.1.186

nginx-keepalived-3

Backup 节点查看虚拟 IP

在 Backup 节点执行以下命令,查看节点的 IP 状态

1
# ip addr

在 Backup 节点默认不会看到生成的虚拟 IP,如果生成那就是 Keepalived 的配置文件出现了错误,即备节点和主节点争用 IP 资源,这个现象叫做 脑裂

nginx-keepalived-4

使用虚拟 IP 访问 Nginx

分别在 Master 节点和 Backup 节点上,验证是否可通过虚拟 IP 访问本地的 Nginx 服务

1
2
3
4
5
# 确保可以Ping得通虚拟IP
# ping 192.168.1.186

# 访问Nginx
# curl -X GET 192.168.1.186

值得一提的是,建议额外在宿主机上测试是否可以访问 VIP

主备服务器高可用切换

关闭 Master 节点的 Keepalived 服务

1
# service keepalived stop

查看 Backup 节点是否会生成虚拟 IP 192.168.1.186

nginx-keepalived-5

重新启动 Master 的 Keepalived 服务,然后查看 Master 和 Backup 的虚拟 IP,此时主节点应该会将虚拟 IP 抢夺回来

1
# service keepalived restar

nginx-keepalived-6

nginx-keepalived-7

Keepalived 脑裂(主备节点均有 VIP)

脑裂(split-brain)指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏。对于无状态服务的 HA,无所谓脑裂不脑裂;但对有状态服务(比如 MySQL)的 HA,必须要严格防止脑裂。

脑裂原因

一般来说脑裂问题有以下这几种原因:

  • 高可用服务器上开启了 iptables 防火墙,阻止了心跳消息传输
  • 高可用服务器上心跳网卡地址等信息配置不正确,导致发送心跳失败
  • 其他服务配置不当的原因,如心跳方式不同,心跳广播冲突,软件 Bug 等
  • 高可用服务器对之间心跳线链路发生故障,导致无法正常通信,例如:心跳线坏了(包括断了或者老化)、网卡及相关驱动损坏、IP 配置及冲突问题(网卡直连)、心跳线之间的设备故障(网卡及交换机)、仲裁的机器出现问题(采用仲裁的方案)

值得一提的是,Keepalived 配置里的同一个 VRRP 实例,如果 virtual_router_id 参数在主备节点上的配置不一致,也会导致出现脑裂现象。

脑裂方案

在实际生产环境中,可以从以下方面防止脑裂:

  • 同时使用串行电缆和以太网电缆连接、同时使用两条心跳线路,这样一条线路断了,另外一条还是好的,依然能传送心跳消息
  • 当检查脑裂时强行关闭一个心跳节点(这个功能需要特殊设备支持,如 stonith、fence),目的是让备节点接收不到心跳消息,可以通过单独的线路发送关机命令关闭主节点的电源
  • 做好对脑裂的监控报警

解决常见方案:

  • 如果开启了防火墙,一定要让心跳消息通过,一般通过允许 IP 段的形式解决
  • 可以拉一条以太网网线或者串口线作为主备节点心跳线路的冗余
  • 开发检测程序,通过监控软件检测脑裂

脑裂报警脚本

监控报警思路,正常情况下 Keepalived 的 VIP 是挂载在 Master 节点上的,如果在 Backup 节点发现了 VIP,同时还可以 Ping 得通 Master 节点,就触发脑裂报警。这种监控思路是假设在 Keepalived 服务自身不会宕机的基础上的,若 Master 节点上的 Keepalived 服务宕机了,VIP 会正常挂载到 Backup 节点上,同时还是可以 Ping 得通 Master 节点,这种极端情况下就会错误触发脑裂警报。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash

# 检查脑裂的脚本,在Backup节点上进行部署
VIP=192.168.1.186
MASTER_IP=192.168.1.163

while true
do
ping -c 2 -W 3 $MASTER_IP &>/dev/null
if [ $? -eq 0 -a `ip add|grep "$VIP"|wc -l` -eq 1 ];then
echo "ha is brain."
else
echo "ha is ok"
fi
sleep 5
done

Nginx + Keepalived 高可用架构方案

双机主备方案

nginx-keepalived-model

双机主备方案(又叫 双机热备)就是上文介绍过的,使用一个 VIP 地址,前端使用 2 台机器,一台做主节点(Master),一台做备节点(Backup),但同时只有一台机器工作。这方案的缺点很明显,另一台备用机器在主机器不出现故障的时候,永远处于浪费状态,仅仅用于灾备,平时都是空闲着的。

双主热备方案

nginx-keepalived-model-2

双主热备方案 弥补了双机主备方案的缺点,使用 2 个 VIP 地址,前端使用 2 台机器,彼此互为主备,同时有两台机器工作。用户访问之后,DNS 负载均衡(轮询)选择访问哪个 VIP,当其中一台机器出现故障,两台机器的请求会转移到同一台机器负载。

Keepalived 常见使用问题

Master 节点无法访问虚拟 IP

Master 节点里的 Keepalived 服务配置好 VIP 后,通过 ip addr 可以看到 VIP 已经顺利挂载,但是在 Master 节点内部无法 Ping 通。原因是 keepalived.conf 文件中默认配置了 vrrp_strict,需要把它注释掉,重启 Keepalived 的服务后即可以 Ping 得通。vrrp_strict 参数表示严格遵守 VRRP 协议,下列情况将会阻止 Keepalived 的虚拟 IP 功能:

  • 1)单播邻居
  • 2)没有 VIP 地址
  • 3)在 VRRP 版本 2 中有 IPv6 地址

Backup 节点无法访问虚拟 IP

虚拟 IP 的网段要和 Real Server 真实 IP 的网段地址一致,比如 Master 节点与 Backup 节点的 IP 网段为 192.168.171,那么虚拟 IP 必须是 192.168.171.*,否则 Backup 节点无法访问虚拟 IP。

Nginx 服务使用非默认的 80 端口

若 Nginx 服务使用非默认的 80 端口,那么在 Keepalived 的配置文件 keepalived.conf 里,只需要正常配置 virtual_ipaddress 参数即可,不需要关心 Nginx 具体使用的是哪个端口,因为默认可以通过 http://vip:port 的地址格式访问 Nginx。

Master 节点与 Backup 节点同时生成了虚拟 IP

关闭系统防火墙,让 Master 节点和 Backup 节点可以互相通信(心跳检测),否则会导致主备节点都生成了两个 VIP(脑裂现象)。也可以配置主备节点之间的防火墙协议(如下),放行其他需要通信的 IP 即可:

1
2
3
4
5
6
7
8
# 放行VRRP协议
# firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --protocol vrrp -j ACCEPT

# 或者
# firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface em1 --destination 192.168.1.163 --protocol vrrp -j ACCEPT

# 重载配置生效
# firewall-cmd --reload

商业云服务器对 Keepalived 的支持

以阿里云服务器举例,可以使用 HAVIP + VPC(Virtual Private Cloud,虚拟私有云) 来实现 Keepalived,但是普通的 ECS 是不适用的,要求必须使用 VPC 类型的 ECS,而且虚拟 IP 需要另外申请(不支持自建 VIP)。阿里云目前不支持自建 LVS 高可用负载均衡,但有现成的商业产品–负载均衡 SLB 可以选择。值得一提的是,云服务器 ECS 不支持组播和广播,这点需要注意一下。

参考博客