keepalived-lsy

329 阅读4分钟

原理&介绍

vrrp协议

Virtual Router Redundancy Protocol 虚拟路由冗余协议 百科解释

多台路由器(实例)组成一个虚拟的设备,对外提供虚拟路由器IP(vip),在内部拥有者为master,其他为backup,除接受VRRP报文外不提供对外网络功能。master失效时,backup进行选举成为master。

用于实现 HA(High Available) 当同时注册到同一个虚拟路由器上的实例指定服务出现问题,则自动切换到备节点,实现Failover


安装&指令

安装

yum安装的同时会注册服务 可以使用 service 或 systemctl 控制

yum install -y keepalived 

控制

systemctl status keepalived
systemctl start keepalived
systemctl stop keepalived
systemctl restart keepalived

service keepalived start
service keepalived status
service keepalived stop
service keepalived restart

实时状态显示

#未启动 inactive
[root@192 keepalived]# service keepalived status
Redirecting to /bin/systemctl status keepalived.service
 keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
[root@192 keepalived]# systemctl status keepalived
 keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
   
#启动 active
[root@localhost keepalived]# systemctl status keepalived
 keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
   Active: active (running) since Wed 2021-12-08 06:29:07 CST; 29s ago
  Process: 7181 ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS)
 Main PID: 7182 (keepalived)
    Tasks: 3
   Memory: 5.7M
   CGroup: /system.slice/keepalived.service
           ├─7182 /usr/sbin/keepalived -D
           ├─7183 /usr/sbin/keepalived -D
           └─7184 /usr/sbin/keepalived -D

启动问题

#指令未识别 Unknow keyword
[root@localhost keepalived]# systemctl status keepalived
● keepalived.service - LVS and VRRP High Availability Monitor
   Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

Dec 08 06:51:45 localhost.localdomain Keepalived_vrrp[8409]: Registering Kernel netlink command channel
Dec 08 06:51:45 localhost.localdomain Keepalived_vrrp[8409]: Registering gratuitous ARP shared channel
Dec 08 06:51:45 localhost.localdomain Keepalived_vrrp[8409]: Opening file '/etc/keepalived/keepalived.conf'.
Dec 08 06:51:45 localhost.localdomain Keepalived_vrrp[8409]: WARNING - default user 'keepalived_script' for sc...te.
Dec 08 06:51:45 localhost.localdomain Keepalived_vrrp[8409]: Unknown keyword 'virtual_router'
Dec 08 06:51:45 localhost.localdomain Keepalived_vrrp[8409]: Unknown keyword 'adver_int'
Dec 08 06:51:45 localhost.localdomain Keepalived_vrrp[8409]: VRRP_Instance(VI_1) the virtual id must be set!
Dec 08 06:51:45 localhost.localdomain systemd[1]: Started LVS and VRRP High Availability Monitor.
Dec 08 06:51:46 localhost.localdomain Keepalived[8407]: Keepalived_vrrp exited with permanent error CONFIG. Te...ing
Dec 08 06:51:46 localhost.localdomain Keepalived[8407]: Stopping
Hint: Some lines were ellipsized, use -l to show in full.

查看网络中VRRP报文

tcpdump -i eth0 vrrp -n | grep "vrid <vrid编号>"

配置内容

配置文件路径 /etc/keepalived/keepalived.conf 原始配置

default config
! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
}
virtual_server 10.10.10.3 1358 {
    delay_loop 3
    lb_algo rr 
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 192.168.200.5 1358 {
        weight 1
        HTTP_GET {
            url { 
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url { 
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url { 
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

官方文档

参数详情


简单配置(结合nginx)

MASTER config
! Configuration file for keepalived
global_defs {
  router_id 131
}
vrrp_script check_nginx {
  script "/etc/keepalived/nginx_check.sh"
  interval 2
  weight 10
}
vrrp_instance VI_1 {
  state MASTER
  interface eth0
  virtual_router 25
  mcast_src_ip 192.168.85.131
  priority 100
  adver_int 1
  authentication {
    auth_type PASS
    auth_pass 12345
  }
  track_script {
    check_nginx
  }
  virtual_ipaddress {
    192.168.85.130
  }
}

BACKUP config
! Configuration file for keepalived
global_defs {
  router_id 131
}
vrrp_script check_nginx {
  script "/etc/keepalived/nginx_check.sh"
  interval 2
  weight 10
}
vrrp_instance VI_1 {
  state BACKUP #备节点
  interface ens33
  virtual_router_id 25
  mcast_src_ip 192.168.85.132 #广播的ip
  priority 95 #权重与主节点不同
  advert_int 1 
  authentication {
    auth_type PASS
    auth_pass 12345
  }
  track_script {
    check_nginx
  }
  virtual_ipaddress {
    192.168.85.130
  }
}

进程检测脚本1

只进行检测,不启动服务或关停keepalived nginx_check.sh 赋予脚本执行权限

#!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
  exit 1 # 检测失败
else
  exit 0 # 检测成功
fi

检测脚本2

关闭keepalived(不推荐) 会进行服务启动以及关闭keepalived的脚本

# /bin/bash
MYSQL_ALIVE=`ps -C mysqld |grep -v PID|wc -l`
if [ $MYSQL_ALIVE -eq 0 ];then
    service mysql restart
    sleep 3
    if [ `ps -C mysqld |grep -v PID |wc -l` -eq 0 ];then
    killall keepalived
    fi
fi

权重为正

可依据下列表格,检查是否能切换

名称节点A节点B
priority10095
weight1010
check_success(检测脚本返回0110105
check_fail(检测脚本返回非010095

配置文件中的priority 只是初始值,实际值需要结合检测脚本增减weight 来看

主节点检测失败时,master报文priority=100 < backup 成功 = 105节点的报文priority 所以backup能够抢占,进行切换

主节点 绑定成功可在对应的网口号上查看到VIP(第二个inet 192.168.85.130/32

ip addr show ens33
2: ens33: <broadcast,multicast,up,lower_up> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:d4:fa:28 brd ff:ff:ff:ff:ff:ff
    inet 192.168.85.131/24 brd 192.168.85.255 scope global noprefixroute dynamic ens33
       valid_lft 1012sec preferred_lft 1012sec
    inet 192.168.85.130/32 scope global ens33

切换过程中 vrrp网络的报文

tcpdump -i ens33 vrrp -n | grep "vrid 25"
09:06:11.727032 IP 192.168.85.131 > 224.0.0.18: VRRPv2, Advertisement, vrid 25, prio 110, authtype simple, intvl 1s, length 20
09:06:12.730351 IP 192.168.85.131 > 224.0.0.18: VRRPv2, Advertisement, vrid 25, prio 110, authtype simple, intvl 1s, length 20
#切换时
09:09:16.127825 IP 192.168.85.132 > 224.0.0.18: VRRPv2, Advertisement, vrid 25, prio 105, authtype simple, intvl 1s, length 20
09:09:17.129341 IP 192.168.85.132 > 224.0.0.18: VRRPv2, Advertisement, vrid 25, prio 105, authtype simple, intvl 1s, length 20

抢占模式

A为Master,B为Backup,必须配置权重weight A 服务挂,B抢到VIP,A服务启动后,A争抢回VIP 发生两次VIP的漂移

权重为负

名称节点A节点B
priority9995
weight-7-7
check_success(检测脚本返回09995
check_fail(检测脚本返回非09288

非抢占模式

不能配置权重 weight 必须注释掉 两台都是 backup ,配置nopreempt,不能配置权重weight,priority只是初始选举的作用 A 服务挂,B抢到VIP,A服务启动后,B不退还,A不争抢 两个节点各增加了nopreempt指令,表示不争抢vip

! Configuration file for keepalived
global_defs {
  router_id 131
}
vrrp_script check_nginx {
  script "/etc/keepalived/nginx_check.sh"
  interval 2
  #weight 10
}
vrrp_instance VI_1 {
  state BACKUP
  interface ens33
  virtual_router_id 25
  mcast_src_ip 192.168.85.131
  nopreempt
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass 12345
  }
  track_script {
    check_nginx
  }
  virtual_ipaddress {
    192.168.85.130
  }
}
  • 同时绑定多个VIP情况

  • 结合LVS

技巧&困惑

使用的注意点(坑) vip使用子网中非已存在的ip(物理机ip,其他的vip) 通过ping查看 virtual_router_id 需使用该子网未被使用的id,否则会将机器注册到已存在的id上,主从服务器必须保持一致 authentication - auth_pass主从服务器必须一致,keepalived靠这个来通信

出现手动调用脚本结果与keepalived自动调用结果不一致,打印日志后明显判断不同 配置文件有问题时,keepalived将无法启动,通过systemctl status keepalvied查看

遇到检测脚本不执行,可能是 selinux 或脚本未有执行权限

重启失效

setenforce 0

永久生效

sed -i "s/^SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config