搭建lvs+keepalivedy双主高可用负载均衡系统

来自linux中国网wiki
跳到导航 跳到搜索

Preface 前言and info

Mon Aug 19 17:13:45 CST 2019

Note

1.
注意脑裂问题 

2. 要添加脚本 ?
vrrp_script jiancha {   #脚本名称
script "/server/scripts/jiancha.sh"  #定义检查的脚本
interval 2  #每隔2秒执行
weight 1    #权重分配数量

track_script {  #执行脚本
jiancha     #脚本名称
}



-Keepalived高可用

常用 负载均衡器

F5
LVS 
nginx
haproxy 


lvs 
目前有三种IP负载均衡技术(VS/NAT、VS/TUN和VS/DR),十种调度算法(rrr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq)

 

常用HA软件

keepalived 
heartbeat 


info

vip 11.240   10.3.10.146(intraip)
 
master  lvs01 148.66.11.27   10.3.10.144  172.23.11.144  lvs+keepalive
backup  lvs02 148.66.11.57   10.3.10.145  172.23.11.145 lvs+keepalive

web1   java-01 172.23.11.141  10.3.10.141  jdk 
web2  java-02  172.23.11.142 10.3.10.142  jdk  
web3  pjava-03 172.23.11.143  10.3.10.143 jdk 

类似的

搭建keepalived+haproxy双主高可用负载均衡系统

Keepalived安装和配置

firewall

#lvs master and slave
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --reload 

开启路由转发功能

分别在lvs master和lvs slave执行如下操作:
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.ip_nonlocal_bind = 1 # 

sysctl -p

#使用LVS的DR模式最好需设置两个arp相关的参数
#开启IP转发功能
sysctl -w net.ipv4.ip_forward=1
#开启允许绑定非本机的IP
sysctl -w net.ipv4.ip_nonlocal_bind = 1

net.ipv4.ip_nonlocal_bind:此参数表示是否允许服务绑定一个本机不存在的IP地址;
使用场景:有些服务需要依赖一个vip才能启动,但是此vip不在本机上,当vip飘移到本机上时才存在;但是服务又需要提前启动,例如haproxy,nginx等代理需要绑定vip时;
0:默认值,表示不允许服务绑定一个本机不存的地址
1:表示允许服务绑定一个本机不存在的地址

开始

Keepalived安装和配置

lvs

ipvs安装
分别在lvs master和lvs slave执行如下操作:
yum -y install ipvsadm
ipvsadm

lsmod | grep ip_vs
ip_vs_rr               12600  2 
ip_vs                 141432  4 ip_vs_rr
nf_conntrack          133053  1 ip_vs
libcrc32c              12644  3 xfs,ip_vs,nf_conntrack

keepalive

keepalived安装

分别在lvs master和lvs slave执行如下操作:
yum -y install keepalived

keepalived配置

lvs master的keepalived配置如下

 cat keepalived.conf
#master
#解说
# lb_algo rr  rr 调试算法为rr 轮询算法
# lb_kind DR  DR模式

! Configuration File for keepalived

global_defs {
  # notification_email {
  #   [email protected]
  #   [email protected]
  #   [email protected]
  # }
  # notification_email_from [email protected]
  # smtp_server 192.168.200.1
  # smtp_connect_timeout 30
   router_id LVS_01
   #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_ipaddress {
       #148.66.11.240/24 dev eth0 label eth0:1 
       10.3.10.146/24 dev eth0 label eth0:1 
    }
}
#http
   virtual_server 10.3.10.146  80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP

    real_server 10.3.10.141 80 {
         weight 1
      TCP_CHECK {
          connect_timeout 3
          nb_get_retry 3
          delay_before_retry 3
          connect_port 80
         }
    }

    real_server 10.3.10.142 80 {
        weight 1
      TCP_CHECK {
          connect_timeout 3
          nb_get_retry 3
          delay_before_retry 3
          connect_port 80
         }
    }

    real_server 10.3.10.143 80 {
       weight 1
     TCP_CHECK {
         connect_timeout 3
         nb_get_retry 3
         delay_before_retry 3
         connect_port 80
         }
    }

}

#https
virtual_server 10.3.10.146 443 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP

    real_server 10.3.10.141 443 {
         weight 1
      TCP_CHECK {
          connect_timeout 3
          nb_get_retry 3
          delay_before_retry 3
          connect_port 443
         }
    }

   real_server 10.3.10.142 443 {
        weight 1
      TCP_CHECK {
          connect_timeout 3
          nb_get_retry 3
          delay_before_retry 3
          connect_port 443
         }
    }

   real_server 10.3.10.143 443 {
      weight 1
     TCP_CHECK {
         connect_timeout 3
         nb_get_retry 3
         delay_before_retry 3
         connect_port 443
         }
    }    
}

#virtual_server 10.3.101.99 46656 {
#    delay_loop 6
#    lb_algo rr
#    lb_kind DR
#    persistence_timeout 50
#    protocol TCP

#    real_server 10.3.101.101 46656 {
#         weight 1
#      TCP_CHECK {
#          connect_timeout 3
#          nb_get_retry 3
#          delay_before_retry 3
#          connect_port 46656
#         }
#    }
#}
#
#virtual_server 10.3.101.99 46657 {
#    delay_loop 6
#    lb_algo rr
#    lb_kind DR
#    persistence_timeout 50
#    protocol TCP
#
#    real_server 10.3.101.151 46657 {
#         weight 1
#      TCP_CHECK {
#          connect_timeout 3
#          nb_get_retry 3
#          delay_before_retry 3
#          connect_port 46657
#         }
#    }
#}
#

lvs salve keepalive配置如下:

 cat keepalived.conf

! Configuration File for keepalived
##salve
global_defs {
  # notification_email {
  #   [email protected]
  #   [email protected]
  #   [email protected]
  # }
  # notification_email_from [email protected]
  # smtp_server 192.168.200.1
  # smtp_connect_timeout 30
   router_id LVS_02
   #vrrp_skip_check_adv_addr
   #vrrp_strict
   #vrrp_garp_interval 0
   #vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        #148.66.11.240/24 dev eth0 label eth0:1 
        10.3.10.146/24 dev eth0 label eth0:1 
    }
}

virtual_server 10.3.10.146 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP

    real_server 10.3.10.141 80 {
         weight 1
      TCP_CHECK {
          connect_timeout 3
          nb_get_retry 3
          delay_before_retry 3
          connect_port 80
          }
     }

    real_server 10.3.10.142 80 {
        weight 1
     TCP_CHECK {
          connect_timeout 3
          nb_get_retry 3
          delay_before_retry 3
          connect_port 80
         }
    }

   real_server 10.3.10.143 80 {
        weight 1
     TCP_CHECK {
          connect_timeout 3
          nb_get_retry 3
          delay_before_retry 3
          connect_port 80
         }
   }
}

#https
virtual_server 10.3.10.146  443 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 50
    protocol TCP

    real_server 10.3.10.141 443 {
         weight 1
      TCP_CHECK {
          connect_timeout 3
          nb_get_retry 3
          delay_before_retry 3
          connect_port 443
          }
     }

    real_server 10.3.10.142 443 {
        weight 1
     TCP_CHECK {
          connect_timeout 3
          nb_get_retry 3
          delay_before_retry 3
          connect_port 443
         }
    }

   real_server 10.3.10.143 443 {
        weight 1
     TCP_CHECK {
          connect_timeout 3
          nb_get_retry 3
          delay_before_retry 3
          connect_port 443
         }
   }
}

#这些端口 干啥的 
#virtual_server 10.3.101.99 46656 {
#    delay_loop 6
#    lb_algo rr
#    lb_kind DR
#    persistence_timeout 50
#    protocol TCP
#
#    real_server 10.3.101.101 46656 {
#         weight 1
#      TCP_CHECK {
#          connect_timeout 3
#          nb_get_retry 3
#          delay_before_retry 3
#          connect_port 46656
#          }
#     }
#}
#
#virtual_server 10.3.101.99 46657 {
#    delay_loop 6
#    lb_algo rr
#    lb_kind DR
#    persistence_timeout 50
#    protocol TCP
#
#    real_server 10.3.101.151 46657 {
#         weight 1
#      TCP_CHECK {
#          connect_timeout 3
#          nb_get_retry 3
#          delay_before_retry 3
#          connect_port 46657
#         }
#    }
#}

keepalived 配置参数 解说

global_defs {
    notification_email {
        [email protected]        #设置报警邮件地址,可以设置多个,每行一个。
        [email protected]       #需开启本机的sendmail服务
        [email protected]
    }
    notification_email_from [email protected]  #设置邮件的发送地址
    smtp_server 127.0.0.1           #设置smtp server地址
    smtp_connect_timeout 30         #设置连接smtp server的超时时间
    router_id LVS_DEVEL             #表示运行keepalived服务器的一个标识。发邮件时显示在邮件主题的信息
}

vrrp_instance VI_1 {
    state MASTER              #指定keepalived的角色,MASTER表示此主机是主服务器,BACKUP表示此主机是备用服务器
    interface eno16777736     #指定HA监测网络的接口
    virtual_router_id 51      #虚拟路由标识,这个标识是一个数字,同一个vrrp实例使用唯一的标识。即同一vrrp_instance下,MASTER和BACKUP必须是一致的
    priority 100              #定义优先级,数字越大,优先级越高,在同一个vrrp_instance下,MASTER的优先级必须大于BACKUP的优先级
    advert_int 1              #设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒
    authentication {          #设置验证类型和密码
        auth_type PASS        #设置验证类型,主要有PASS和AH两种
        auth_pass 1111        #设置验证密码,在同一个vrrp_instance下,MASTER与BACKUP必须使用相同的密码才能正常通信
    }
    virtual_ipaddress {       #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个
        172.16.122.100
    }
}

virtual_server 172.16.122.100 80 {     #设置虚拟服务器,需要指定虚拟IP地址和服务端口,IP与端口之间用空格隔开
    delay_loop 6                        #设置运行情况检查时间,单位是秒
    lb_algo rr                          #设置负载调度算法,这里设置为rr,即轮询算法
    lb_kind DR                          #设置LVS实现负载均衡的机制,有NAT、TUN、DR三个模式可选
    nat_mask 255.255.255.0
    persistence_timeout 0               #会话保持时间,单位是秒。这个选项对动态网页是非常有用的,为集群系统中的session共享提供了一个很好的解决方案。
                                        #有了这个会话保持功能,用户的请求会被一直分发到某个服务节点,直到超过这个会话的保持时间。
                                        #需要注意的是,这个会话保持时间是最大无响应超时时间,也就是说,用户在操作动态页面时,如果50秒内没有执行任何操作
                                        #那么接下来的操作会被分发到另外的节点,但是如果用户一直在操作动态页面,则不受50秒的时间限制
    protocol TCP                        #指定转发协议类型,有TCP和UDP两种

    real_server 172.16.122.193 80 {     #配置服务节点1,需要指定real server的真实IP地址和端口,IP与端口之间用空格隔开
        weight 1                        #配置服务节点的权值,权值大小用数字表示,数字越大,权值越高,设置权值大小可以为不同性能的服务器
                                        #分配不同的负载,可以为性能高的服务器设置较高的权值,而为性能较低的服务器设置相对较低的权值,这样才能合理地利用和分配系统资源
        TCP_CHECK {                     #realserver的状态检测设置部分,单位是秒
            connect_timeout 3           #表示3秒无响应超时
            nb_get_retry 3              #表示重试次数
            delay_before_retry 3        #表示重试间隔
            connect_port 80

realserver的配置

三台web服务器都要执行下面脚本:


#不然就改成 255.255.255.0
#netmask 是多少   直接抄就行 [email protected] 1.9 172.23.101.101

cat /etc/rc.d/init.d/realserver.sh

#!/bin/bash
    SNS_VIP=148.66.11.240
    #/etc/rc.d/init.d/functions
    case "$1" in
    start)
        ifconfig lo:0 $SNS_VIP netmask 255.255.255.252 broadcast $SNS_VIP
        /sbin/route add -host $SNS_VIP dev lo:0
        echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
        echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
        echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
        echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
        sysctl -p >/dev/null 2>&1
        echo "RealServer Start OK"
        ;;
    stop)
        ifconfig lo:0 down
        route del $SNS_VIP >/dev/null 2>&1
        echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
        echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
        echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
        echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
        echo "RealServer Stoped"
        ;;
    *)
        echo "Usage: $0 {start|stop}"
        exit 1
    esac
exit 0

chmod u+x /etc/rc.d/init.d/realserver.sh
/etc/rc.d/init.d/realserver.sh start

ifconfig #得到 

lo:0: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 148.66.11.240  netmask 255.255.255.252
        loop  txqueuelen 1000  (Local Loopback)



# vi /etc/rc.local #有时会不生效么 
/etc/rc.d/init.d/realserver.sh start


防火墙配置 允许vrrp的组播

Lvs两台服务器防火墙配置: in and out 
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 \
  --in-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
  
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 \
  --out-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT

firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload


启动keepalived并进行测试

systemctl start firewalld
systemctl enable keepalived
systemctl start keepalived
systemctl stop firewalld
ps -ef |grep keepalived

注:重启keepalived服务后,lvs master本地网卡添加了eth0:1的ip,即vip地址
配置心得:如果vip访问不了,先重启服务器,开启keepalived服务,然后才关闭防火墙 


查看防火墙配置:
iptables -L OUTPUT_direct --line-numbers
iptables -L INPUT_direct --line-numbers
删除防火墙配置:
firewall-cmd --direct --permanent --remove-rule ipv4 filter INPUT 0 \
  --in-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
  
firewall-cmd --direct --permanent --remove-rule ipv4 filter OUTPUT 0 \
  --out-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --zone=public --remove-port=80/tcp --permanent
firewall-cmd --reload

总结:
当 MASTER 服务器无法提供服务时,VIP 会在 MASTER 上自动移除,BACKUP 服务器会提升为 MASTER 状态,绑定 VIP 、接管服务。
当 MASTER 修复加入网络后,会自动抢回 VIP ,成为 MASTER 身份。
当后端提供服务nginx服务挂起时,会自动切换至其它nginx服务器。

检查

检查主keepalived 启动后的配置情况
ip add |grep eth0
如果网卡下出现148.66.11(VIP)说明主已经启动成功


检查备keepalived 启动后的配置情况
ip add |grep eth0
备服务器的网卡下没有出现148.66.11((VIP)的ip,说明备服务正常
注:如果这里也出现了VIP,那么说明裂脑了,需要检查防火墙是否配置正确;是否允许了vrrp的多播通讯

#lvs master 
tail -f /var/log/messages


-lvs01 keepalived]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  148.66.11:80 rr persistent 50
TCP  148.66.11:443 rr persistent 50 

测试负载均衡

curl -H 'Host:a.com' http://外网vip

nginx 3


故障模拟

关闭keepalived

#
lvs01 keepalived]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.3.10.146:80 rr persistent 50
  -> 10.3.10.141:80               Route   1      0          0         
  -> 10.3.10.142:80               Route   1      0          1         
  -> 10.3.10.143:80               Route   1      0          2         
TCP  10.3.10.146:443 rr persistent 50

lvs01 keepalived]# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 10.3.10.144/24 brd 10.3.10.255 scope global noprefixroute eth0
    inet 10.3.10.146/24 scope global secondary eth0:1 #vip



systemctl stop keepalived

ip a | grep eth0 #这个时候vip去了lvs slave 
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 10.3.10.144/24 brd 10.3.10.255 scope global noprefixroute eth0


lvs02 keepalived]# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 10.3.10.145/24 brd 10.3.10.255 scope global noprefixroute eth0
    inet 10.3.10.146/24 scope global secondary eth0:1
 
 master 启动起来 ,就会抢占 
 

关闭nginx

[email protected]:~ % curl -H 'Host:a.com' http://148.66.11.240
nginx 3 

故意关掉 nginx 3 然后再访问  nginx 关闭了 会有一会儿间断 
[email protected]:~ % curl -H 'Host:a.com' http://148.66.11.240
curl: (7) Failed to connect to 148.66.11.240 port 80: Connection refused
[email protected]01:~ % curl -H 'Host:a.com' http://148.66.11.240
nginx 2 

nginx安装

三台 real
https://nginx.org/en/linux_packages.html#RHEL-CentOS
添加官方源太新了 1.16 

yum install nginx -y #这样有各部module 
#nginx.x86_64 1:1.12.2-3.el7 他是源码1.14 

防火墙设置:
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp

firewall-cmd --reload
firewall-cmd --list-all-zones


systemctl start nginx
 systemctl enable  nginx
systemctl restart nginx

cd /etc/nginx/

cp nginx.conf nginx.conf20190819


server_name  a.com;
        #server_name  _;
        root         /usr/share/nginx/html; #这里的内容改一下以前区别
        
        
        然后  a.com  a 到vip 或者 绑host

curl -H 'Host:a.com' http://10.3.10.141

other


总结:前提vip地址已经映射到外网地址,依次停止某一台服务(master keepalived,backup keepalived,101 nginx,151 nginx),查看访问http://148.6.11.10/是否正常。
5.8、防火墙配置
Lvs两台服务器防火墙配置:
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 \
  --in-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
  
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 \
  --out-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT

firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload

nginx两台服务器防火墙配置:
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload

查看防火墙配置:
iptables -L OUTPUT_direct --line-numbers
iptables -L INPUT_direct --line-numbers

troubleshooting

vip 老是访问不了 原来要用 那个内网的vip哦  最后打开文档才看到呢 

keepalived配置学习,解决vip无法ping通,虚拟服务器端口无法访问的问题


虚拟路由器冗余协议【原理篇】VRRP详解


centos7 keepalived 主备通信 防火墙vrrp 协议

keepalived 防火墙配置

linux防火墙下允许keepalived组播

see also

apache+Keepalived实现站点高可用

https://www.keepalived.org/LVS-NAT-Keepalived-HOWTO.html

LVS+Keeplive 负载均衡


LVS+Keepalived+Nginx+Tomcat高可用负载均衡集群配置

LVS+KeepAlived+Nginx高可用实现方案

linux搭建LVS+keepalive+nginx实现集群高性能负载均衡配置详解

CentOS7 搭建LVS+keepalived负载均衡(二)


Keepalived无法绑定VIP故障排查经历

LVS+Keepalived+Nginx实现HA