keepalived

2
  • 会自动虚拟一个ip(virtual ip address,简称VIP)
    • vip漂移在a机器上,ip a 会看到两个ip,一个是本机ip,另一个是vip
    • 当a机器故障时,无法接受请求;由于a 和 b在同一组虚拟网络设备中,他们能互相通信 知道对方的存在,当b发现a挂掉之后会自动接管vip资源,使流量来到b机器,实现负载均衡集群的高可用
  • 核心就是: 1. 创建vip 2. 实现vip的漂移
    [[Drawing 2025-04-07 20.54.55.excalidraw]]
    ![[Pasted image 20250407210300.png]]

部署keepalived环境

  • 四台机器:两台业务 两台slb
# 两台业务
yum install nginx -y
echo 'i am yw 1|2' > /usr/share/nginx/html/index.html
nginx
curl localhost
# 两台slb
yum install nginx keepalived -y
vim /etc/nginx/conf.d/slb.conf
vim /etc/nginx/proxy_params
# slb.conf
upstream web_pools {
	server 192.168.32.104;
	server 192.168.32.105;
}
server {
	listen 88; # 避免与默认配置文件80冲突
	server_name _;
	location / {
		proxy_pass http://web_pools;
		include proxy_params;
	}
}

# proxy_params
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
nginx
curl localhost:88

vim /etc/keepalived/keepalived.conf
# master
global_defs {
    router_id slb_106
}

vrrp_instance VIP_1 {
    state MASTER                
    interface ens32   
    virtual_router_id 50  
    priority 150        
    advert_int 1       
    authentication {  
        auth_type PASS 
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.32.108/24     
    }
}
# backup
global_defs {
    router_id slb_107
}

vrrp_instance VIP_1 {
    state BACKUP                
    interface ens32   
    virtual_router_id 50  
    priority 100        
    advert_int 1       
    authentication {  
        auth_type PASS 
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.32.108/24     
    }
}
systemctl start keepalived
ip a # 可以看到vip108在master机器上

keepalived配置文件解读

  • router_id 在这个虚拟路由器组中的都不一样
  • state 只有一个master,可以有多个backup
  • interface 指定当前负载均衡机器的 通信的网卡
  • virtual_router_id 注意,每个机器,都一样,表示是一组内的设备
  • priority 优先级,master需要高于backup
  • advert_int 发送组播间隔1s
  • authentication 一组设备中的master和backup的通信认证,是明文形式的 1111;这个信息,可以通过抓包看到。
  • virtual_ipaddress 指定VIP的ip地址,需要在局域网内,无人使用

测试vip漂移

  • 当master的keepalived挂掉时,vip会自动切换到backup机器上,可以ip a看到
  • 当master的keepalived起来时,vip又会自动切换回来,是因为配置文件中的优先级 150>100;注意 这里一定是master大于backup,否则无法实现master自动漂移;
keepalived就是虚拟了一个网络设备组 vrrp组

![[Pasted image 20250407232419.png]]
[[Drawing 2025-04-07 23.16.05.excalidraw]]

vrrp原理

  • keepalived是通过vrrp协议实现的高可用,实现vip的漂移
  • vrrp将多台设备组成一个虚拟设备(一台master 可以多台backup),master和backup一直在发送心跳包,如果不发了backup就会认定master挂掉了,会自动抢占接管master的位置
1. keppalived高可用是基于VRRP虚拟路由冗余协议实现的,因此我从VRRP给您描述起
2. VRRP也就是虚拟路由冗余协议,是为了解决静态路由的单点故障;
3. VRRP通过竞选协议将路由任务交给某一台VRRP路由器。
4. VRRP正常工作时,master会自动发送数据包,backup接收数据包,目的是为了判断对方是否存活;如果backup收不到master的数据包了,自动接管master的资源;
backup节点可以有多个,通过优先级竞选,但是keepalived服务器一般都是成对出现;
5. VRRP默认对数据包进行了加密,但是官网默认还是推荐使用明文来配置认证;

说完了VRRP,我再给您描述下keepalived工作原理。
1.keepalived就是基于VRRP协议实现的高可用,master的优先级必须高于backup,因此启动时master优先获得机器的IP资源,backup处于等待状态;若master挂掉后,backup顶替上来,继续提供服务。
2.在keepalived工作时,master角色的机器会一直发送VRRP广播数据包,告诉其他backup机器,“我还活着”,此时backup不会抢夺资源,老实呆着。
当master出现问题挂了,导致backup收不到master发来的广播数据包,因此开始接替VIP,保证业务的不中断运行,整个过程小于1秒。

抓包理解

![[Pasted image 20250409001040.png]]

  • 目前是106一直在想这个组播地址发vrrp包,告诉虚拟组中vip是我 我还活着呢 backup都是在同一个这个组播地址中,也收到了106vip的包
    ![[Pasted image 20250409001336.png]]
  • 这时候停掉106vip的keepalived,看看会发生什么👀
    ![[Pasted image 20250409001752.png]]

单播、广播、组播

  • 单播是网络中1对1 想一对三的话得发三份
  • 广播是网络中1对网络中所有可能收到的设备 只发一份
  • 组播是网络中1对这个组 一份这个组都能收到

脑裂问题

  • 本质上就是master还在正常工作,但是backup没有收到master的心跳包,以为master挂了进而抢占master资源;
  • 这时候就会导致两个机器都有了VIP,导致冲突故障,这就是脑裂问题

原因:

  • 心跳线老化,线路破损,导致无法通信
  • 网卡驱动损坏,master、backup ip地址冲突
  • 防火墙配置错误
  • 配置文件写错,两台虚拟路由id不一致,导致不是同一个组播地址

模拟:

tcpdump -i any vrr
-i 指定网卡
any 监测所有网卡

![[Pasted image 20250413222713.png]]

脑裂的影响:

(刚才测试了下测试环境并不会有影响,但是生产没测试环境这么简单)

  1. 业务不稳定 / 访问异常
    • 如果两台机器同时绑定了 VIP,会导致客户端连接到两台机器之间跳来跳去。
    • 尤其是如果你的业务是有状态的(比如登录态、session、数据库连接),就容易出问题。
  2. 数据不一致
    • 如果后端有数据库写入、缓存更新等,脑裂会导致数据冲突或错乱。
  3. 日志混乱 / 故障难排查
    • 日志里可能一会儿是这台机器处理的请求,一会儿是另一台,非常难查问题。
小插曲💡
  • 如果slb1的nginx挂掉什么现象
不会502,因为只有后端程序挂掉才会502(java php)
就只是单纯的网站无法连接,不会影响keepalived通信

脚本监测脑裂故障

## backup机器:
#!/bin/bash
MASTER_VIP=$(ssh 192.168.32.106 ip a | grep 192.168.32.108 | wc -l)
MY_VIP=$(ip a | grep 192.168.32.108 | wc -l)
if [[ $MASTER_VIP == 1 && $MY_VIP == 1 ]];then
systemctl stop keepalived
fi
  • 在backup的keepalive.conf中添加
    ![[Pasted image 20250413231817.png]]
    ![[Pasted image 20250413233215.png]]
小插曲💡

![[Pasted image 20250413232438.png]]

master机器nginx挂掉故障

#!/bin/bash
NGINX_STATUS=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ $NGINX_STATUS -eq 0 ];then
    nginx
    if [ $? -ne 0 ];then
        systemctl stop keepalived
    fi
fi
  • nginx随机写入一些汉字,就无法启动了,就会自动停止keepalived,把这个脚本类似上面那个写入到keepalive.conf里就行了
    (但不知道为啥我一直没模拟成功,后面再说吧)