简介:
Keepalived 是一个基于 VRRP 协议来实现 WEB 服务高可用的解决方案,用来避免单点故障。主服务器会发送特定的消息给备份服务器,当备份服务器收不到这个消息时,即主服务器宕机的时候,备份服务器就会接管虚拟 IP ,继续提供服务,从而保证高可用性。
下载地址:http://www.keepalived.org/download.html
1、安装 keepalived
shell > tar zxf keepalived-1.2.10.tar.gz -C ../ shell > cd ../keepalived-1.2.10/ shell > ./configure --prefix=/usr/local/keepalived --disable-lvs
## 这里不使用 lvs ,所以要禁用它,不然会报错无法通过,如果使用 lvs ,那么先安装 ipvsadm 。
shell > make ; make install
2、调整 keepalived
shell > cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/ shell > cp /usr/local/keepalived/sbin/keepalived /usr/sbin/ shell > cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/ shell > mkdir /etc/keepalived shell > cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
3、修改主服务器上的 keepalived.conf
shell > vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { # 全局配置 notification_email { # 设置报警邮件地址 ,多个地址换行写 ,如开启邮件报警本机需启动 sendmail 服务 acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc # 邮件发送地址 smtp_server 192.168.200.1 # 设置邮件的 smtp server 地址 smtp_connect_timeout 30 # 设置连接 smtp server 的超时时间 router_id LVS_DEVEL # keepalived 标识 ,邮件主题内容 } ## 以上信息保持默认即可 ,我们不使用 keepalived 的邮件功能 vrrp_instance VI_1 { # VRRP 实例配置 ,VI_1 实例名称 state MASTER # keepalived 角色 ,MASTER 为主服务器 ,BACKUP 为备用服务器 interface eth0 # 指定监听的网络接口 virtual_router_id 80 # 虚拟路由标识 ,表示为一个数字 ,同一个 VRRP 实例使用唯一的标识 ,MASTER BACKUP 必须一致 priority 100 # 节点优先级 ,数字越大 优先级越高 ,范围 0-255 ,同一 VRRP 实例中 MASTER 的优先级必须大于 BACKUP 的优先级 advert_int 1 # MASTER 与 BACKUP 同步检查时间间隔 ,单位为 秒 # mcast_src_ip 192.169.1.88 # 发送多播包的地址 ,不设置时将使用绑定网卡所对应的 IP 地址 # garp_master_delay 10 # 切换到 MASTER 状态后延时进行 Gratuitous arp 请求的时间 authentication { # 设置节点通信验证类型和密码 auth_type PASS # 类型有 PASS 和 AH 两种 auth_pass 888888 # 验证密码 ,同一 VRRP 实例中 ,MASTER BACKUP 必须使用相同的密码才能正常通信 } virtual_ipaddress { # 虚拟 IP ,又称漂移 IP 地址 ,有多个时每行一个 。当 keepalived 为 MASTER 状态时 ,这个 IP 会自动添加到系统 192.168.1.35 中 ,而切换到 BACKUP 时 ,这些 IP 又会自动从系统中删除 。可以通过 ip add 命令查看。 } 可以写成 :192.168.1.35 或 192.168.1.35 dev eth0 或 192.168.1.35/24 dev eth0 # nopreempt # 高可用集群中的不抢占功能 。只能在"状态"为 BACKUP 的节点上设置 ,并且优先级必须高于其他节点(1) # preemtp_delay 120 # 抢占延时时间 ,单位为 秒 。( 我定义为:常用在备节点上 # 没研究透 ,慎用 )(2) }
## 1、如果不设置 nopreempt 参数 ,当主节点无法正常提供服务时 ,备节点会接管服务 ,而当主节点恢复正常时 ,主节点会再次自动接管服务 。
这种来回切换的操作对实时性和稳定性要求很高的业务来说是不理想的 ,存在着一定的风险和不稳定性 。配置此参数后 ,主节点恢复正常后不自动接管服务 ,服务会一直运行在备用节点上 ,直到备用节点发生故障才进行切换 。
## 2、有时系统启动或重启之后 ,网络需要经过一段时间才能正常工作 ,在这种情况下是无需进行切换的 ,preemtp_delay 参数用来设置这种情况的发生间隔。
在此时间内发生的故障将不会进行切换 ,如果超过 preemtp_delay 指定的时间 ,并且网络异常时 ,进行主备切换。
4、备机
1)、与 MASTER 相同
2)、与 MASTER 相同
3)、keepalived.conf ! 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 LVS_DEVEL } vrrp_instance VI_1 { state BACKUP # keepalived 备机状态 interface eth0 virtual_router_id 80 # 虚拟路由标识要跟 MASTER 一致 priority 90 # 优先级要比 MASTER 低 advert_int 1 authentication { auth_type PASS auth_pass 888888 # 验证密码要跟 MASTER 一致 } virtual_ipaddress { 192.168.1.35 # 虚拟 IP 地址 } preemtp_delay 120 # 当备节点 120 秒没有接收到主节点发送的 VRRP 数据包时进行主备切换 }
5、主、备节点启动 keepalived ( service keepalived start )
主节点日志:
shell > tail -14 /var/log/messages Dec 30 13:31:32 study Keepalived[2987]: Starting Keepalived v1.2.10 (12/30,2014) Dec 30 13:31:32 study Keepalived[2988]: Starting VRRP child process, pid=2990 Dec 30 13:31:32 study Keepalived_vrrp[2990]: Registering Kernel netlink reflector Dec 30 13:31:32 study Keepalived_vrrp[2990]: Registering Kernel netlink command channel Dec 30 13:31:32 study Keepalived_vrrp[2990]: Registering gratuitous ARP shared channel Dec 30 13:31:32 study Keepalived_vrrp[2990]: Opening file '/etc/keepalived/keepalived.conf'. Dec 30 13:31:32 study Keepalived_vrrp[2990]: Configuration is using : 63321 Bytes Dec 30 13:31:32 study Keepalived_vrrp[2990]: Using LinkWatch kernel netlink reflector... Dec 30 13:31:32 study Keepalived_vrrp[2990]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)] Dec 30 13:31:33 study Keepalived_vrrp[2990]: VRRP_Instance(VI_1) Transition to MASTER STATE Dec 30 13:31:34 study Keepalived_vrrp[2990]: VRRP_Instance(VI_1) Entering MASTER STATE Dec 30 13:31:34 study Keepalived_vrrp[2990]: VRRP_Instance(VI_1) setting protocol VIPs. Dec 30 13:31:34 study Keepalived_vrrp[2990]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.1.35 Dec 30 13:31:44 study Keepalived_vrrp[2990]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.1.35
## 可以看到倒数第四行 ,Entering MASTER STATE (进入 MASTER 状态),并且将虚拟 IP 192.168.1.35 绑定在了 eth0 上
shell > ip add | grep -A 5 ^2: 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:d0:99:fa brd ff:ff:ff:ff:ff:ff inet 192.168.1.88/24 brd 192.168.1.255 scope global eth0 inet 192.168.1.35/32 scope global eth0 inet6 fe80::20c:29ff:fed0:99fa/64 scope link valid_lft forever preferred_lft forever
## 可以看到虚拟 IP 192.168.1.35
备节点日志:
shell > tail -15 /var/log/messages Dec 30 13:19:11 localhost Keepalived[2757]: Starting Keepalived v1.2.10 (12/30,2014) Dec 30 13:19:11 localhost Keepalived[2758]: Starting VRRP child process, pid=2760 Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: Registering Kernel netlink reflector Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: Registering Kernel netlink command channel Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: Registering gratuitous ARP shared channel Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: Opening file '/etc/keepalived/keepalived.conf'. Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: Configuration is using : 63302 Bytes Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: Using LinkWatch kernel netlink reflector... Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Entering BACKUP STATE Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)] Dec 30 13:19:15 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Transition to MASTER STATE Dec 30 13:19:16 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Entering MASTER STATE Dec 30 13:19:16 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) setting protocol VIPs. Dec 30 13:19:16 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.1.35 Dec 30 13:19:21 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.1.35
## 发现备节点居然也进入了 MASTER 状态
shell > ip add | grep -A 5 ^2: 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 link/ether 00:0c:29:46:d3:7c brd ff:ff:ff:ff:ff:ff inet 192.168.1.80/24 brd 192.168.1.255 scope global eth0 inet 192.168.1.35/32 scope global eth0 inet6 fe80::20c:29ff:fe46:d37c/64 scope link valid_lft forever preferred_lft forever
## 也可以看到虚拟 IP 192.168.1.35
## 经过分析:
1、首先配置文件没有错
2、其次就是主备的选举中出现了问题 ,主备选举按优先级来判定 ,优先级高的为 MASTER ,低的为 BACKUP ,按配置文件来看也没有问题
3、那么就是主备检测出了问题 ,正常情况下主会定期给备发送 VRRP 数据包 ,当备接收不到主发来的 VRRP 数据包时认为主不可用,然后从多个备中选举新的 MASTER。
我们这个例子中只有一个备 ,所以当备无法收到主发来的 VRRP 数据包时 ,备就成为了主 ,而主还是主( 因为自己没问题 )。
## 所以将故障定位在了备节点的 iptables( 因为备节点无法接收到主节点发来的 VRRP 数据包 )
备节点操作:
shell > iptables --line-numbers -nL Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:80 5 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 6 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) num target prot opt source destination shell > iptables -I INPUT 4 -s 192.168.1.88 -j ACCEPT # 记得保存规则 ,否则重启失效
马上就会发现备节点从 MASTER 状态切换回了 BACKUP 状态:
shell > tail -f /var/log/messages Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: Opening file '/etc/keepalived/keepalived.conf'. Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: Configuration is using : 63302 Bytes Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: Using LinkWatch kernel netlink reflector... Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Entering BACKUP STATE Dec 30 13:19:11 localhost Keepalived_vrrp[2760]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)] Dec 30 13:19:15 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Transition to MASTER STATE Dec 30 13:19:16 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Entering MASTER STATE Dec 30 13:19:16 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) setting protocol VIPs. Dec 30 13:19:16 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.1.35 Dec 30 13:19:21 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.1.35 Dec 30 13:34:34 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Received higher prio advert Dec 30 13:34:34 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) Entering BACKUP STATE Dec 30 13:34:34 localhost Keepalived_vrrp[2760]: VRRP_Instance(VI_1) removing protocol VIPs.
## 倒数三行 ,Entering BACKUP STATE( 进入了 BACKUP 状态 ),并且移除了 VIP
shell > ip add | grep -A 5 ^2 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 link/ether 00:0c:29:46:d3:7c brd ff:ff:ff:ff:ff:ff inet 192.168.1.80/24 brd 192.168.1.255 scope global eth0 inet6 fe80::20c:29ff:fe46:d37c/64 scope link valid_lft forever preferred_lft forever
## VIP 消失了 。而此时的主还是主 !
6、测试高可用是否生效
## 当主节点关闭 keepalived 服务时 ,备节点瞬间绑定虚拟 IP ,主节点移除虚拟 IP ,在此过程中 ping 包会丢一个 。
## 当主节点恢复 keepalived 服务时 ,备节点瞬间移除虚拟 IP ,主节点绑定虚拟 IP ,在此过程中 ping 包会丢一个 。
## 关于参数 nopreempt
1> 测试发现,主节点无法提供服务时 ,被切换到备节点 。当主节点修复完成 ,加入网络的时候 ,如果 state 还为 MASTER 那么此参数不生效,会抢占 VIP
2> 主节点后加入网络并且不想抢占资源时 ,state 应设为 BACKUP ,优先级不变 ,保持最大 ,加入 nopreempt 参数可以实现此需求,当备节点故障时才抢占 VIP