LVS和Keepalived

LVS

LVS概述

LVS(Linux Virtual Server) 是 Linux 内核中集成的一套负载均衡框架,通过 IPVS(IP Virtual Server)模块实现。

基于 IP 和端口(如 TCP/UDP 协议)进行流量转发,不解析应用层(七层)的协议内容

ipvsadm 是一个 用户空间工具,用于配置和管理 LVS 内核模块。它提供命令行接口,允许管理员定义虚拟服务器、添加 / 删除后端服务器,以及调整调度策略。

特性 NAT 模式 DR 模式
数据包流向 请求和响应都经过 Director 请求经过 Director,响应直接返回客户端
网卡要求 Director 需要双网卡 单网卡即可
性能 较低(需处理双向流量) 较高(仅处理请求)
后端网关 RS 网关必须指向 Director RS 网关设置为真实网关
调度器参数 -m(NAT 模式) -g(DR 模式)

NAT模式

Director配置

  • 关闭iptables
systemctl stop firewalld
systemctl disable firewalld
  • 启用 IP 转发
# 临时启用
echo "1" > /proc/sys/net/ipv4/ip_forward

# 永久生效(编辑 /etc/sysctl.conf)
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
  • 配置 VIP
    ip addr add 1.1.1.100/32 dev ens37

  • 配置 LVS

yum install ipvsadm -y
ipvsadm -C
ipvsadm -A -t 1.1.1.100:80 -s rr
ipvsadm -a -t 1.1.1.100:80 -r 192.168.248.80:8080 -m  # 添加后端服务器,使用 NAT 方式

ipvsadm-save > /etc/sysconfig/ipvsadm

RS配置

  • 配置路由
ip route del default
ip route del 1.1.1.0/24
ip route add default via 192.168.248.50 dev ens33  # 写Director的IP
ip route add default via 1.1.1.50 dev ens37  # 写Director的IP

DR模式

Director配置

  • 绑定VIP到网卡ens33
# 临时绑定(重启失效)
ip addr add 192.168.248.61/32 dev ens33 label ens33:0

# 永久绑定(CentOS)
cat > /etc/sysconfig/network-scripts/ifcfg-ens33:0 <<EOF
DEVICE=ens33:0
BOOTPROTO=none
IPADDR=192.168.248.61
NETMASK=255.255.255.255
ONBOOT=yes
EOF
systemctl restart network
  • 设置内核参数
# 禁用 ARP 响应(让 VIP 只通过 Director 响应)
echo "1" > /proc/sys/net/ipv4/conf/ens33/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/ens33/arp_announce

# 永久生效
cat >> /etc/sysctl.conf <<EOF
net.ipv4.conf.ens33.arp_ignore = 1
net.ipv4.conf.ens33.arp_announce = 2
EOF
sysctl -p
  • 配置LVS规则
yum install -y ipvsadm
ipvsadm -C  # 清空之前的规则
ipvsadm -A -t 192.168.248.61:8080 -s rr  # 创建 LVS 服务,使用轮询调度算法
ipvsadm -a -t 192.168.248.61:8080 -r 192.168.248.80:8080 -g  # 添加 Real Server,使用 DR 方式
ipvsadm-save > /etc/sysconfig/ipvsadm  # 保存配置到系统启动时自动加载
ipvsadm -Ln  # 查看 LVS 规则

RS配置

  • 配置VIP到lo接口
# 临时绑定(重启失效)
ip addr add 192.168.248.61/32 dev lo

# 永久绑定(CentOS) lo子接口

# Centos7不支持在lo接口配置 IPADDR_SECONDARIES="192.168.248.61/32 192.168.248.62/32"
cat > /etc/sysconfig/network-scripts/ifcfg-lo:0 <<EOF
DEVICE=lo:0
BOOTPROTO=none
IPADDR=192.168.248.61
NETMASK=255.255.255.255
ONBOOT=yes
EOF
systemctl restart network
  • 设置内核参数
# 临时配置
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore  # 禁止lo响应 ARP请求
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce  # 防止广播lo接口的 ARP请求

# 永久配置(追加到 /etc/sysctl.conf)
cat >> /etc/sysctl.conf <<EOF
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
EOF
sysctl -p

抓包分析

首先我们统计下arp 表

IP MAC
192.168.248.10 00:0c:29:81:26:7e
192.168.248.80 00:0c:29:6e:6e:6e
192.168.248.60 00:0c:29:b6:ff:10
192.168.248.61 00:0c:29:b6:ff:10

数据包流向:
简单的说,就是client发送给Director的请求,Director转发给RS,然后RS直接回复Client。

其实从这也可以看出,TCP3次握手和四次挥手,只看IP不看MAC

  1. "SYN
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:81:26:7e
    目的MAC:00:0c:29:b6:ff:10"
  2. "TCP Retransmission |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:b6:ff:10
    目的MAC:00:0c:29:6e:6e:6e"
  3. "SYN,ACK |
    源IP:192.168.248.61
    目的IP:192.168.248.10
    源MAC:00:0c:29:6e:6e:6e
    目的MAC:00:0c:29:81:26:7e"
  4. "ACK |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:81:26:7e
    目的MAC:00:0c:29:b6:ff:10"
  5. "TCP Dup ACK |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:b6:ff:10
    目的MAC:00:0c:29:6e:6e:6e"
  6. "GET / HTTP/1.1 |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:81:26:7e
    目的MAC:00:0c:29:b6:ff:10"
  7. "TCP Retransmission |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:b6:ff:10
    目的MAC:00:0c:29:6e:6e:6e"
  8. "源IP:192.168.248.61
    目的IP:192.168.248.10
    源MAC:00:0c:29:6e:6e:6e
    目的MAC:00:0c:29:81:26:7e"
  9. "源IP:192.168.248.61
    目的IP:192.168.248.10
    源MAC:00:0c:29:6e:6e:6e
    目的MAC:00:0c:29:81:26:7e"
  10. "源IP:192.168.248.61
    目的IP:192.168.248.10
    源MAC:00:0c:29:6e:6e:6e
    目的MAC:00:0c:29:81:26:7e"
  11. "ACK |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:81:26:7e
    目的MAC:00:0c:29:b6:ff:10"
  12. "TCP Dup ACK |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:b6:ff:10
    目的MAC:00:0c:29:6e:6e:6e"
  13. "ACK |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:81:26:7e
    目的MAC:00:0c:29:b6:ff:10"
  14. "TCP Dup ACK |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:b6:ff:10
    目的MAC:00:0c:29:6e:6e:6e"
  15. "FIN,ACK |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:81:26:7e
    目的MAC:00:0c:29:b6:ff:10"
  16. "TCP Retransmission |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:b6:ff:10
    目的MAC:00:0c:29:6e:6e:6e"
  17. "FIN,ACK |
    源IP:192.168.248.61
    目的IP:192.168.248.10
    源MAC:00:0c:29:6e:6e:6e
    目的MAC:00:0c:29:81:26:7e"
  18. "ACK |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:81:26:7e
    目的MAC:00:0c:29:b6:ff:10"
  19. "TCP Dup ACK |
    源IP:192.168.248.10
    目的IP:192.168.248.61
    源MAC:00:0c:29:b6:ff:10
    目的MAC:00:0c:29:6e:6e:6e"

问题

RS在lo上配置VIP的作用

RS在lo上配置了VIP的作用就是,Director 转发数据包时,没有修改源/目的IPV4地址,而是修改MAC地址
所以Director转发给RS时,目的地址是VIP,RS收到数据包后,会发现是发给自己的VIP的,就直接处理了,否则RS会丢包或转发

RS在lo上配置了VIP,但实际上接收数据包的还是物理网卡是吗?

因为ipvsadm -a -t 192.168.248.51:8080 -r 192.168.248.70:8080 -g
Director 负责修改数据包的目的 MAC 地址,使其指向 RS 的物理网卡,所以不是发给lo
虽然 VIP 绑定在 lo 接口,但 Linux 内核认为本地所有接口的 IP 均属于主机本身。因此,无论数据包从哪个接口进入,只要目标 IP 是本地任意接口配置的 IP,内核都会将其视为 “本地进程需处理的数据包”,直接将其路由到本地协议栈

arp_ignore参数解析

控制是否响应 ARP 请求
0(默认):只要 ARP 请求的 IP 存在于本机任何网卡,就回应 MAC 地址(可能导致 ARP 混乱)。
1:仅当 ARP 请求的 IP 与接收网卡的 IP 严格匹配时,才回应 MAC 地址

  • Director[会响应arp]
    ens33.arp_ignore=1
    Director 只响应目标 IP 是自身物理网卡 IP 的 ARP 请求,VIP 配在 ens33:0 上,内核认为 ens33 配置了 VIP(因为 ens33:0 共享 IP 空间)。
    ens33.arp_ignore=1 → 允许响应。

  • RS[不响应arp]
    VIP:
    配置在 lo 接口(如 192.168.248.51/32)。
    物理网卡(如 ens33):未配置 VIP,仅配置真实 IP(如 192.168.248.70)。
    ARP 参数:
    lo.arp_ignore=1,lo.arp_announce=2。
    ens33.arp_ignore=0(默认值)。

当 ARP 请求到达 ens33 [ARP请求到达的都是物理网卡]
请求内容:Who has 192.168.248.51? Tell 192.168.248.10
内核处理流程:
检查接收接口 ens33:ens33 配置的 IP 是 192.168.248.70,与请求的 192.168.248.51 不匹配。
检查 arp_ignore 值:ens33.arp_ignore=0 → 允许继续检查其他接口。
检查其他接口:发现 lo 接口配置了 192.168.248.51。
检查 lo 的 arp_ignore 值:lo.arp_ignore=1 → 要求请求必须从 lo 接口接收才响应。
但实际请求是从 ens33 接收的,与 lo 无关 → 不响应。

arp_announce参数解析

决定系统在发送 ARP 响应时,使用哪个 IP 和 MAC 地址作为源
0(默认):允许使用任意本地 IP 地址作为 ARP 响应的源 IP,无论该 IP 配置在哪个接口。
2:严格只使用本网卡的 IP 地址进行 ARP 宣告

  • Director[物理网卡的源IP和MAC地址进行响应arp]
    ens33.arp_announce=2
    确保是 ens33 发送 ARP 响应,不使用 VIP 作为源 IP。

  • RS[防止RS广播VIP的ARP请求]
    防止 RS 主动广播 VIP 的 ARP 请求,避免客户端缓存错误的 MAC 地址

keepalived

主机 内网 IP (ens33) 外网 IP (ens37) VIP 角色
Client 192.168.248.10/24 客户端发起请求
Director1 192.168.248.50/24 1.1.1.50/24 192.168.248.100 主负载均衡器
Director2 192.168.248.60/24 1.1.1.60/24 192.168.248.100 备负载均衡器
RS 1.1.1.80/24 应用服务器

keepalived概述

  • 抢占模式:指当主节点(Master)恢复正常后,会主动从当前备用节点(Backup)夺回虚拟 IP(VIP)及服务资源的控制权,恢复为主节点。
  • 非抢占模式:主节点恢复后,需手动切换或通过其他策略(如权重值)才能重新成为 Master,备用节点不会主动让出资源。
    避免因主节点短暂故障恢复后频繁切换 VIP,适合对稳定性要求高、切换代价大的场景。

keepalived配置

  • Master
! Configuration File for keepalived

global_defs {
    router_id LVS_MASTER
}

vrrp_instance VI_1 {
    state BACKUP           # 实测这里得配置为BACKUP,不然还是会抢占
    interface ens33        # 绑定到内网网卡
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.248.100    # 内网 VIP
    }
}

vrrp_instance VI_2 {
    state BACKUP
    interface ens37        # 绑定到内网网卡
    virtual_router_id 52
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 2222
    }
    virtual_ipaddress {
        1.1.1.100    # 内网 VIP
    }
}


virtual_server 192.168.248.100 80 {
    delay_loop 6    # 检查间隔时间(秒),但下面的real_server 8080并没有配置,所以这里配置的延迟检查其实是无效的
    lb_algo rr      # 负载均衡算法,rr 表示轮询
    lb_kind NAT     # 负载均衡类型,NAT 表示 NAT 模式
    persistence_timeout 50  # 持久连接超时时间(秒)
    protocol TCP
    real_server 1.1.1.80 8080 {  # RS 外网 IP
        weight 1
    }
}
  • Backup
! Configuration File for keepalived

global_defs {
    router_id LVS_BACKUP
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33        # 绑定到内网网卡
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    nopreempt
    virtual_ipaddress {
        192.168.248.100    # 内网 VIP
    }
}

vrrp_instance VI_2 {
    state BACKUP
    interface ens37        # 绑定到内网网卡
    virtual_router_id 52
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 2222
    }
    nopreempt
    virtual_ipaddress {
        1.1.1.100    # 内网 VIP
    }
}


virtual_server 192.168.248.100 80 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 1.1.1.80 8080 {  # RS 外网 IP
        weight 1
    }
}
  • 健康检查
    # 纯TCP连接检查
    TCP_CHECK {
        connect_port 8080        # 检查端口
        connect_timeout 3        # 连接超时
        retry 3                  # 重试次数
        delay_before_retry 3     # 重试间隔
    }

RS配置路由

配置默认路由指向VIP:1.1.1.100
img

修改日志路径

tail -f /var/log/messages # 默认路径
修改keepalived日志存储路径(修改keepalived配置文件)
vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -S 0"

vim /etc/rsyslog.conf
local0.* /var/log/keepalived.log #添加一行配置

systemctl restart rsyslog # rsyslog,系统日志管理工具,负责统一管理所有日志的流转
systemctl restart keepalived

img

posted @ 2025-06-04 10:49  WiseHYH  阅读(17)  评论(0)    收藏  举报