Keepalived的做用是检测服务器状态,若是一台服务器宕机或者出现其余故障致使当前服务器不可用,keep alived就会检测到并将故障的服务器从系统中剔除,同时使用备用服务器替代该服务器的工做,当服务器工做正常后Keepalived自动将服务器加入到服务器群中,这些工做所有自动完成,不须要人工干涉,须要人工作的只是修复故障的服务器。
Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了能够实现高可用的VRRP功能。所以,Keepalived除了可以管理LVS软件外,还能够做为其余服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件。
Keepalived软件主要是经过VRRP协议实现高可用功能的。VRRP是Virtual Router RedundancyProtocol(虚拟路由器冗余协议)的缩写,VRRP出现的目的就是为了解决静态路由单点故障问题的,它可以保证当个别节点宕机时,整个网络能够不间断地运行。
因此,Keepalived 一方面具备配置管理LVS的功能,同时还具备对LVS下面节点进行健康检查的功能,另外一方面也可实现系统网络服务的高可用功能。nginx
(1)、管理LVS软件
(2)、基于VRRP实现高可用
(3)、健康检查,故障切换docker
分层 | 功能 | 相关协议 |
---|---|---|
应用层 | 网络服务和最终用户的一个接口 | TFTP,HTTP,SNMP,DNS,FTP,SMTP,TELNET |
表示层 | 数据的表示、安全、压缩 | 无协议 |
会话层 | 会话的创建、管理、停止 | 无协议 |
传输层 | 定义传输数据的协议端口号,以及流控和差错校验 | TCP,UDP |
网络层 | 进行逻辑地址寻址,实现不一样网络之间的路径选择 | IP,ICMP,RIP,OSPF,BGP,IGMP |
数据链路层 | 创建逻辑链接、硬件地址寻址、差错校验等功能 | SLIP,CSLIP,PPP,ARP,RARP,MTU |
物理层 | 创建、链接、断开物理链接 | ISO2110,IEEE802,IEEE802.2 |
Keepalived工做在TCP/IP协议的IP层、TCP层、应用层,既Layer 3/4/5;
Layer3:当Keepalived工做在这层时,它会按期向服务器群中的服务器发送ICMP包,若是发现某台服务器IP没有激活就会报告这台服务器失效,而且将其从服务器群剔除。Layer3的是以服务器IP地址是否有效做为判断是否存活的标准;
Layer4:当工做在这层时,主要是以TCP端口状态来判断服务器工做是否正常;
Layer5:当工做在这层时,主要是以用户设定的服务运行是否正常来判断是否存活;
Keepalived高可用主要是经过VRRP进行通讯的,VRRP是经过竞选机制来肯定主备的,主的优先级高于备。因此正常工做时,主会优先提供服务,备处于等待阶段,只有当主出现异常,备才会接管主的任务向外提供服务。
在Keepalived服务器群之间,只有做为主的服务器不断发送VRRP广播包,告诉备它还活着,此时备不会抢占主,只有当主不可用,既备接受不到主的VRRP广播包,这时候备就会启动相关的服务接管主的任务向外提供服务,以保证服务的正常使用。vim
# 安装命令 # yum install keepalived -y # rpm -ql keepalived /etc/keepalived /etc/keepalived/keepalived.conf # 主配置文件 /etc/sysconfig/keepalived /usr/bin/genhash /usr/lib/systemd/system/keepalived.service /usr/libexec/keepalived /usr/sbin/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 # 状态参数:MASTER/BACKUP只是说明 interface eth0 # 虚拟IP放置的网卡地址 virtual_router_id 51 # 设置集群ID,同一个组的ID要一致 priority 100 # 优先级设置,数值越大优先级越高 advert_int 1 # 主备通信时间间隔 authentication { # 验证相关 auth_type PASS auth_pass 1111 } virtual_ipaddress { # 虚拟IP地址 192.168.200.16 192.168.200.17 192.168.200.18 } }
(1)、Master配置安全
! Configuration File for keepalived global_defs { router_id lb01 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 150 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.169.200 } }
(2)、Slave配置bash
! Configuration File for keepalived global_defs { router_id lb02 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 140 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.169.200 } }
(3)、启动Keepalived服务器
# systemctl start keepalived
(4)、查看VIP是否启动网络
[root@localhost keepalived]# 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:24:d1:b5 brd ff:ff:ff:ff:ff:ff inet 192.168.169.131/24 brd 192.168.169.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet 192.168.169.200/32 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::fd8:8531:b2e2:c6bb/64 scope link noprefixroute valid_lft forever preferred_lft forever
(5)、测试
关闭master上的keepalived,查看VIP是否漂移到备。负载均衡
# 关闭主master # systemctl stop keepalived # 查看备上的IP信息 [root@localhost keepalived]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:d9:69:08 brd ff:ff:ff:ff:ff:ff inet 192.168.169.130/24 brd 192.168.169.255 scope global dynamic ens33 valid_lft 1464sec preferred_lft 1464sec inet 192.168.169.200/32 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::51f1:7ad1:f554:65cc/64 scope link valid_lft forever preferred_lft forever 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN link/ether 02:42:88:bb:94:f6 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 scope global docker0 valid_lft forever preferred_lft forever
Keepalived的主备配置文件的主要区别有:
(1)、router_id不一致
(2)、state描述信息不一致
(3)、priority优先级不一致tcp
在高可用系统中,若是两个节点的心跳线断开,原本两个节点为一个总体、动做协调的一个HA系统,如今因为两个之间的心跳线断开致使它们分裂成了两个单独的个体。因为双方互相失去了联系,都会觉得对方出了故障。这时候这两个单独的个体就像"脑裂人"同样互相争抢共享资源、争用应用服务,这样就会形成严重问题:
(1)、共享资源被瓜分,两边服务都起不来;
(2)、两边服务都起来了,同时提供服务,同时读写存储,致使数据不一致甚至损坏。oop
通常来讲,脑裂的发生,有如下几种缘由:
(1)、HA服务器之间心跳线故障,致使没法正常通讯;
(2)、HA服务器上开启了防火墙,阻挡了心跳线的信息传输;
(3)、HA服务器上心跳网卡配置不正确,致使心跳信息发送失败;
(4)、其余服务器配置不当的缘由。好比心跳方式不一样,心跳广播冲突,软件BUG等;
(5)、Keepalived配置里同一 VRRP实例中若是 virtual_router_id两端参数配置不一致也会致使裂脑问题发生。
在实际环境中,咱们能够从如下几个方面来防止脑裂的问题:
(1)、同时使用串行线路或者以太网电缆链接,同时使用两条心跳线路,若是一条坏了,另一条还能正常提供服务;
(2)、当检测到脑裂时强行关闭一个节点(该功能须要特殊设备支持,如Stonith,feyce),至关于备节点接受不到心跳心跳消患,经过单独的线路发送关机命令关闭主节点的电源;
(3)、作好脑裂监控报警(用zabbix等来监控),在问题发生时能在第一时间介入仲裁,下降损失。
(4)、启动磁盘锁。正在服务一方锁住共享磁盘,“裂脑”发生时,让对方彻底“抢不走”共享磁盘资源。但使用锁磁盘也会有一个不小的问题,若是占用共享盘的一方不主动“解锁”,另外一方就永远得不到共享磁盘。现实中假如服务节点忽然死机或崩溃,就不可能执行解锁命令。后备节点也就接管不了共享资源和应用服务。因而有人在HA中设计了“智能”锁。即:正在服务的一方只在发现心跳线所有断开(察觉不到对端)时才启用磁盘锁,平时就不上锁了;
(5)、加入仲裁机制。例如设置网关IP,当脑裂发生时,两个节点都各自ping如下这个网关IP,不通则代表断点就在本端,不只“心跳”、还兼对外“服务”的本端网络链路断了,即便启动(或继续)应用服务也没有用了,那就主动放弃竞争,让可以ping通网关IP的一端去起服务。更保险一些,ping不通网关IP的一方干脆就自我重启,以完全释放有可能还占用着的那些共享资源。
(1)、执行脚本,用来检测
vim check_keepalived.sh #!/bin/bash NGINX_SBIN=`which nginx` NGINX_PORT=80 function check_nginx(){ NGINX_STATUS=`nmap localhost -p ${NGINX_PORT} | grep "80/tcp open" | awk '{print $2}'` NGINX_PROCESS=`ps -ef | grep nginx|grep -v grep|wc -l` } check_nginx if [ "$NGINX_STATUS" != "open" -o $NGINX_PROCESS -lt 2 ] then ${NGINX_SBIN} -s stop ${NGINX_SBIN} sleep 3 check_nginx if [ "$NGINX_STATUS" != "open" -o $NGINX_PROCESS -lt 2 ];then systemctl stop keepalived fi fi
(2)、添加执行权限
chmod +x check_keepalived.sh
(3)、配置keepalived
master:
! Configuration File for keepalived global_defs { router_id lb01 } # 定义脚本 vrrp_script check_ng { script "/etc/keepalived/check_keepalived.sh" # 脚本路径 interval 2 # 执行时间间隔 weight -5 # 计算权重值,脚本结果致使的优先级变动,检测失败(脚本返回非0)则优先级 -5 fall 3 # 检测连续3次失败才算肯定是真失败。会用weight减小优先级(1-255之间) rise 2 # 检测2次成功就算成功。但不修改优先级 } vrrp_instance VI_1 { state MASTER interface ens33 virtual_router_id 51 priority 150 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.169.200 } # 调用脚本 track_script { check_ng } }
slave:
! Configuration File for keepalived global_defs { router_id lb02 } vrrp_script check_ng { script "/etc/keepalived/check_keepalived.sh" interval 2 weight -5 fall 3 rise 2 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 147 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.169.200 } track_script { check_ng } }
(1)、master配置
! Configuration File for keepalived global_defs { router_id lb01 } vrrp_script check_ng { script "/etc/keepalived/check_keepalived.sh" interval 2 weight -5 fall 3 rise 2 } vrrp_instance VI_1 { state BACKUP # 主上也设置为备 interface ens33 virtual_router_id 51 priority 150 advert_int 1 nopreempt # 设置为不抢夺VIP authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.169.200 } track_script { check_ng } }
(2)、slave配置
! Configuration File for keepalived global_defs { router_id lb02 } vrrp_script check_ng { script "/etc/keepalived/check_keepalived.sh" interval 2 weight -5 fall 3 rise 2 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 149 advert_int 1 nopreempt authentication { auth_type PASS auth_pass 1111 virtual_ipaddress { 192.168.169.200 } track_script { check_ng } }