Keepalived-了解

参考 Archwiki

介绍

Keepalived 使用 VRRP 协议来实现故障转移. 其本身不具备负载均衡的功能, 需要依赖运行在 Linux 内核的 LVS.

也就是说, Keepalived 由两部分组成:

  • VRRP
  • LVS

注意每一台主机都需要配置好 Keepalived 才能实现功能.

(注意这里的后端之后两台服务器, 而不是三台, 前面的哪个不是真实存在的主机)

相关概念

Virtual Router Redundancy Protocol (VRRP)

VRRP 是一个网络协议, 用于实现在多个路由器间的故障转移.

三种状态

其定义了三种状态机:

  • Initialize, 表明不可用, 此时设备不对 VRRP 通告报文做处理
  • Master, 承担虚拟路由设备的所有转发工作, 并定期向整个虚拟组发送 VRRP 通告报文
  • Backup, 不承担路由设备的转发工作, 定期接受 Master 设备的 VRRP 通告报文, 判断 Master 的工作状态是否正常

设备优先级

每一台设备都会设置一个优先级, 值越大, 在选举时会成为 Master 设备.

工作原理

  1. 确定虚拟路由器组 (VRID): 多个路由器 (或交换机) 被组织成一个虚拟路由器组. 每个虚拟路由器组都有一个唯一的标识符, 称为虚拟路由器 ID (Virtual Router ID, 简称 VRID).

  2. 确定主备关系: 在每个虚拟路由器组中, 通过选举产生一个主路由器和一个或多个备用路由器. 主路由器负责处理流量, 而备用路由器处于待命状态.

  3. 分配虚拟 IP 地址: 虚拟路由器组中的主路由器分配一个虚拟 IP 地址, 作为默认网关提供给客户端. 客户端将其流量发送到虚拟 IP 地址.

  4. 心跳检测: 主路由器和备用路由器之间定期发送心跳消息, 以检测主路由器的可用性. 心跳消息通常使用组播(multicast) 或广播 (roadcast) 方式发送.

  5. 选举过程: 主备选举是通过比较优先级 (Priority) 来确定的. 每个路由器都有一个优先级值, 优先级高的成为主路由器. 如果主路由器不可用, 备用路由器中优先级最高的将接管成为新的主路由器.

  6. 路由器切换: 当主路由器失效或不可达时, 备用路由器中的一个将接管虚拟 IP 地址, 并成为新的主路由器. 这个过程称为故障切换 (Failover), 它确保网络流量可以继续被路由和传递.

  7. 主路由器恢复: 如果主路由器恢复, 它将尝试重新接管虚拟 IP 地址, 并恢复为主路由器. 备用路由器将检测到主路由器的恢复, 并将虚拟 IP 地址转移回主路由器. 这个过程称为故障恢复 (Failback)

详细工作过程:

Gratuitous ARP

GARP 是一种网络协议, 用于通知网络中的其他设备更新其 ARP 缓存, 以便更快地将流量转发到新的虚拟 IP 地址.

Gratuitous Neighbor Advertisement

GNA 类似于 GARP, 用于通知其他设备更新其邻居缓存.

Keepalived 工作原理

  1. 配置 VRRP 实例: 在每台服务器上配置 Keepalived, 并定义一个或多个 VRRP 实例 (不是路由器组, 路由器组有 global 中的 router_id 指定). 每个 VRRP 实例都有一个唯一的虚拟路由器 ID (Virtual Router ID), 用于区分不同的实例.

  2. 选举主服务器: 在 VRRP 实例中, 服务器将根据优先级 (Priority) 进行选举, 以确定主服务器. 具有最高优先级的服务器将成为主服务器, 负责处理流量.

  3. 分配虚拟 IP 地址: 主服务器将分配一个虚拟 IP 地址 (Virtual IP Address), 并将该地址绑定到网络接口上. 客户端将通过该虚拟 IP 地址访问服务.

  4. 心跳检测: 主服务器和备份服务器之间进行心跳检测, 以确定主服务器的可用性. 主服务器定期发送心跳消息, 并备份服务器接收并确认这些消息. 如果主服务器不再发送心跳消息, 备份服务器将检测到主服务器的故障.

  5. 备份服务器接管: 一旦备份服务器检测到主服务器故障, 它将成为新的主服务器, 并接管虚拟 IP 地址. 这个过程称为故障切换 (Failover), 它确保服务的连续性, 并将流量重新路由到新的主服务器.

  6. 主服务器恢复:如果主服务器恢复, 它将尝试重新接管虚拟 IP 地址.备份服务器将检测到主服务器的恢复, 并将虚拟 IP 地址转移回主服务器. 这个过程称为故障恢复 (Failback).

  7. 配置同步: Keepalived 还提供了配置同步的功能, 即将配置更改从主服务器同步到备份服务器. 这确保在故障切换后, 新的主服务器具有相同的配置.

安装

Archlinux 下安装:

1
sudo pacman -S keepalived

CentOS 系列下:

1
dnf install -y keepalived

配置

配置文件位于:

1
/etc/keepalived/keepalived.conf

全局配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
global_defs {
notification_email { # 设置管理员邮箱列表, 接收警告邮箱
acassen@firewall.loc
failover@firewall.loc
}
notification_email_from sysadmin@firewall.loc # 设置发送邮箱
smtp_server 192.168.200.1 # 设置邮箱服务器IP
smtp_connect_timeout 300 # 邮箱服务器连接的超时时间
router_id LVS_DEVEL # 物理节点的标识符, 一般使用主机名
vrrp_skip_check_adv_addr # 检查广播地址是否与虚拟IP地址不匹配
vrrp_strict # 启用严格模式处理VRRP包
vrrp_garp_interval 0 # 定义发送GARP包的时间间隔, 设置成0禁用
vrrp_gna_interval 0 # 定义发送GNA包的时间间隔, 设置成0禁用
}

VRRP 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vrrp_instance VI_1 {      # VI_1为自定义标识符, 用于区分不同的VRRP实例
state MASTER # 指定实例的初始状态
interface eth0 # 实例绑定的接口,用于发送VRRP包
virtual_router_id 51 # 指定VRRP实例ID
mcast_src_ip 192.168.122.10 # 指定VRRP组播的源IP
priority 100 # 指定优先级
advert_int 1 # 通告间隔为1s
authentication {
auth_type PASS # 设置认证方式,这里为密码认证
auth_pass 123456 # 设置认证密码
}
virtual_ipaddress { # 配置VIP
192.168.200.16
}
}

vrrp_script 和 track_script 设置

LVS 配置

这里设置负载均衡的几台后端服务器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
virtual_server 192.168.200.100 443 {  # 指定监听的虚拟服务器IP和端口
delay_loop 6 # 健康检查间隔时间
lb_algo rr # LVS的调度算法
lb_kind NAT # LVS模式
persistence_timeout 50 # 持久化时间, 持久化用于确保客户端在多次请求中被路由到同一台后端服务器
protocol TCP # 表明虚拟服务器用什么协议来传入连接
real_server 192.168.201.100 443 { # 配置后端的real server的IP和端口
weight 1 # 负载均衡的权重
SSL_GET { # 设置健康检查的方式
url {
path /
digest 640205b7b0fc66c1ea91c463fac6334d
}
connect_timeout # 连接超时时间
retry 3 # 重试次数
delay_before_retry # 重试之间的间隔
}
}
}

注意这里配置成 NAT, 需要开启内核参数 net.ipv4.ip_forward:

1
sysctl -w net.ipv4.ip_forward=1

若配置成 DR, 则需要开启:

1
2
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=1

HTTP_CHECK 和 SSL_GET 健康检查设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HTTP_GET | SSL_GET {
url {
path <string> # 指定要检查的URL路径
digest <string> # 用上述路径进行哈希计算生成
status_code <INI> # 指定状态码
}
nb_get_retry <INT> # 用GET尝试的次数
delay_before_retry <INT> # 用GET尝试的间隔
connect_ip <IP ADDRESS> # 连接的ip, 默认为real server的ip地址
connect_port <PORT> # 连接的端口, 默认是real server的端口
bindto <IP ADDRESS> # 发起连接的接口的地址
bind_port <PORT> # 发起连接的源端口
connect_timeout <INT> # 连接超时时间, 默认是5s
fwmark <INTEGER> # 使用fwmark对搜有出去的检查数据包进行标记
warmup <INT> # 指定随即延迟
}

可以用:

1
genhash -s 172.17.100.1 -p 80 -u /index

来生成 digest.

TCP_CHECK 健康检查设置

1
2
3
4
5
6
7
8
9
10
11
TCP_CHECK {
connect_ip <IP ADDRESS> # 连接的ip, 默认为real server的ip地址
connect_port <PORT> # 连接的端口, 默认是real server的端口
bindto <IP ADDRESS> # 发起连接的接口的地址
bind_port <PORT> # 发起连接的源端口
connect_timeout <INT> # 连接超时时间, 默认是5s
fwmark <INTEGER> # 使用fwmark对搜有出去的检查数据包进行标记
warmup <INT> # 指定随即延迟
retry <INT> # 重试次数,默认1次
delay_before_retry <INT> # 用重试的间隔
}

MISC_CHECK 健康检查设置

1
2
3
4
5
6
7
MISC_CHECK {
misc_path <string> # 外部脚本地址
misc_timeout <INT> # 脚本执行超时时间
user USERNAME [GROUPNAME] # 指定运行脚本的用户和组, 若没指定GROUPNAME, 则同USERNAME
misc_dynamic # 根据退出状态吗动态调整权重
warmup <INT> # 指定随即延迟
}

其退出码有:

  • 0, 健康检查成功, 权重不变
  • 1, 健康检查失败
  • 2-255, 健康检查成功, 权重设置为推出码 -2

Keepalived 支持的健康检查

  • TCT_CHECK, 运行在 OSI 第四层 (传输层), Keepalived 向后端服务器发送 TCP 连接请求, 如果收不到响应或超时, 则认为该服务器不可用, 从服务器池中移除
  • HTTP_GET, 运行在 OSI 第五层 (会话层), 向指定 URL 执行 http 请求, 将得到的结果用 md5 加密并与指定的 md5 值比较看是否匹配, 不匹配则从服务器池中移除. (也可以通过指定 http 返回码来判断)
  • SSL_GET, 同 HTTP_GET, 只不过使用 SSL 连接
  • MISC_CHECK, 使用脚本对服务器状态进行检查, 脚本的返回值为 0 表示状态正常.

Keepalived-了解
http://example.com/2023/10/11/Keepalived-了解/
作者
Jie
发布于
2023年10月11日
许可协议