Keepalived本质就是为ipvs服务的,它也不须要共享存储。IPVS其实就是一些规则,Keepalived主要的任务就是去调用ipvsadm命令,来生成规则,并自动实现将用户须要访问的地址转移到可用LVS节点实现。因此keepalive的高可用是属于具备很强针对性的高可用,它和corosync这种通用性HA方案不一样。html
Keepalived的主要目的就是它自身启动为一个服务,它工做在多个LVS主机节点上,当前活动的节点叫作Master备用节点叫作Backup,Master会不停的向Backup节点通告本身的心跳,这种通告是基于VRRP协议的。Backup节点一旦接收不到Master的通告信息,它就会把LVS的VIP拿过来,而且把ipvs的规则也拿过来,在本身身上生效,从而替代Master节点。linux
Keepalived除了能够监控和转移LVS资源以外,它还能够直接配置LVS而不须要直接使用ipvsadm命令,由于它能够调用,也就是说在LVS+KEEPALIVED模型中,你全部的工做在Keepalived中配置就能够了,并且它还有对后端应用服务器健康检查的功能。算法
直接一句话Keepalived就是VRRP协议的实现,该协议是虚拟冗余路由协议。后端
那么这个VRRP协议是干吗用呢?传统上来讲咱们经过一个路由器上网,若是故障那就不能用了,若是使用2个路由器,有一个故障你就须要手动的设置客户端切换到另外的路由器上,或者使用ARP客户端也能够实现,但总之部署比较麻烦不利于管理,就像下图:缓存
有没有一种办法能够自动转移而省去手动配置呢?咱们就能够经过VRRP协议来实现路由器的故障转移。以下图:bash
这里有个问题,VRRP提供一个VIP,它能够来设定那个路由器是活动节点,而后出现故障进行切换,VIP也随之对应到新的路由器上,可是内网是用过MAC地址来寻址的,虽然VIP对应到了新的路由器上,但是MAC变了,客户端的ARP表也没有更新,因此仍是用不了,为了解决这个问题VRRP不但提供VIP还提供VMAC地址,这个VMAC地址是VRRP单独申请的,你们均可以正常使用。服务器
故障切换的时候虽然改变了后端路由器,可是因为客户端使用的是VIP和VMAC地址,这样就不会有任何影响了。curl
因此Keepalived就是在Linux系统上提供了VRRP功能,固然还提供了服务监控功能,好比监控后端服务器的健康检查、LVS服务可用性检查。jsp
VRRP的工做过程是这样的:tcp
VRRP还支持认证,就是为了防止随意一个VRRP设备加入到当前的虚拟路由组离来,它提供无认证、简单8位字符串认证和MD5认证(该认证方式Keepalive不支持)。
Keepalived启动后之后会有一个主进程Master,它会生成还有2个子进程,一个是VRRP Stack负责VRRP(也就是VRRP协议的实现)、一个是Checkers负责IPVS的后端的应用服务器的健康检查,当检测失败就会调用IPVS规则删除后端服务器的IP地址,检测成功了再加回来。当检测后端有失败的状况可使用SMTP通知管理员。另外VRRP若是检测到另一个Keepalive失败也能够经过SMTP通知管理员。
Control Plane:这个就是主进程,主进程的功能是分析配置文件,读取、配置和生效配置文件,指挥那2个子进程工做。
WatchDog:看门狗,这个是Linux系统内核的一个模块,它的做用是帮助主进程盯着那2个子进程,由于主进程并不负责具体工做,具体工做都是子进程完成的。若是子进程挂了,那Keepalived就不完整了,因此那2个子进程会按期的向主进程打开的一个内部Unix Socket文件写心跳信息。若是有某个子进程不写信息了,它就会重启子进程,主进程就是让WatchDog来监控子进程的。下面咱们就使用Keepalive来作LVS的高可用讲解。关于后端服务器上的设置我这里就不说了请看另一篇博文。
服务器 | IP地址 | 角色 |
---|---|---|
Srv01 | 172.16.42.100 VIP: 172.16.42.111 |
LVS+Keepalive |
Srv02 | 172.16.42.101 VIP: 192.168.100.1 |
LVS+Keepalive |
Srv03 | 172.16.42.102 VIP: 172.16.42.111 |
Nginx |
Srv04 | 172.16.42.103 VIP: 172.16.42.111 |
Nginx |
禁用SElinux、清除iptables规则、关闭防火墙。就算因某种缘由不能清除iptables规则,那么你须要增长一条规则放行多播
各个节点时间同步,启用时间同步服务systemctl start chronyd
确保Keepalive使用的网卡开启了多播,以下图:
若是没有开启,可使用该命令打开ip link set multicast on dev ens33
,ens33是网卡名称。
之间经过yum安装便可yum install -y keepalived
。我这里使用的是阿里云的源,它默认就在里面,以下图:
在2个节点都安装。
文件 | 说明 |
---|---|
/usr/sbin/keepalived | 二进制程序 |
/etc/keepalived/keepalived.conf | 配置文件 |
/usr/lib/systemd/system/keepalived.service | 服务文件 |
# 全局配置 global_defs { # 邮件通知信息 notification_email { # 定义收件人 acassen@firewall.loc } # 定义发件人 notification_email_from Alexandre.Cassen@firewall.loc # SMTP服务器地址 smtp_server 192.168.200.1 smtp_connect_timeout 30 # 路由器标识,通常不用改,也能够写成每一个主机本身的主机名 router_id LVS_DEVEL # VRRP的ipv4和ipv6的广播地址,配置了VIP的网卡向这个地址广播来宣告本身的配置信息,下面是默认值 vrrp_mcast_group4 224.0.0.18 vrrp_mcast_group6 ff02::12 } # 定义用于实例执行的脚本内容,好比能够在线下降优先级,用于强制切换 vrrp_script SCRIPT_NAME { } # 一个vrrp_instance就是定义一个虚拟路由器的,实例名称 vrrp_instance VI_1 { # 定义初始状态,能够是MASTER或者BACKUP state MASTER # 工做接口,通告选举使用哪一个接口进行 interface ens33 # 虚拟路由ID,若是是一组虚拟路由就定义一个ID,若是是多组就要定义多个,并且这个虚拟 # ID仍是虚拟MAC最后一段地址的信息,取值范围0-255 virtual_router_id 51 # 使用哪一个虚拟MAC地址 use_vmac XX:XX:XX:XX:XX # 监控本机上的哪一个网卡,网卡一旦故障则须要把VIP转移出去 track_interface { eth0 ens33 } # 若是你上面定义了MASTER,这里的优先级就须要定义的比其余的高 priority 100 # 通告频率,单位为秒 advert_int 1 # 通讯认证机制,这里是明文认证还有一种是加密认证 authentication { auth_type PASS auth_pass 1111 } # 设置虚拟VIP地址,通常就设置一个,在LVS中这个就是为LVS主机设置VIP的,这样你就不用本身手动设置了 virtual_ipaddress { # IP/掩码 dev 配置在哪一个网卡 192.168.200.16/24 dev eth1 # IP/掩码 dev 配置在哪一个网卡的哪一个别名上 192.168.200.17/24 dev label eth1:1 } # 虚拟路由,在须要的状况下能够设置lvs主机 数据包在哪一个网卡进来从哪一个网卡出去 virtual_routes { 192.168.110.0/24 dev eth2 } # 工做模式,nopreempt表示工做在非抢占模式,默认是抢占模式 preempt nopreempt|preempt # 若是是抢占默认则能够设置等多久再抢占,默认5分钟 preempt delay 300 # 追踪脚本,一般用于去执行上面的vrrp_script定义的脚本内容 track_script { } # 三个指令,若是主机状态变成Master|Backup|Fault以后会去执行的通知脚本,脚本要本身写 notify_master "" notify_backup "" notify_fault "" } # 定义LVS集群服务,能够是IP+PORT;也能够是fwmark 数字,也就是防火墙规则 # 因此经过这里就能够看出来keepalive天生就是为ipvs而设计的 virtual_server 10.10.10.2 1358 { delay_loop 6 # 算法 lb_algo rr|wrr|lc|wlc|lblc|sh|dh # LVS的模式 lb_kind NAT|DR|TUN # 子网掩码,这个掩码是VIP的掩码 nat_mask 255.255.255.0 # 持久链接超时时间 persistence_timeout 50 # 定义协议 protocol TCP # 若是后端应用服务器都不可用,就会定向到那个服务器上 sorry_server 192.168.200.200 1358 # 后端应用服务器 IP PORT real_server 192.168.200.2 1358 { # 权重 weight 1 # MSIC_CHECK|SMTP_CHEKC|TCP_CHECK|SSL_GET|HTTP_GET这些都是 # 针对应用服务器作健康检查的方法 MISC_CHECK {} # 用于检查SMTP服务器的 SMTP_CHEKC {} # 若是应用服务器不是WEB服务器,就用TCP_CHECK检查 TCP_CHECK { # 向哪个端口检查,若是不指定默认使用上面定义的端口 connect_port <PORT> # 向哪个IP检测,若是不指定默认使用上面定义的IP地址 bindto <IP> # 链接超时时间 connect_timeout 3 } # 若是对方是HTTPS服务器就用SSL_GET方法去检查,里面配置的内容和HTTP_GET同样 SSL_GET {} # 应用服务器UP或者DOWN,就执行那个脚本 notify_up "这里写的是路径,若是脚本后有参数,总体路径+参数引发来" notify_down "/PATH/SCRIPTS.sh 参数" # 使用HTTP_GET方法去检查 HTTP_GET { # 检测URL url { # 具体检测哪个URL path /testurl/test.jsp # 检测内容的哈希值 digest 640205b7b0fc66c1ea91c463fac6334d # 除了检测哈希值还能够检测状态码,好比HTTP的200 表示正常,两种方法二选一便可 status_code 200 } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } # 向哪个端口检查,若是不指定默认使用上面定义的端口 connect_port <PORT> # 向哪个IP检测,若是不指定默认使用上面定义的IP地址 bindto <IP> # 链接超时时间 connect_timeout 3 # 尝试次数 nb_get_retry 3 # 每次尝试之间间隔几秒 delay_before_retry 3 } } real_server 192.168.200.3 1358 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }
Srv01上的keepalived.conf
global_defs { notification_email { acassen@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id srv01 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.42.111/24 brd 172.16.42.111 dev ens33 label ens33:0 } preempt delay 60 }
Srv02上的keepalived.conf,惟一不一样的就是state、priority以及router_id。
global_defs { notification_email { acassen@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id srv02 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 90 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.42.111/24 brd 172.16.42.111 dev ens33 label ens33:0 } preempt delay 60 }
启动2个节点,启动后会自动配置ens33:0这个子接口的虚拟IP
在主节点上你经过systemctl status keepalived
看不到它究竟是什么角色,不过在BACKUP节点上你能够看到,可是你在主节点日志中cat /var/log/message
里能够看到Srv01进入到MASTER状态,以下图:
查看Srv02的状态
那么你经过中止Srv01上的keepalived服务就看到MASTER会被转移到Srv02上。
使用该命令查看VRRP通告tcpdum -i ens33 -nn host 224.0.0.18
,你在2台主机都会看到相同的信息。
Srv01使用真实物理IP对该地址进行发送通告,那么Srv02也会收到,若是Srv01宕机,那么Srv02就会使用本身的物理IP向该地址发送通告,因为Srv01已经宕机那么此时Srv02的优先级就是最高的,因此Srv02就变成了MASTER。
这里只是用了LVS来讲明如何配置Keepalived,若是要看完整内容请移步使用Keepalived构建LVS高可用集群
在keepalived.conf文件中增长下面的内容,2台服务器增长的内容一致,因此这里就写一份。
virtual_server 172.16.42.111 80 { delay_loop 6 lb_algo rr lb_kind DR nat_mask 255.255.255.0 persistence_timeout 0 protocol TCP sorry_server 192.168.200.200 1358 # 后端应用服务器 IP PORT real_server 172.16.42.102 80 { weight 1 # 应用服务器UP或者DOWN,就执行那个脚本 notify_up "/usr/local/notify.sh up" notify_down "/usr/local/notify.sh down" HTTP_GET { # 检测URL url { path /index.html # 除了检测哈希值还能够检测状态码,好比HTTP的200 表示正常,两种方法二选一便可 status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 172.16.42.103 80 { weight 1 # 应用服务器UP或者DOWN,就执行那个脚本 notify_up "/usr/local/notify.sh up" notify_down "/usr/local/notify.sh down" HTTP_GET { # 检测URL url { path /index.html # 除了检测哈希值还能够检测状态码,好比HTTP的200 表示正常,两种方法二选一便可 status_code 200 } connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }
这里的notify_up|down脚本我写的很简单就是为了使用一下这个功能,内容以下:
#!/bin/bash # 不一样的是2个主机上的echo部分不同,由于主机名不一样。 if [ $1 == "up" ]; then echo "Srv02 is UP" > /tmp/notify.txt elif [ $1 == "down" ]; then echo "Srv02 is DOWN" > /tmp/notify.txt fi
重启Keepalived服务以后你就能够经过ipvsadm -Ln
查看ipvs规则了,这些规则在2台服务器上都会有,以下图:
测试访问
使用下面的命令快速访问for i in {1..20}; do curl http://172.16.42.111/ | grep "Srv0" --color ; done
能够看到2台服务器交替,由于咱们使用的rr调度算法。
连续访问VIP,而后中止Srv01上面的keepalived服务,这就意味着Srv01也就是失去了VIP,而后观察请求状况以及是否触发以前设定的脚本。
在Srv01上查看脚本执行状况
查看Srv02上面的日志