LVS以及KeepAlived实现故障转移<未完成>
发布于2025-03-23 10:59:07,更新于2025-04-01 22:59:22,标签:devops 文章会持续修订,转载请注明来源地址:https://meethigher.top/blog我有多个 Backend,这些 Backend 通过 Nginx 作为 LoadBalancer。当 Nginx 节点出现故障时,整个系统的流量无法正确转发,导致服务不可用。为了确保系统的高可用性,可以引入一个备份 Nginx 节点,并使用 keepalived
来实现故障转移和流量切换。本文目的是学习 keepalived,顺便将其涉及的基础知识也进行了解。
本文按如下顺序,层层递进展开。
- IP 与子网掩码
- 网络基础
- LVS
- keepalived
针对 IP 与子网掩码的基础,此处不做记录。可以参考 IP 与 CentOS7 防火墙基础
一、网络基础
1.1 网络分层模型
计算机网络中,有三种常见的网络分层模型
- OSI 七层模型
- 用途:理论标准
- TCP/IP 四层模型
- 用途:实践标准
- 五层模型
- 用途:教学标准
第一层从表格最下面开始,逐往上递增。
理解 | OSI 七层模型 | TCP/IP 四层模型 | 五层模型 |
---|---|---|---|
看到的内容:比如 HTTP 接口返回的数据内容 | 应用层 | 应用层 | 应用层 |
数据的翻译官:加密、解码、压缩 | 表示层 | ||
建立“会话”的门卫:登录、保持连接 | 会话层 | ||
把内容切好、编号,保证顺序送达 | 运输层 | 运输层 | 运输层 |
找路:确定从哪条线路送到对方 | 网络层 | 网络层 | 网络层 |
把数据帧传到邻居,找 MAC 地址 | 数据链路层 | 网络接口层 | 数据链路层 |
电、光、无线信号本身 | 物理层 | 物理层 |
交换机:用于局域网内部的设备互联,让同一网段内的主机能够通信。处于数据链路层。
路由器:连接不同子网,让不同网络之间的数据包能够互通。处于网络层。
1.2 路由器与网关
1.2.1 网关分类
路由器(Router) 是一个设备,用来连接不同子网,并根据 IP 地址进行数据包转发,工作在网络层。
网关(Gateway) 是一个概念,用来连接不同协议或网络,它不仅仅负责转发数据包,还能进行协议转换。可以工作在多个 OSI 层。常用网关如下
- 网络通信网关
- 代表:路由器(OSI 第三层网络层)。
- 解释:路由器作为网关,用来连接不同子网,这包括局域网(LAN)和广域网(WAN)。
- 负载均衡网关
- 代表:负载均衡器,如 Nginx(OSI 第七层应用层)、LVS(OSI 第四层运输层)。
- 解释:负载均衡器作为网关,将流量转发出去。
1.2.2 网络通信网关的触发时机
如果当前机器访问的目标 IP 在本地子网内,数据包就会直接传输,不经过默认网关。
如果当前机器访问的目标 IP 不在本地子网内,数据包就会发送给默认网关,由网关转发到其他子网。
将目标 IP 与子网掩码的二进制进行 AND 运算,如果当前 IP 与子网掩码的运算结果一致,那么就说明在同一个子网内。
就像生活中的送东西,如果近,就自己上门送;如果远,就甩给快递站。
1.3 两子网进行组网通信
1.3.1 环境安装
将以下环境在 Windows11 上按顺序进行安装。相关的内容在 B 站有很多免费的课程。参考
1.3.2 实践
“我要模拟两个子网进行组网,使用 WIFI 即可实现,还有必要使用交换机吗?”
还是有必要的。简单对照两者的优劣,如下。
对比点 | Wi-Fi | 有线交换机 |
---|---|---|
灵活性 | 无线连接,设备自由移动,适合动态环境 | 有线固定,设备受限于网线长度与端口位置 |
带宽共享 | 所有设备共享局域网带宽。你在下载东西我打游戏就会卡 | 每个物理接口独立带宽,互不影响 |
延迟表现 | 延迟较高,易受干扰与墙壁影响 | 延迟低,稳定性强,适合高要求应用 |
信号范围 | 信号覆盖有限,可能存在死角 | 信号稳定,不受距离影响 |
成本 | 初期投入低 | 初期投入较高,需要交换机和网线 |
使用场景 | 家庭、移动设备多、无缝漫游 | 办公室、企业、固定设备多,需高速稳定网络 |
我通过 eNSP 这个网络拓扑模拟器,使用交换机和路由器,两者组合的方式,进行两个子网 10.0.0.0/8
和 192.168.1.0/24
的组网。
如果你安装了其他的虚拟环境,比如 VMware、Docker、WSL、Qemu 之类的,底层虚拟化冲突,可能会出现启动设备失败的问题。
配置拓扑如下
源码示例可以访问 meethigher/ensp-repo: ensp examples 下载 net-test
。
下载用 ensp 打开后,针对路由器进行配置。
1 | The device is running! |
用 PC3 去访问 PC1,可以连通,证明组网成功!
1.3.3 理解原理
拓扑图如下,Server1
开启 HTTP 80 端口。
1.) 问题 1:通过 Client1
这台机器请求 Server1
的 80 端口,能否连通?
答:能。由于 Server1
不在 Client1
所处的 10.0.0.0/8
子网内,因此 Client1
会将数据包发送给网关 10.0.0.1
,即路由器 1
。路由器 1
有两个接口,分别处于两个子网 10.0.0.0/8
和 192.168.1.0/24
,而 Server1
的 IP 属于子网 192.168.1.0/24
,因此路由器 1
会将数据包发送给该子网对应的接口,最终到达 Server1
。之后路由器 1
再次中转,将响应内容写回。
以上图为例,主机 1 向主机 2 发起请求,整体流程如下:
- 主机 1 的应用进程 AP1 向主机 2 的应用进程 AP2 传输数据。AP1 将数据交给本机的第 5 层(应用层)。
- 第 5 层(应用层)为数据添加必要的头信息(H5),如 HTTP 头部。
- 第 4 层(运输层)为数据添加
源/目端口
头部(H4)。 - 第 3 层(网络层)为数据添加
源/目IP
头部(H3)。 - 第 2 层(数据链路层)在数据首部加入
源/目 MAC
(H2)、尾部加入校验和
(T2)。 - 第 1 层(物理层)传输比特流时,不再添加控制信息。注意,比特流从首部开始传输。
- 当比特流离开主机 1,通过网络的物理传输介质到达路由器时:
- 路由器从第 1 层开始,逐层向上拆包,剥去控制信息后,将剩余数据传递给上一层。
- 到达第 3 层(网络层)时,路由器根据首部中的目的地址查找路由表,确定转发接口,然后将数据下传至第 2 层,加入新的首部和尾部,再传递至第 1 层,最终通过物理介质发送每一个比特。
- 比特流从路由器离开,抵达目的主机 2 时,数据依照相同流程从第 1 层开始逐层拆包,最终到达第 5 层。
- 最终,AP1 发送的数据交给主机 2 的应用进程 AP2。
ARP请求就是一种用于在局域网中查询MAC地址的广播请求。作用阶段是数据链路层。
如果源主机知道目标主机的IP地址,但不确定其MAC地址,它会广播一个ARP请求包。该请求包含了目标IP地址,并询问“谁拥有这个IP地址?请回复你的MAC地址”。
参考
2.) 问题 2:Client1
发起请求后,如果能连通,那么 Server1
收到的请求源 IP 是什么?
答:视情况而定。如果路由器启用 NAT(Network Address Translation),那么 Server1
收到的请求源 IP 为 192.168.1.1
;如果未启用 NAT,则为 10.0.0.10
。
像我们 WIFI 连接的路由器,默认就是开启 NAT 的。
最直接的体现是,所有连接该 WIFI 的,对外出去的互联网 IP 都是同一个。
二、LVS
2.1 背景
LVS(Linux Virtual Server) 是由中国工程师章文嵩博士于 1998 年发起并开发的开源负载均衡项目。1999 年,LVS 代码被集成到 Linux 内核 2.4 版本中,成为 Linux 生态的重要组成部分。
随着互联网流量的快速增长,传统单台服务器的性能已无法满足大规模服务的需求。章文嵩博士提出通过集群技术将多台物理服务器组合成一个“虚拟服务器”,对外表现为单一入口,从而提升服务能力和可靠性。
2.2 工作模式
LVS(Linux Virtual Server)是一个基于 Linux 内核的负载均衡解决方案,是 Linux 内核层面的负载均衡实现,核心是 IPVS 模块(IP Virtual Server)。
ipvsadm 是 LVS 的用户空间管理工具,它用来配置和查看 LVS(IPVS)的运行状态。安装 ipvsadm
1 | yum -y install ipvsadm |
LVS 支持三种主要的工作模式,适应不同网络环境:
- LVS-NAT模式
- 全名:Network Address Translation
- 原理:网络地址转换。Client 请求 LVS,LVS 通过 DNAT 将目标地址修改为真实地址,将请求转给 RealServer 并获取响应后,LVS 通过 SNAT 将源地址修改为自己的 VIP,再转发给 Client。
- 特点:LVS 对请求和响应双向都参与处理,压力较大。
- 适用场景:要求 RealServer 与 LVS 在同一局域网;性能略差。
- LVS-DR模式
- 全名:Direct Routing
- 原理:直接路由模式。Client 请求 LVS,LVS 只修改 MAC 地址,将数据包通过数据链路层直接发给 RealServer,RealServer 不经过 LVS 直接将响应返回给 Client。
- 特点:LVS 仅负责请求方向,响应绕过,减少 LVS 负载。
- 适用场景:要求 RealServer 与 LVS 在同一局域网;要求禁用ARP;性能较高。
- LVS-TUN模式
- 全名:IP Tunneling
- 原理:IP 隧道模式。Client 请求 LVS,LVS 将请求封装成 IP 隧道包(使用 IPIP 协议)转发给 RealServer,RealServer 解封装后处理请求,直接将响应返回给 Cilent。
- 特点:LVS 只负责请求方向,且不要求与 RealServer 在同一局域网。
- 适用场景:允许后端服务器分布在不同物理网络;要求支持隧道;性能较高。
参考
2.3 实践(一知半解,该内容暂留,以后填坑)
2.3.1 LVS-NAT模式
三个核心角色
- Client(客户端)
- 含义:发起请求的主机
- 流程:访问虚拟服务地址 VIP
- Director(LVS 调度器)
- 含义:安装有 LVS(通过 ipvsadm 配置)并对外开放 VIP 作为流量入口
- 流程:接收来自 Client 请求,并转发给 RealServer
- RealServer(真实服务器)
- 含义:提供服务的主机
- 流程:与 Director 处于同一局域网内,并将默认网关设置为 Director 的内网 IP(DIP),保证响应正确返回给 LVS
三个 IP
名称 | 所属角色 | 含义 |
---|---|---|
VIP | Director | Virtual IP,对外暴露,Client 访问这个地址 |
DIP | Director | Director IP,LVS 的内网地址,RealServer 的网关应设为此 |
RIP | RealServer | RealServer IP,真实服务器的地址,仅 LVS 与之通信 |
我有四台机器,这四台机器在同一个局域网内。
- 10.0.0.10
- 用途:Client
- 10.0.0.101
- 用途:Director
- 10.0.0.102
- 用途:RealServer。部署 Nginx,开启 80 端口。
- 10.0.0.103
- 用途:RealServer。部署 Nginx,开启 80 端口。
Director 配置
1.) 开启 IP 转发。该内容仅需要针对 Director 开启即可。
验证是否开启 ipv4
1 | # 方式一 |
临时修改,服务器重启后失效
1 | # 方式一 |
永久修改
1 | echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf |
2.) 配置负载均衡规则。并开启一个虚拟 IP。
1 | # 添加虚拟 IP(VIP),dev 是 device 的缩写,ens33 表示网络接口 |
其他常用命令
1 | # 若需要删除 |
RealServer 配置
1.) 安装 Nginx, 开启 http 80 端口。一键安装 Nginx 脚本参考那些年,我玩过的Bash脚本
2.) 分别修改默认 index.html,返回当前的 IP 地址
1 | echo "<h1>10.0.0.102</h1>" >/usr/local/nginx/html/index.html |
3.) 最关键的一步,需要将首选网关配置为 Director,并设置较高的优先级。metric 值越小,优先级越高。
1 | # 查看当前路由 |
运行结果
修改了网关后,要等一会。不会立马生效。
2.3.2 LVS-DR模式
同样是三个角色,Director、RealServer、Client,也同样是上述四台机器。具体含义可以参考上述说明。
Director 配置
1 | # 为 Director(负载均衡器)上的 ens33 网络接口添加 IP 地址 10.0.0.200,/32 表示这是一个单一的 IP 地址 |
RealServer 配置
1.) 安装 Nginx, 开启 http 80 端口。一键安装 Nginx 脚本参考那些年,我玩过的Bash脚本
2.) 分别修改默认 index.html,返回当前的 IP 地址
1 | echo "<h1>10.0.0.102</h1>" >/usr/local/nginx/html/index.html |
3.) 配置
1 | # 为 RealServer 上的 lo 网络接口添加 Director 的虚拟 IP 地址 10.0.0.200,确保其能够与 Director 进行 ARP 通信 |
2.3.3 LVS-TUN模式
同样是三个角色,Director、RealServer、Client,也同样是上述四台机器。具体含义可以参考上述说明。
问题1:Director与Realserver之间,只需要开启一个IP隧道吗?那怎么负载均衡?
问题2:如果只需要开启一个IP隧道是正确的,那么不配置ip隧道是不是也可以?
Director 配置
1 | # 启用IP转发,允许流量转发到真实服务器 |
RealServer 配置
三、keepalived
3.1 工作原理
keepalived 用于应用服务的高可用,当应用服务出现故障时,可以将请求转移到正常的服务上面。
keepalived 由以下部分组成:
- VRRP(Virtual Router Redundancy Protocol)
- 负责虚拟 IP(VIP)的主备切换,保证服务高可用。
- 健康检查(Health Check)
- 支持编写自定义脚本,检测服务的存活状态,避免流量转发到故障节点。
VRRP 主备切换,其核心原理如下:
- 角色划分
- Master(主):持有 VIP,负责对外提供服务,并定期发送 VRRP 广播
- Backup(备):监听 Master 的心跳消息,在 Master 故障时接管 VIP。
- 选举机制
- VRRP 采用 优先级(Priority) 进行主备选举,默认范围 1-255,值越大优先级越高。
- 默认情况下,优先级高的节点成为 Master。
- Master 会 周期性发送 VRRP 广播包,告诉 Backup “我还活着”。
- Backup 监听 Master 的 VRRP 包,如果一定时间内收不到心跳,则触发故障转移(Failover):
- 最高优先级的 Backup 变为 Master,接管 VIP。
- 旧的 Master 恢复后,如果优先级较低,则作为 Backup。
问:当 VIP 进行故障转移时,局域网内其他机器如何知道这个 VIP 被哪台机器接管了?
答:局域网内其他机器,在访问这个 IP 时,如果当前
arp -a
缓存里面不存在该 IP 对应 MAC 地址。则会发送 ARP 请求,询问同一子网内的机器:拥有这个 IP 地址的机器需要将 MAC 地址返回。
3.2 安装
直接运行 i-keepalived.sh
1 |
|
运行日志查看
1 | journalctl -u keepalived -f |
3.3 实践
我有四台机器,这四台机器在同一个局域网内。
- 10.0.0.10
- 用途:Client
- 10.0.0.101
- 用途:Keepalived + Nginx (HTTP 80)
- 主机名:node1
- 10.0.0.102
- 用途:Keepalived + Nginx (HTTP 80)
- 主机名:node2
- 10.0.0.103
- 用途:Keepalived + Nginx (HTTP 80)
- 主机名:node3
我现在要实现将 node1、node2、node3 组建成一个支持故障转移的高可用集群,要点如下。
- 对外的 VIP 为 10.0.0.200。
- node1 为 master 节点,其他的为 backup 节点,并且 node1、node2、node3 的优先级分别为 100、99、98。
node1 的 /etc/keepalived/keepalived.conf
完整配置如下
1 | global_defs { |
在此基础上,针对 node2 进行配置调整。
- state 调整为 BACKUP
- priority 调整为 99
针对 node3 进行配置调整。
- state 调整为 BACKUP
- priority 调整为 98
依次在 node1、node2、node3 机器上进行 keepalived的服务启动。关闭 nginx 进行验证即可。
- 验证脚本执行:查看 nginx 访问日志
- 验证 VIP 漂移:查看 keepalived 日志,或者,执行
ip addr
查看