keepalived简介
lvs在我之前的博客《高负载集群实战之lvs负载均衡-技术流ken》中已经进行了详细的介绍和应用,在这里就不再赘述。这篇博文将把lvs与keepalived相结合使用,在实际工作中搭建高可用,高负载,高性能的服务器集群。
“Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。”
keepalived的主要功能
1. healthcheck
检查后端节点是否正常工作
如果发现后端节点异常,就将该异常节点从调度规则中删除;
如果发现后端的异常节点恢复正常了,就将该节点重新加入到调度规则中;
2. failover
是对调度器的主节点做健康检测。
将备用节点升级为主节点
接管主节点上的资源(vip、lvs规则)
keepalived实现故障切换的原理
1.keepalived是基于vrrp写于实现的故障切换
2.正常情况下,主节点会每隔一段时间向备节点发送一个心跳信息,这个就是告诉备节点自己正常
当主节点发生故障,那么备节点无法接收都心跳信息,就认定主节点故障,那么就会接收主节点的业务和资源(包括vip)
当主节点又恢复的时候,那么备节点释放所接收到资源和业务
简单说说vrrp协议
1. VRRP((Virtual Router Redundancy Protocol),虚拟路由冗余协议,为了解决静态路由的单点故障问题
2. VRRP的工作机制是基于竞选机制选择一个路由来完成任务处理
3. VRRP协议是通过发送多播数据包实现竞选的(Multicat)
4. 竞选出来主节点会一直发送广播包,backup节点一直监听这些广播包(处于监听状态)
5. 当备用节点无法接收到广播包的是时候,就会重新进行竞选,选出一个新的节点作为主节点
keepalived可以完成如下工作
1. 自动生成vip(vip给用户提供服务)
2. 自动配置lvs规则
3. 可以实现各种服务的高可用
4. failover的时候,做vip的漂移
keepalived的配置文件
第一段:global_defs,全局配置段 global_defs { notification_email { 237745635@qq.com } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id id1 <<< 当前主机的ID值,这个值必须是唯一的 } 第二段:vrrp_instance,实例配置段(虚拟服务段) 【该段是定义虚拟服务的vip等信息】 vrrp_instance VI_1 { <<< 指定实例的名称 state MASTER <<< 指定节点的状态,MASTER表示主,BACKUP表示备用节点 interface eth0 <<< 指定将VIP绑定在哪个网卡上 virtual_router_id 51 <<< 虚拟路由ID,用于标识哪些个节点是一组,同一组的主机的虚拟id需要相同 priority 100 <<< 指定该节点的优先级(主这节点的优先级大于备节点) advert_int 1 <<< 指定备节点在几秒之内没有接收到主节点的心跳信息,就接管其业务和资源 authentication { <<< 指定keepalived集群中各个主备节点做认证的方式 auth_type PASS auth_pass 1111 } virtual_ipaddress { <<< 指定用于提供服务的ip地址(也就是VIP) 10.220.5.233 } } 第三段:virtual_server,虚拟主机配置段 【该段主要是给lvs来用,用来定义后端RS节点】 virtual_server 10.220.5.222 80 { #指定实例对应的VIP delay_loop 6 # 对后端节点做健康检查的时间间隔 lb_algo rr # 指定负载均衡调度算法 lb_kind DR # 指定所使用的lvs模型 nat_mask 255.255.255.0 persistence_timeout 50 # 同一IP的请求50秒内被分配到同一台真实主机 protocol TCP # 用TCP协议对真实节点做健康检查 real_server 10.220.5.190 80 { # 指定一台真实服务器的IP和端口 weight 1 # 设置权重 TCP_CHECK { # 用建立tcp连接的方式做健康检测 connect_timeout 10 # 设置建立tcp连接的超时时间 delay_before_retry 3 # 超时后多久重试 nb_get_retry 3 # 重试次数 connect_port 80 # 健康检查使用的端口号 } } real_server 10.220.5.191 80 { weight 1 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } }
修改配置文件需要注意的问题
1. 实例可以有一个,也可以有多个
2. 单实例中必须相同的配置
vrrp_instance VI_1
virtual_router_id 51
auth_type PASS
auth_pass 1111
virtual_ipaddress
3. 单实例中必须不相同的配置
router_id id1
state MASTER
priority 100
指定日志保存方式和位置
1. 修改keepalived的配置 [root@ken ~]# cat /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 -d -S 0" #KEEPALIVED_OPTIONS="-D" 2. 修改系统日志配置文件 [root@ken ~]# echo "local0.* /var/log/ka.log" >>/etc/rsyslog.conf 3. 重启服务 [root@ken ~]# systemctl restart rsyslog [root@ken ~]# systemctl restart keepalived 日志 级别:指定触发日志的事件的重要等级 日志设施:指定将日志记录在什么位置
keepalived对RS做健康检查的方式
1. HTTP_GET:向后端的RS发送http请求,如果请求成功,说明后端节点正常(RS是web服务的时候比较常用) 2. TCP:尝试与后端RS建立TCP连接,如果成功,说明后端节点正常 【仅仅是检查RS系统是否正常工作,不能检查具体的业务】 3. SMTP:对邮件服务器做健康检测 4. MISC:通过脚本的方式实现健康检测 TCP健康检测方式举例 TCP_CHECK { # 通过TcpCheck判断RealServer的健康状态 connect_timeout 10 # 连接超时时间 nb_get_retry 3 # 重连次数 delay_before_retry 3 # 重连时间间隔 connect_port 80 # 检测端口 } HTTP_GET健康检测方式举例 HTTP_GET { url { path check/t.html # 检查的uri地址 digest 1362a91278f0 # 用keepalived自带的genhash生成,genhash -s 192.168.64.8 -p 80 -u http://192.168.64.8/index.html connect_timeout 3 # 链接超时时间 nb_get_retry 3 # 重连次数 delay_before_retry 3 # 重连时间间隔 connect_port 6500 # 检测端口 } MISC健康检测方式举例 MISC_CHECK { misc_path "/tmp/check.sh http://1.2.3.4:80/c/200.jsp" # 调用外部程序或者脚本的路径和参数 misc_timeout 10 # 脚本执行的超时时间 misc_dynamic # 动态权重标志。 # 脚本返回0 则检测成功,权重不变 # 返回1表示失败,权重设置为0 }
keepalsived+lvs服务器集群实战
1.环境准备
centos7.5
VIP:172.20.10.11/28
客户端IP:172.20.10.3/28
KEEPALIVED+LVS1服务器端IP:172.20.10.2/28
KEEPALIVED+LVS2服务器端IP:172.20.10.5/28
WEB1服务器端IP:172.20.10.8/28
WEB2服务器端IP:172.20.10.9/28
2.关闭安全服务
[root@ken ~]# setenforce 0 [root@ken ~]# systemctl stop firewalld [root@ken ~]# iptables -F
3.配置KEEPALIVED+LVS1服务器端
相当的服务器配置需要保持相同。接下来的配置你需要配置两遍,即在每个服务端都需要配置一遍。
安装ipvsadm
[root@ken ~]# yum install ipvsadm -y
安装keepalived
[root@ken ~]# yum install keepalived -y
配置主服务器端keepalived
! 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 id1 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 150 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.20.10.11/28 } } virtual_server 172.20.10.11 80 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 50 protocol TCP real_server 172.20.10.8 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 172.20.10.9 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }
配置好之后可以把这个文件使用scp传输到另外一台服务器上面
[root@ken ~]# scp /etc/keepalived/keepalived.conf 172.20.10.5:/etc/keepalived/keepalived.conf root@172.20.10.5's password: keepalived.conf 100% 1116 669.7KB/s 00:00
配置从服务器端keepalived
! 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 id2 vrrp_skip_check_adv_addr vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_instance VI_1 { state BACKUP interface eth0 interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.20.10.11/28 } } virtual_server 172.20.10.11 80 { delay_loop 6 lb_algo rr lb_kind DR persistence_timeout 50 protocol TCP real_server 172.20.10.8 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 172.20.10.9 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }
4.重启keepalived
[root@ken ~]# systemctl restart keepalied
5.检查ipvsadm
[root@ken ~]# ipvsadm -L -n --stats IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes -> RemoteAddress:Port TCP 172.20.10.11:80 7 84 0 22131 0 -> 172.20.10.8:80 4 69 0 21009 0 -> 172.20.10.9:80 3 15 0 1122 0
6.检查VIP
检查主服务器端
[root@ken ~]# 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 UNKNOWN group default qlen 1000 link/ether 00:0c:29:2d:5b:b8 brd ff:ff:ff:ff:ff:ff inet 172.20.10.2/28 brd 172.20.10.15 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet 172.20.10.11/28 scope global secondary eth0 #VIP现在在主服务器端 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe2d:5bb8/64 scope link valid_lft forever preferred_lft forever
检查从服务器端
[root@ken ~]# 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 UNKNOWN group default qlen 1000 link/ether 00:0c:29:a5:e9:a4 brd ff:ff:ff:ff:ff:ff inet 172.20.10.5/28 brd 172.20.10.15 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fea5:e9a4/64 scope link valid_lft forever preferred_lft forever
6.配置web服务器端
1.下载apache
[root@ken ~]# yum install httpd -y
2.准备测试页面
[root@ken ~]# echo "this is 172.20.10.8 for test" >/var/www/html/index.html
3.启动apache
[root@ken ~]# systemctl restart httpd [root@ken ~]# ss -tnl |grep 80 LISTEN 0 128 :::80 :::*
4.绑定VIP
[root@ken ~]# ip a a 172.20.10.11/32 dev lo:0
5.arp抑制
1 2 3 4 | [root@ken ~]# echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore [root@ken ~]# echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore [root@ken ~]# echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce [root@ken ~]# echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce |
浏览器测试
确认每台服务器每项服务重启之后,再次关闭每台服务器
关闭keepalived服务器端的防火墙规则
[root@ken ~]# iptables -F
注意:
keepalived 在启动后如果参数配置不当,会在iptables中自动添加一条DROP VIP的规则。这里的一些参数可能会造成这个问题。
1、在配置中添加了strict 或 noaccept参数。
2、在全局配置下使用了vrrp_strict 参数。此参数为严格控制VRRP协议,不支持单播模式,注释掉此选项,将不会默认添加DROP规则。
输入VIP地址
测试成功!
进行刷新测试
测试成功!
关闭一台172.20.10.8web服务器进行测试
[root@ken ~]# systemctl stop httpd
查看ipvsadm规则
[root@ken ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.20.10.11:80 rr -> 172.20.10.9:80 Route 1 0 0
已自动移除172.20.10.8服务器
测试成功!
关闭172.20.10.2 keepalived主服务器进行测试
[root@ken ~]# systemctl stop keepalived
查看keepalived主服务器端ipvsadm规则
[root@ken ~]# ipvsadm -L -n IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn
查看keepalived主服务器端VIP
[root@ken ~]# 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 UNKNOWN group default qlen 1000 link/ether 00:0c:29:2d:5b:b8 brd ff:ff:ff:ff:ff:ff inet 172.20.10.2/28 brd 172.20.10.15 scope global noprefixroute eth0 valid_lft forever preferred_lft forever #已经没有VIP inet6 fe80::20c:29ff:fe2d:5bb8/64 scope link valid_lft forever preferred_lft forever
查看从服务器ipvsadm规则
[root@ken ~]# ipvsadm -L -n --stats IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes -> RemoteAddress:Port TCP 172.20.10.11:80 0 0 0 0 0 -> 172.20.10.9:80 0 0 0 0 0
从服务器端已经自动继承主服务器端ipvsadm规则
查看从服务器端是否有VIP
[root@ken ~]# 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 UNKNOWN group default qlen 1000 link/ether 00:0c:29:a5:e9:a4 brd ff:ff:ff:ff:ff:ff inet 172.20.10.5/28 brd 172.20.10.15 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet 172.20.10.11/28 scope global secondary eth0 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fea5:e9a4/64 scope link valid_lft forever preferred_lft forever
VIP已经自动继承到从服务器端
测试完成!