第三十一章 高可用集群KEEPALIVED

225 阅读3分钟

@[TOC](第三十一章 高可用集群KEEPALIVED)

实验:双主Keepalived

实验环境

主机名称网卡IP/GW
client桥接1.16/24 GW1.7
routeNAT、桥接37.7和1.7
ka1NAT37.30/24 GW37.7
ka2NAT37.40/24 GW37.7
rs1NAT37.10/24 GW37.7
rs2NAT37.20/24 GW37.7

ka1和ka2

[root@ka1 ~]# yum install keepalived httpd -y
[root@ka1 ~]# echo Sorry Server > /var/www/html/index.html
[root@ka1 ~]# systemctl start httpd

[root@ka1 ~]# ssh-keygen

相互ke验证

[root@ka1 ~]# ssh-copy-id 192.168.37.40
和
[root@ka2 ~]# ssh-copy-id 192.168.37.30

ka1

[root@ka1 ~]# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.37.30 ka1    <--
192.168.37.40 ka2    <--

[root@ka1 ~]# scp /etc/hosts ka2:/etc/

[root@ka1 ~]# cd /etc/keepalived/
[root@ka1 keepalived]# ls
keepalived.conf
[root@ka1 keepalived]# cp keepalived.conf{,.bak}
[root@ka1 keepalived]# ls
keepalived.conf  keepalived.conf.bak

[root@ka1 keepalived]# vim keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ka1
   vrrp_mcast_group4 224.100.100.100
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 66
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.37.100/24 dev eth0 label eth0:1
    }
#出了故障触发相应的脚本执行
    notify_master "/etc/keepalived/notify.sh master"   <--
    notify_backup "/etc/keepalived/notify.sh backup"   <--
    notify_fault "/etc/keepalived/notify.sh fault"     <--
}

vrrp_instance VI_2 {
    state BACKUP
    interface eth0
    virtual_router_id 88
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 654321
    }
    virtual_ipaddress {
        192.168.37.200/24 dev eth0 label eth0:2
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

[root@ka1 keepalived]# scp keepalived.conf ka2:/etc/keepalived/

[root@ka1 keepalived]# vim notify.sh
#!/bin/bash
#
contact='root@localhost'
notify() {
	mailsubject="$(hostname) to be $1, vip floating"
	mailbody="$(date +'%F %T'): vrrp transition, $(hostname) changed to be $1"
	echo "$mailbody" | mail -s "$mailsubject" $contact
}
case $1 in
master)
	notify master
	;;
backup)
	notify backup
	;;
fault)
	notify fault
	;;
*)
	echo "Usage: $(basename $0) {master|backup|fault}"
	exit 1
	;;
esac

[root@ka1 keepalived]# chmod +x notify.sh 
[root@ka1 keepalived]# scp notify.sh ka2:/etc/keepalived/
[root@ka1 keepalived]# systemctl start keepalived


#测试一下、看看是否收到邮件
[root@ka1 keepalived]# ./notify.sh master
[root@ka1 keepalived]# mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/root": 1 message 1 new
>N  1 root                  Sun Jul 31 14:37  18/671   "ka1 to be master, vip floating"
& 1
Message  1:
From root@ka1.localdomain  Sun Jul 31 14:37:30 2022
Return-Path: <root@ka1.localdomain>
X-Original-To: root@localhost
Delivered-To: root@localhost.localdomain
Date: Sun, 31 Jul 2022 14:37:30 -0400
To: root@localhost.localdomain
Subject: ka1 to be master, vip floating
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
From: root@ka1.localdomain (root)
Status: R

2022-07-31 14:37:30: vrrp transition, ka1 changed to be master

& q
Held 1 message in /var/spool/mail/root
You have mail in /var/spool/mail/root

ka2

[root@ka2 ~]# vim /etc/keepalived/keepalived.conf 

! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ka2    <--名称
   vrrp_mcast_group4 224.100.100.100
}

vrrp_instance VI_1 {
    state BACKUP    <--备份
    interface eth0
    virtual_router_id 66
    priority 80    <--优先级
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.37.100/24 dev eth0 label echo0:1
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

vrrp_instance VI_2 {
    state MASTER    <--主
    interface eth0
    virtual_router_id 88        <--
    priority 100    <--优先级
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 654321    <--
    }
    virtual_ipaddress {
        192.168.37.200/24 dev eth0 label eth0:2    <--
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}


[root@ka2 ~]# systemctl start keepalived

ka1

[root@ka1 keepalived]# vim /etc/sysconfig/keepalived 
# Options for keepalived. See `keepalived --help' output and keepalived(8) and
# keepalived.conf(5) man pages for a list of all options. Here are the most
# common ones :
#
# --vrrp               -P    Only run with VRRP subsystem.
# --check              -C    Only run with Health-checker subsystem.
# --dont-release-vrrp  -V    Dont remove VRRP VIPs & VROUTEs on daemon stop.
# --dont-release-ipvs  -I    Dont remove IPVS topology on daemon stop.
# --dump-conf          -d    Dump the configuration data.
# --log-detail         -D    Detailed log messages.
# --log-facility       -S    0-7 Set local syslog facility (default=LOG_DAEMON)
#
KEEPALIVED_OPTIONS="-D -S 6"    <--


[root@ka1 keepalived]# scp /etc/sysconfig/keepalived ka2:/etc/sysconfig/

[root@ka1 keepalived]# vim /etc/rsyslog.conf 
...
# Save boot messages also to boot.log
local7.*                                                /var/log/boot.log
local6.*                                                /var/log/keepalived.log    <--
...

[root@ka1 keepalived]# scp /etc/rsyslog.conf ka2:/etc/
[root@ka1 keepalived]# systemctl restart keepalived rsyslog

ka2

[root@ka2 ~]# systemctl restart keepalived rsyslog

邮件设置

配置发送邮件的邮箱设置:

vim ~/.mailrc 或 /etc/mail.rc

set from=clark_0932@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=clark_0932@qq.com
set smtp-auth-password=llrtrpiosdttbiha
set smtp-auth=login
set ssl-verify=ignore

rs2

[root@rs2 ~]# vim .mailrc
set from=clark_0932@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=clark_0932@qq.com
set smtp-auth-password=llrtrpiosdttbiha    <--登陆qq邮箱设置--账户--POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务('POP3/SMTP服务'开启)--生成授权码
set smtp-auth=login
set ssl-verify=ignore

#测试、发邮件后qq邮箱会收到邮件
[root@rs2 ~]# echo test | mail -s linux clark_0932@qq.com

KeepAlived支持IPVS

虚拟服务器:

配置参数:

virtual_server IP port | virtual_server fwmark int
{
   ...
   real_server {
   ...
   }
   ...
}

常用参数

  • delay_loop <INT>:检查后端服务器的时间间隔

  • lb_algo rr|wrr|lc|wlc|lblc|sh|dh:定义调度方法

  • lb_kind NAT|DR|TUN:集群的类型

  • persistence_timeout <INT>:持久连接时长

  • protocol TCP:服务协议,仅支持TCP

  • sorry_server <IPADDR> <PORT>:所有RS故障时,备用服务器地址

  • real_server <IPADDR> <PORT>

{
   weight <INT> RS权重
   notify_up <STRING>|<QUOTED-STRING> RS上线通知脚本
   notify_down <STRING>|<QUOTED-STRING> RS下线通知脚本
   HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHEC K { ... }:定义当前主机的健康状态检测方法
}

KeepAlived配置检测

  • HTTP_GET|SSL_GET:应用层检测
HTTP_GET|SSL_GET {
   url {
       path <URL_PATH>:定义要监控的URL
       status_code <INT>:判断上述检测机制为健康状态的响应码
       digest <STRING>:判断为健康状态的响应的内容的校验码
       }
connect_timeout <INTEGER>:连接请求的超时时长
nb_get_retry <INT>:重试次数
delay_before_retry <INT>:重试之前的延迟时长
connect_ip <IP ADDRESS>:向当前RS哪个IP地址发起健康状态检测请求
connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求
bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址
bind_port <PORT>:发出健康状态检测请求时使用的源端口
}    
  • 传输层检测 TCP_CHECK
TCP_CHECK {
   connect_ip <IP ADDRESS>:向当前RS的哪个IP地址发起健康状态检测请求
   connect_port <PORT>:向当前RS的哪个PORT发起健康状态检测请求
   bindto <IP ADDRESS>:发出健康状态检测请求时使用的源地址
   bind_port <PORT>:发出健康状态检测请求时使用的源端口
   connect_timeout <INTEGER>:连接请求的超时时长
}

实验:单主LVS

ka1

[root@ka1 keepalived]# vim keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ka1
   vrrp_mcast_group4 224.100.100.100
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 66
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.37.100/24 dev eth0 label eth0:1
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

virtual_server 192.168.37.100 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    protocol TCP
    sorry_server 127.0.0.1 80

    real_server 192.168.37.10 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
   real_server 192.168.37.20 80 {
        weight 1 
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        } 
    }
}

    
[root@ka1 keepalived]# scp keepalived.conf ka2:/etc/keepalived/
[root@ka1 keepalived]# systemctl restart keepalived

ka2

[root@ka2 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from keepalived@localhost
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id ka2    <--
   vrrp_mcast_group4 224.100.100.100
}

vrrp_instance VI_1 {
    state BACKUP    <--
    interface eth0
    virtual_router_id 66
    priority 80    <--
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        192.168.37.100/24 dev eth0 label eth0:1
    }
    notify_master "/etc/keepalived/notify.sh master"
    notify_backup "/etc/keepalived/notify.sh backup"
    notify_fault "/etc/keepalived/notify.sh fault"
}

virtual_server 192.168.37.100 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    protocol TCP
    sorry_server 127.0.0.1 80

    real_server 192.168.37.10 80 {
        weight 1
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
   real_server 192.168.37.20 80 {
        weight 1 
        HTTP_GET {
            url {
              path /
              status_code 200
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        } 
    }
}    
                        
[root@ka2 ~]# systemctl restart keepalived                        

rs1

[root@rs1 ~]# vim lvs_dr_rs.sh 
#!/bin/bash
vip=192.168.37.100    <--
mask='255.255.255.255'
dev=lo:1
rpm -q httpd &> /dev/null || yum -y install httpd &>/dev/null
service httpd start &> /dev/null && echo "The httpd Server is Ready!"
echo "<h1>`hostname`</h1>" > /var/www/html/index.html

case $1 in
start)
    echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
    ifconfig $dev $vip netmask $mask #broadcast $vip up
    #route add -host $vip dev $dev
    echo "The RS Server is Ready!"
    ;;
stop)
    ifconfig $dev down
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
    echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
    echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
    echo "The RS Server is Canceled!"
    ;;
*)   
    echo "Usage: $(basename $0) start|stop"
    exit 1
    ;;
    esac
    
        
    
[root@rs1 ~]# bash lvs_dr_rs.sh start
[root@rs1 ~]# scp lvs_dr_rs.sh 192.168.37.20:

rs2

[root@rs2 ~]# bash lvs_dr_rs.sh start

ka1和ka2

[root@ka1 ~]# yum install -y ipvsadm 
[root@ka1 ~]# systemctl restart keepalived

route

#配置路由转发功能 
[root@route ~]# vim /etc/sysctl.conf 
net.ipv4.ip_forward = 1 
#启动路由转发 
[root@route ~]# sysctl -p 
net.ipv4.ip_forward = 1


[root@route ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     0.0.0.0         255.255.255.0   U     101    0        0 eth1
192.168.37.0    0.0.0.0         255.255.255.0   U     100    0        0 eth0

client

[root@client ~]$ while : ;do curl 192.168.37.100 ;sleep 0.5;done
<h1>rs1</h1>
<h1>rs2</h1>
<h1>rs1</h1>
<h1>rs2</h1>
^C

ka1

#停止ka1主机的keepalived服务
[root@ka1 ~]# systemctl stop keepalived

#策略没有了
[root@ka1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

ka2

#ka2接管ka1规则、策略等···
[root@ka2 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.37.100:80 rr
  -> 192.168.37.10:80             Route   1      0          15        
  -> 192.168.37.20:80             Route   1      0          15  

[root@ka2 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:42:ff:ea brd ff:ff:ff:ff:ff:ff
    inet 192.168.37.40/24 brd 192.168.37.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 192.168.37.100/24 scope global secondary eth0:1    <--
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe42:ffea/64 scope link 
       valid_lft forever preferred_lft forever    

测试

ka1

[root@ka1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.37.100:80 rr
  -> 192.168.37.10:80             Route   1      0          27        
  -> 192.168.37.20:80             Route   1      0          28 

rs1

[root@rs1 ~]# systemctl stop httpd

ka1

[root@ka1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.37.100:80 rr       
  -> 192.168.37.20:80             Route   1      0          28                                 

rs2

[root@rs2 ~]# systemctl stop httpd    

ka1

'Sorry Server'上线

[root@ka1 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.37.100:80 rr
  -> 127.0.0.1:80                 Route   1      0          4