【前言】
本文是我近期对 Linux 高可用架构的一次系统复习。通过搭建一个包含 LVS、Keepalived、Nginx、NFS 和 DNS 的五节点集群,深入理解了负载均衡与故障自动转移的原理。
核心目标 :构建一个无单点故障、数据统一、支持域名访问的高性能 Web 服务集群。
适用场景 :Linux 运维入门、毕业设计参考、面试突击复习。
注意:本文基于 Redhat系统进行命令编写 ,其他发行版命令略有差异。
前置知识
- LVS(Linux Virtual Server):实现负载均衡
- Keepalived:实现 VIP 高可用(故障转移)
- Nginx:作为反向代理或 Web 服务器
- DNS:提供域名解析服务
- NFS:共享存储,用于统一内容(如网页、图片等)
LVS(Linux Virtual Server)
1、简介
LVS是章文嵩博士发起的开源项目,它是Linux内核的一部分,属于四层(传输层)负载均衡技术。它不是一个独立的软件服务,而是内核中IPVS(IP Virtual Server)模块的功能体现。LVS工作在网络模型的第四层,负责处理TCP/UDP协议的请求,不关心应用层(如HTTP)的具体内容,这使得它的转发效率极高,能够承载巨大的并发连接。
2、工作原理
其核心原理是在集群前端设立一个或多个"调度器"(Director),这些调度器接收来自客户端的请求。调度器根据预设的负载均衡算法(如轮询RR、加权轮询WRR、最少连接LC、加权最少连接WLC等),从后端的"真实服务器"(Real Server)池中选择一台最合适的服务器。然后,LVS通过修改数据包的目标IP地址(NAT模式)、目标MAC地址(DR模式)或将数据包封装在IP隧道中(TUN模式),将请求转发给选定的真实服务器。真实服务器处理完请求后,响应数据包会直接或间接地返回给客户端。
3、作用
LVS的主要作用是构建一个高性能、高可扩展性的服务器集群。它能够将海量的用户请求智能地分发到多台后端服务器上,从而避免单台服务器因负载过高而崩溃,极大地提升了整个系统的吞吐能力和响应速度。由于其工作在内核层面,资源消耗极低,常被用作大型网站或应用架构的最前端入口,作为整个负载均衡体系的基石,为后端的Nginx、Apache或应用服务器分担压力。
Keepalived
1、简介
Keepalived是一款基于VRRP(Virtual Router Redundancy Protocol,虚拟路由器冗余协议)实现的高可用(High Availability, HA)解决方案。它的核心目标是消除单点故障,确保关键服务(如LVS、Nginx)的持续可用性。Keepalived通过在多台服务器(一个Master主节点和多个Backup备份节点)之间进行"心跳"检测,来监控整个集群的健康状态,并管理一个或多个虚拟IP地址(VIP)。
2、工作原理
其工作原理是,集群中的所有节点都运行Keepalived守护进程。Master节点会周期性地发送VRRP通告,告知其他节点自己处于活动状态。Backup节点监听这些通告,如果在指定时间内没有收到Master的通告,就会认为Master已经宕机。此时,Backup节点之间会根据预设的优先级(Priority)进行选举,优先级最高的节点将接管VIP,并对外提供服务的网络接口(如eth0)上绑定这个VIP,这个过程称为"VIP漂移"。同时,Keepalived还具备健康检查功能,可以监控后端真实服务器的端口或运行特定脚本,自动将故障节点从服务池中剔除。
3、作用
Keepalived的主要作用是为LVS、Nginx等负载均衡器提供高可用保障。在没有Keepalived的情况下,一旦LVS调度器宕机,整个服务就会中断。通过部署Keepalived,可以构建一个LVS调度器集群(一主多备),当主LVS发生故障时,VIP会自动、快速地漂移到备用LVS上,客户端几乎无感知,从而实现了服务的故障自动转移(Failover),保证了业务的连续性。
Nginx
1、简介
Nginx是一款轻量级、高性能的开源Web服务器和反向代理服务器。它以其高并发处理能力、低内存消耗和稳定性而闻名。与传统的Apache服务器不同,Nginx采用异步非阻塞的事件驱动架构,能够用很少的线程处理大量的并发连接,这使得它在处理静态内容和作为反向代理时表现尤为出色。
2、工作原理
作为反向代理,其工作原理是,Nginx接收来自客户端的HTTP/HTTPS请求,然后根据自身的配置规则,将这些请求转发给后端的一个或多个应用服务器(如Tomcat、Gunicorn等)。后端服务器处理完业务逻辑后,将结果返回给Nginx,最后由Nginx将响应内容返回给客户端。在这个过程中,Nginx可以执行多种任务,例如:负载均衡(在多个后端服务器间分配请求)、缓存静态内容、压缩响应数据、处理SSL/TLS加密解密(SSL卸载)、以及根据URL路径进行请求路由。
3、作用
Nginx的主要作用非常广泛。首先,它是一个优秀的反向代理和负载均衡器,常部署在LVS之后,处理更复杂的七层(应用层)HTTP请求分发。其次,它是一个高效的静态文件服务器,可以直接提供HTML、图片、CSS、JS等文件,减轻后端应用服务器的压力。此外,它还常被用作API网关、内容缓存服务器和动态内容的加速器,是现代Web架构中不可或缺的核心组件。
DNS(Domain Name System)
1、简介
DNS,即域名系统,是互联网的基础设施,常被比作互联网的"电话簿"。它是一个分布式、分层的数据库系统,其核心功能是将人类易于记忆的域名(如http://www.example.com)转换为计算机用于互相通信的IP地址(如192.0.2.1)。没有DNS,用户就需要记住每个网站的数字IP地址,这在实际使用中是不可想象的。
2、工作原理
DNS的工作原理是一个递归与迭代相结合的查询过程。当用户在浏览器输入一个域名时,操作系统会首先查询本地DNS缓存。如果未命中,请求会发送到配置的本地DNS解析器(通常由ISP提供)。解析器会依次向根域名服务器、顶级域名服务器(如.com)、权威域名服务器发起查询,直到获取到最终的IP地址。这个过程对终端用户是完全透明的。DNS采用树状分层结构,从根域到顶级域,再到二级域,每一层都负责管理其下一级的域名信息。
3、作用
DNS的主要作用是实现域名到IP地址的解析,这是其最基本的功能。除此之外,它还有许多高级应用。例如,通过配置多条A记录,DNS可以实现简单的负载均衡,将域名解析到不同的服务器IP。通过设置MX记录,可以指定接收邮件的邮件服务器。通过CDN(内容分发网络)技术,DNS可以根据用户的地理位置,将其解析到距离最近的服务器,从而加速内容访问。因此,DNS不仅是互联网的导航系统,也是实现高可用和性能优化的重要一环。
NFS(Network File System)
1、简介
NFS,即网络文件系统,是由Sun公司开发的一种分布式文件系统协议。它允许网络中的计算机(通常是Linux/Unix系统)通过TCP/IP网络共享目录和文件,就像访问本地硬盘一样。NFS使得多台服务器可以方便、统一地访问同一份数据,是实现数据集中管理和共享的经典解决方案。
2、工作原理
其工作原理基于客户端/服务器(C/S)架构。在一台服务器上启动NFS服务,并配置需要共享的目录及其访问权限(即NFS服务器)。然后,在其他的客户端机器上,通过mount命令将服务器共享出来的目录挂载到本地的一个挂载点上。一旦挂载成功,客户端上的应用程序和用户就可以像操作本地文件一样,对挂载点下的文件进行读取、写入、创建和删除等操作。所有的文件I/O请求都会通过网络被透明地发送到NFS服务器进行处理,结果再返回给客户端。
3、作用
NFS的主要作用是在服务器集群中提供统一的共享存储。在你提到的架构中,如果多台Nginx或Web服务器需要访问相同的网页文件、用户上传的图片或视频等内容,使用NFS可以完美解决这个问题。只需将这些共享内容存放在一台NFS服务器上,然后让所有的Web服务器都挂载这个NFS共享目录,就可以确保所有服务器看到的内容是完全一致的。这极大地简化了内容部署和管理的复杂度,避免了在每台服务器上单独同步文件的麻烦,保证了数据的一致性和可靠性。
一、目标
本方案采用经典的 LVS-DR (Direct Routing) + Keepalived 架构,配合 NFS 实现数据共享。搭建一个高可用、可扩展的 Web 服务集群,具备以下特性:
-
多个后端 Web 服务器(Nginx)通过 LVS 负载均衡
-
使用 Keepalived 实现 LVS 主备切换(避免单点故障)
-
所有 Nginx 服务器从 NFS 共享存储读取静态内容
-
通过 DNS 解析访问 VIP 地址
LVS-DR工作模式
DR(Direct Routing 直接路由),LVS默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部进行转发,源MAC是 DIP 所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址。源IP/PORT,以及目标IP/PORT均保持不变。

它的核心思想是:请求经过负载均衡器(Director),但响应数据直接由真实服务器(Real Server)返回给客户端,不经过负载均衡器。
核心特点:
- 高性能:只有入站流量经过调度器,出站流量(响应)由后端服务器直接处理,极大减轻了调度器的网络压力。
- 透明性:对客户端完全透明,客户端认为自己在访问一个单一的虚拟服务(VIP)。
- 局域网要求:调度器(Director)和所有真实服务器(Real Server)必须连接在同一个物理网段(同一二层网络)上。
- IP 不变:转发过程中,IP 包头中的源 IP 和目标 IP 保持不变,只修改 MAC 地址。
工作原理:图解
1、客户端请求 (Client → LVS)
- 用户访问虚拟IP (VIP, 11.1.1.10)。
- 数据包的目标MAC地址是 LVS的DIP MAC (mac@VIP / mac@1)。
- 数据包到达LVS调度器。
2、LVS转发 (LVS → Real Server)
- LVS根据负载均衡算法选择一台真实服务器 (例如 RIP-1)。
- 关键操作: LVS 只修改数据包的MAC地址!
- 目标MAC从 mac@VIP 改为 RIP-1的MAC (mac@RIP)。
- IP地址保持不变 (源IP仍是客户端IP,目标IP仍是VIP)。
- 修改后的数据包被直接发送给 RIP-1。
3、真实服务器响应 (Real Server → Client)
- RIP-1收到数据包,发现目标IP是VIP (11.1.1.10)。
- 由于RIP-1的回环接口 (lo) 绑定了VIP,并且配置了ARP抑制,它会正常处理这个请求。
- 最关键的一步: RIP-1 直接将响应包返回给客户端。
- 响应的源IP是 VIP (11.1.1.10)。
- 响应的源MAC是 RIP-1的MAC (mac@RIP)。
- 完全不经过LVS!
二、所需虚拟机数量(建议配置)
| 角色 | 数量 | 说明 |
|---|---|---|
| LVS + Keepalived 主节点 | 1 | 负责负载均衡和 VIP 管理 |
| LVS + Keepalived 备节点 | 1 | 作为主节点故障时的热备 |
| Nginx 服务器 | 1 | 提供 Web 服务,挂载 NFS 共享目录 |
| NFS 服务器 | 1 | 提供共享存储(存放网页文件) |
| DNS 服务器 | 1 | 提供域名解析(可选,也可用公网 DNS) |
总共需要 5 台虚拟机
三、IP 规划
| 主机名 | IP 地址 | 角色 | 用途 |
|---|---|---|---|
lvs-master |
192.168.194.128 |
LVS + Keepalived 主 | 主负载均衡 |
lvs-backup |
192.168.194.130 |
LVS + Keepalived 备 | 备份负载均衡 |
web1 |
192.168.194.131 |
Nginx + NFS 客户端 | Web 服务器 |
nfs-server |
192.168.194.134 |
NFS 服务器 | 存放网站文件 |
dns-server |
192.168.194.135 |
DNS 服务器 | 域名解析 |
| VIP | 192.168.194.100 |
虚拟 IP | 由 Keepalived 管理,用户访问地址 |
所有主机需在同一个局域网内,且能互相通信。
四、详细搭建步骤
步骤 0:准备工作
-
在所有虚拟机上安装 RHEL 9.6(或 CentOS Stream 9)
-
设置静态 IP(使用
nmcli或/etc/sysconfig/network-scripts/ifcfg-ens33) -
关闭防火墙和 SELinux(测试环境可关闭)
bash
# 修改静态IP、主机名等。
#!/bin/bash
# useage: sudo ./init_sys.sh <hostname> <ip_address> [gateway] [dns]
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "此脚本必须以root权限运行"
exit 1
fi
}
usage() {
echo "用法: $0 <hostname> <ip_address> [gateway] [dns_servers]"
echo ""
echo "参数说明:"
echo " hostname 要设置的主机名"
echo " ip_address 要设置的静态IP地址 (如: 192.168.194.100)"
echo " gateway 网关地址 (如: 192.168.194.2)"
echo " dns_servers DNS服务器,逗号分隔 (可选,默认: 8.8.8.8,223.5.5.5)"
echo ""
echo "示例:"
echo " $0 myserver 192.168.194.100/24 192.168.1.1 8.8.8.8,223.5.5.5"
echo " $0 webserver 10.0.0.50/24"
exit 1
}
get_interface() {
# 尝试获取第一个活动的非环回接口
local interface=$(ip route | grep default | head -1 | awk '{print $5}' 2>/dev/null)
if [[ -z "$interface" ]]; then
# 如果没有默认路由,获取第一个非环回接口
interface=$(ip link show | grep -v lo | grep 'state UP' | head -1 | awk -F': ' '{print $2}')
fi
if [[ -z "$interface" ]]; then
log_error "无法自动检测网络接口"
read -p "请输入网络接口名称 (如: eth0, ens160): " interface
fi
echo "$interface"
}
set_hostname() {
local hostname=$1
log_info "正在设置主机名为: $hostname"
/usr/bin/hostnamectl set-hostname $hostname
log_info "主机名设置完成"
}
set_static_ip() {
local interface=$(get_interface)
local ip=$1
local gateway=${2:-"192.168.194.2"}
local dns=${3:-"223.5.5.5,8.8.8.8"}
log_info "正在为接口 $interface 配置静态IP: $ip"
nmcli c modify $interface ipv4.method manual ipv4.addresses $ip/24 ipv4.gateway $gateway ipv4.dns $dns connection.autoconnect yes
nmcli c up $interface
}
main() {
if [[ $# -lt 2 ]]; then
usage
fi
check_root
set_hostname "$1"
set_static_ip "$2" "$3" "$4"
}
main "$@"
# 使用的时候,写成shell脚本,运行使用 bash 脚本名称 虚拟机IP
# 接下来关闭防火墙,selinux
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=permissive/" /etc/selinux/config
systemctl disable --now firewalld.service
运行脚本
bash
bash init_sys.sh lvs-master 192.168.194.128
步骤 1:搭建 NFS 服务器(nfs-server)
1.1 安装 NFS 服务
bash
dnf install -y nfs-utils
1.2 创建共享目录并设置权限
bash
mkdir -p /data/www/html
chown -R nobody: /data
echo "<h1>Welcome to NFS Website</h1>" > /data/www/html/index.html
1.3 配置 /etc/exports
bash
/data/www/html 192.168.194.0/24(rw,sync,no_subtree_check)
no_root_squash 允许 root 用户访问,生产环境建议禁用。
1.4 启动服务并开机自启
bash
systemctl start nfs-server
1.5 查看是否导出成功
bash
exportfs -v
1.6 验证
bash
[root@nfs ~]# showmount -e 192.168.194.134
Export list for 192.168.194.134:
/data/www/html 192.168.194.0/24
步骤 2:配置 Nginx 服务器(web1)
2.1 安装 Nginx
bash
dnf install -y nginx nfs-utils
2.2 挂载 NFS 共享目录
bash
mount -t nfs 192.168.194.134:/data/www/html /usr/share/nginx/html/
# 验证 cat /usr/share/nginx/html/index.html
2.3 启动 Nginx
bash
systemctl start nginx
2.4 测试访问
在浏览器中访问 http://192.168.194.131,应显示欢迎页面。
步骤 3:搭建 DNS 服务器(dns-server)
1、安装bind
bash
[root@dns ~]# dnf install bind -y
2、配置/etc/named.conf
bash
[root@dns ~]# vim /etc/named.conf
文件的内容如下:
bash
options {
listen-on port 53 { 127.0.0.1; 192.168.194.135; };
directory "/var/named";
dump-file "/var/named/data/cache_dump.db";
statistics-file "/var/named/data/named_stats.txt";
memstatistics-file "/var/named/data/named_mem_stats.txt";
secroots-file "/var/named/data/named.secroots";
recursing-file "/var/named/data/named.recursing";
allow-query { localhost; 192.168.194.0/24; };
recursion yes;
dnssec-validation no;
managed-keys-directory "/var/named/dynamic";
geoip-directory "/usr/share/GeoIP";
pid-file "/run/named/named.pid";
session-keyfile "/run/named/session.key";
include "/etc/crypto-policies/back-ends/bind.config";
};
logging {
channel default_debug {
file "data/named.run";
severity dynamic;
};
};
zone "." IN {
type hint;
file "named.ca";
};
include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
3、配置区域文件
bash
[root@dns ~]# vim /etc/named.rfc1912.zones
文件的内容如下:
bash
zone "chengke.com" IN {
type master;
file "chengke.com.zone";
};
4、配置区域数据解析文件
bash
[root@dns ~]# cp -p /var/named/named.localhost /var/named/chengke.com.zone
[root@dns ~]# vim /var/named/chengke.com.zone
文件内容如下:
bash
$TTL 1D
@ IN SOA ns1 root.chengk.com. (
0 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
IN NS ns1
ns1 IN A 192.168.194.135 # 本机IP
www IN A 192.168.194.131 # Nginx所在虚拟机IP
5、语法校验
bash
[root@dns ~]# named-checkconf -i /etc/named.conf
[root@dns ~]# named-checkzone chengke.com /var/named/chengke.com.zone
zone chengke.com/IN: loaded serial 0
OK
6、启动服务
bash
[root@dns ~]# systemctl start named
7、解析验证
bash
[root@dns ~]# dig -t A www.chengke.com @192.168.194.135
步骤 4:搭建 LVS + Keepalived(主备)
4.0 系统使用LVS-DR 模式配置
在 DR 模式下,如果后端真实服务器(Nginx)也响应了 VIP 的 ARP 请求,会导致网络冲突,VIP 无法正常工作。
由于采用 DR 模式,必须在 Nginx 服务器 (web1) 上配置内核参数,防止其抢占 VIP。
在 web1 上执行:
bash
echo "net.ipv4.conf.lo.arp_ignore = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.lo.arp_announce = 2" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.arp_ignore = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.arp_announce = 2" >> /etc/sysctl.conf
sysctl -p
4.1 安装 LVS 和 Keepalived
在 lvs-master 和 lvs-backup 上执行:
bash
dnf install -y ipvsadm keepalived
创建lvs的配置文件
bash
ipvsadm-save -n > /etc/sysconfig/ipvsadm
启动ipvsadm
bash
systemctl start ipvsadm
查看有无规则
bash
ipvsadm -Ln
4.2 配置 LVS(ipvsadm)
在 lvs-master 上配置(先手动测试)
bash
# 清空现有规则
ipvsadm -C
# 添加虚拟服务(VIP:192.168.194.100:80)
ipvsadm -A -t 192.168.194.100:80 -s rr
# 添加真实服务器
ipvsadm -a -t 192.168.194.100:80 -r 192.168.194.131:80 -m
-m表示 NAT 模式(DR 模式更高效,但需修改 MAC,此处简化)
4.3 配置 Keepalived(主节点)
先备份,再编辑
bash
[root@lvs-master ~]# cp /etc/keepalived/keepalived.conf{,.bak}
[root@lvs-master ~]# vim /etc/keepalived/keepalived.conf
编辑 /etc/keepalived/keepalived.conf(lvs-master)
bash
global_defs {
router_id LVS_master
}
vrrp_instance VI_1 {
state MASTER
interface ens160
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.194.100
}
}
virtual_server 192.168.194.100 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.194.131 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}
4.4 配置 Keepalived(备节点)
在 lvs-backup 上配置 /etc/keepalived/keepalived.conf
bash
global_defs {
router_id LVS_backup
}
vrrp_instance VI_1 {
state BACKUP
interface ens160
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.194.100
}
}
virtual_server 192.168.194.100 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.194.131 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 3
retry 3
delay_before_retry 3
}
}
}
4.5 启动 Keepalived
bash
systemctl start keepalived
ip add # 查看是否有虚拟IP
此时 VIP 应出现在
lvs-master上,可通过ip addr show查看。
五、测试验证
-
在客户端测试访问:
bashcurl http://192.168.194.100 # 可以访问或通过 DNS(如果测试lvs-master或者lvs-backup都需要将DNS改为192.168.194.135):
bash[root@web1 ~]# nmcli d show ens160 | grep DNS IP4.DNS[1]: 223.5.5.5 # 修改DNS地址 [root@web1 ~]# nmcli c m ens160 ipv4.dns 192.168.194.135 [root@web1 ~]# nmcli c up ens160 Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/3) # 验证修改 [root@web1 ~]# nmcli d show ens160 | grep DNS IP4.DNS[1]: 192.168.194.135 # 最后验证测试 curl www.chengke.com -
关闭
lvs-master,观察 VIP 是否自动切换到lvs-backup -
检查
ipvsadm -ln查看负载均衡状态 -
修改 NFS 上的内容,确认所有 Nginx 服务器都能同步更新
-
故障切换测试 (High Availability Test)
模拟主节点宕机:
bash
# 在 lvs-master 上执行
systemctl stop keepalived
# 或者直接切断网卡
ip link set ens160 down
观察现象:
1、等待约 3-6 秒(心跳超时)。
2、在 lvs-backup 上执行 ip addr,确认 VIP (192.168.194.100) 已漂移到备节点。
3、再次 curl http://192.168.194.100,服务依然正常,业务未中断。