• keepalived



    简介:

    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.35192.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

  • 相关阅读:
    数据结构与算法_20 _ 散列表(下):为什么散列表和链表经常会一起使用?
    数据结构与算法_19 _ 散列表(中):如何打造一个工业级水平的散列表?
    数据结构与算法_17 _ 跳表:为什么Redis一定要用跳表来实现有序集合?
    数据结构与算法_18 _ 散列表(上):Word文档中的单词拼写检查功能是如何实现的?
    数据结构与算法_16 _ 二分查找(下):如何快速定位IP对应的省份地址
    数据结构与算法_15 _ 二分查找(上):如何用最省内存的方式实现快速查找功能
    线程池ThreadPoolExecutor源码详解
    用信鸽来解释 HTTPS
    并发集合类之图解CopyOnWriteArrayList
    认识RabbitMQ从这篇文章开始
  • 原文地址:https://www.cnblogs.com/wangxiaoqiangs/p/5630490.html
Copyright © 2020-2023  润新知