keepalived的原理:

keepalived是网络协议VRRPVirtual Route Redundancy Protocol 虚拟路由冗余协议)协议的实现。

keepalived是一个类似于Layer2,4,7交换机制的软件。是Linux集群管理中保证集群高可用的一个服务软件,其功能是用来防止单点故障。

keepalived的工作原理:

keepalived是基于VRRP协议实现的保证集群高可用的一个服务软件,主要功能是实现真机的故障隔离和负载均衡器间的失败切换,防止单点故障。在了解keepalived原理之前先了解一下VRRP协议。

VRRP协议:Virtual Route Redundancy Protocol 虚拟路由冗余协议。是一种容错协议,保证当主机的下一跳路由出现故障时,由另一台路由器来代替出现故障的路由器进行工作,从而保持网络通信的连续性和可靠性。在介绍VRRP之前先介绍一些关于VRRP的相关术语:

虚拟路由器:由一个 Master 路由器和多个 Backup 路由器组成。主机将虚拟路由器当作默认网关。

VRID:虚拟路由器的标识。有相同 VRID 的一组路由器构成一个虚拟路由器。

Master 路由器:虚拟路由器中承担报文转发任务的路由器。

Backup 路由器: Master 路由器出现故障时,能够代替 Master 路由器工作的路由器。

虚拟 IP 地址:虚拟路由器的 IP 地址。一个虚拟路由器可以拥有一个或多个IP 地址。

IP 地址拥有者:接口 IP 地址与虚拟 IP 地址相同的路由器被称为 IP 地址拥有者。

虚拟 MAC 地址:一个虚拟路由器拥有一个虚拟 MAC 地址。虚拟 MAC 地址的格式为 00-00-5E-00-01-{VRID}。通常情况下,虚拟路由器回应 ARP 请求使用的是虚拟 MAC 地址,只有虚拟路由器做特殊配置的时候,才回应接口的真实 MAC 地址。

优先级: VRRP 根据优先级来确定虚拟路由器中每台路由器的地位。

非抢占方式:如果 Backup 路由器工作在非抢占方式下,则只要 Master 路由器没有出现故障, Backup 路由器即使随后被配置了更高的优先级也不会成为Master 路由器。

抢占方式:如果 Backup 路由器工作在抢占方式下,当它收到 VRRP 报文后,会将自己的优先级与通告报文中的优先级进行比较。如果自己的优先级比当前的 Master 路由器的优先级高,就会主动抢占成为 Master 路由器;否则,将保持 Backup 状态。 nopreempt:非抢占模式;默认为抢占模式;

keepalived的架构图:

wKioL1YvnC6zeNmcAAFPDMzjZYY355.jpg 

 

说明:keepalived在实现多个实例时必须为每一个实例设置专用的多播地址。

以下实验环境调度器director使用centos7系统,后端realserver服务器使用centos6系统!

实例一:keepalived做主备模型实现nginx负载均衡httpd服务:

wKiom1YvnB3R8PtuAACuMd3T4eo331.jpg 

环境:centos7keepalivednginx

web服务使用httpd-2.2centos6系统

使用yum分别安装需要的软件包。

并测试httpd服务正常。

配置keepalived

第一步:使用yum安装keepalived(来自本地源)

使用yum安装nginx(来自epel源)

第二步:分别配置nginx做反向代理并做负载均衡

配置第一个主机实现nginx做反向代理并负载均衡后端httpd服务。

upstream upserver{

        server 172.16.249.237:80 weight=1;

        server 172.16.249.233:80 weight=1;

}

    server {

        listen       172.16.249.73:80;

    location / {

        proxy_pass  http://upserver;

        }

 

注意:proxy_pass后的http//upserver后一定不能带“/

启动nginx并测试

[root@lpw2 nginx]# systemctl start nginx.service

wKiom1YvnDqjczusAAKfC85I6OU413.jpg 

停止此主机的nginx服务,配置第二个主机做nginx反向代理并做负载均衡

为了确保两个nginx主机的配置文件一致,从前一个主机复制nginx.conf到当前主机

[root@lpw2 nginx]# scp ./nginx.conf root@172.16.249.209:/etc/nginx/

并做相应的修改

upstream upserver{

        server 172.16.249.237:80 weight=1;

        server 172.16.249.233:80 weight=1;

}

    server {

        listen       172.16.249.209:80;

        location / {

        proxy_pass  http://upserver;

        }

启动nginx服务并做测试

[root@localhost nginx]# systemctl start nginx.service

wKioL1YvnIjw_78fAAJxMko6YNE793.jpg 

现在为止最为调度器的nginx服务以及准备完毕

接下来解释配置使用keepalived高可用nginx调度器:

配置主机1keepalived

global_defs {

   notification_email {

     lpw@126.com

   }

   notification_email_from Alexandre.Cassen@firewall.loc

   smtp_server 127.0.0.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL1

   vrrp_mcast_group4 224.1.1.5   //定义keepalived用来互相发送vrrp协议报文的组播地址

}

vrrp_script chk_nginx {         //此脚本用来检测nginx是否在线

   script "killall -0 nginx"

   interval 1

   weight -2

}

vrrp_script chk_online {     // 此脚本用来检测此主机是否在线或者keepalived是否出故障,及故障后如何实现vip地址的切换

   script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"

   interval 1

   weight -2

}

vrrp_instance VI_nginx {

    state MASTER    //定义此主机为master节点

    interface eno16777736  //定义此主机监听的接口网卡

    virtual_router_id 66   //此真实主机的routeID

    priority 100   //定义此主机的初始优先级

    advert_int 1   //定义keepalived的节点之间每隔1秒检测一侧对端节点是否在线

    authentication {  //用来定义keepalived节点之间的认证方式,有两种,一种是PASS(简单的明文认证,最多8个字节),另一种是AH(加密算法)

        auth_type PASS

        auth_pass 222222

    }

 

    virtual_ipaddress {  //定义虚拟路由器的ip地址,其作为负载均衡的vip使用

        172.16.249.100/16

    }

#  track_interface {

#       eno16777736

#}

  track_script {   //调用前面声明的track_script脚本

        chk_nginx

        chk_online

         }

   notify_master "/etc/keepalived/notify.sh master"  //定义使用邮件通知的脚本,keepalived虽然默认有邮件通知机制,但其真正的通知需要自定义脚本来实现

   notify_backup "/etc/keepalived/notify.sh backup"  //自定义的notify.sh脚本(在后面)

   notify_fault "/etc/keepalived/notify.sh fault"

}

 

然后配置主机2keepalived

global_defs {

   notification_email {

     lpw@126.com

   }

   notification_email_from Alexandre.Cassen@firewall.loc

   smtp_server 127.0.0.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL1

   vrrp_mcast_group4 224.1.1.5

}

vrrp_script chk_nginx {

   script "killall -0 nginx"

   interval 1

   weight -2

}

vrrp_script chk_online {

   script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"

   interval 1

   weight -2

}

vrrp_instance VI_nginx {

    state BACKUP

    interface eno16777736

    virtual_router_id 66

    priority 99

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 222222

    }

 

    virtual_ipaddress {

        172.16.249.100/16

    }

#  track_interface {

#       eno16777736

#}

  track_script {

        chk_nginx

        chk_online

         }

   notify_master "/etc/keepalived/notify.sh master"

   notify_backup "/etc/keepalived/notify.sh backup"

   notify_fault "/etc/keepalived/notify.sh fault"

}

 

自定义的通知脚本内容如下:

# cat notify.sh 

#!/bin/bash

vip=172.16.249.100

contact='root@localhost'

 

notify() {

    mailsubject="`hostname` to be $1: $vip floating"

    mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1"

    echo $mailbody | mail -s "$mailsubject" $contact

}

 

case "$1" in

    master)

        notify master

        exit 0

    ;;

    backup)

        notify backup

        exit 0

    ;;

    fault)

        notify fault

        exit 0

    ;;

    *)

        echo 'Usage: `basename $0` {master|backup|fault}'

        exit 1

    ;;

esac

 

测试keepalived的配置的ip地址能够互相流动

wKioL1YvnMCDxicLAAO3DQhtaYI771.jpg

wKiom1YvnI2Ag8JJAACqFPHFQAo070.jpg

 

 

关闭此主机的keepalived,然后查看另一个主机的keepalived是否获得ip地址

wKiom1YvnL6TnfFjAAPNO9UxCQ0948.jpg 

接下来修改nginx的配置文件,使keepalived能够高可用nginx服务实现负载均衡,根据之前的准备只需要修改nginx的监听地址就可以

 listen       80;

在两个主机上启动nginx服务

测试:

wKioL1YvnQ7AM53-AAHw_MRI73o649.jpg 

keepalived目录下创建down空文件,然后主节点上的vip地址移动到备节点上

wKiom1YvnQng2QedAADI9tkQupE635.jpg

wKioL1YvnT2y7cUEAANSvdAz0B8781.jpg

 

查看备用节点上的ip地址

 

wKiom1YvnTySDW9XAAO52FgUjvA057.jpg

wKioL1YvnXDyD63IAADpr4GqlbE111.jpg

 

 

实例二:keepalived实现lvs调度(DR模型),

wKiom1YvnWCwbYm7AAFAhN4QxOY229.jpg

首先要在两个director都实现lvsDR模型

配置第一个主机做director

[root@lpw1 ~]# ip addr add 172.16.249.100 dev eno16777736

以另一个主机测试此地址联通性

wKioL1YvnbGz-9q0AAIUSqNr5Q8496.jpg 

然后配置后端两个real-server

[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore 

[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore 

[root@localhost ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce 

[root@localhost ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce 

为每一个real-serverlo接口配置vip地址

[root@localhost ~]# ifconfig lo:0 172.16.249.100/32 broadcast 172.16.249.100 up

[root@localhost ~]# route add -host 172.16.249.100 dev lo:0

 

 

然后在第一个director上添加ipvs规则:

[root@lpw1 ~]# ipvsadm -A -t 172.16.249.100:80 -s rr

[root@lpw1 ~]# ipvsadm -a -t 172.16.249.100:80 -r 172.16.249.237 -g -w 1

[root@lpw1 ~]# ipvsadm -a -t 172.16.249.100:80 -r 172.16.249.233 -g -w 1

wKiom1YvnZnjo2KYAAItRf5sZq8378.jpg 

以另一个主机做客户端使用curl命令访问

wKioL1YvneGxZEtvAAJJxApjtwQ618.jpg 

然后清除此director上的VIP地址和ipvs规则

[root@lpw1 ~]# ipvsadm -C

[root@lpw1 ~]# ip addr 172.16.249.100 dev eno16777736

接下来在第二个director上进行同样的配置,并确保lvs能够正确调度。

wKioL1YvngTBX2doAAJMBeHZuF8281.jpg 

然后清除此lvs规则和vip地址

然后配置keepalived实现自动生成ipvs规则

配置文件如下:

! Configuration File for keepalived

 

global_defs {

   notification_email {

     lpw@126.com

   }

   notification_email_from Alexandre.Cassen@firewall.loc

   smtp_server 127.0.0.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL1

#   vrrp_mcast_group4 224.1.1.5

}

#vrrp_script chk_nginx {

#   script "killall -0 nginx"

#   interval 1

#   weight -2

#}

#vrrp_script chk_online {

#   script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"

#   interval 1

#   weight -2

#}

vrrp_instance VI_nginx {

    state MASTER

    interface eno16777736

    virtual_router_id 66

    priority 100

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 222222

    }

 

    virtual_ipaddress {

        172.16.249.100/16

    }

#  track_interface {

#       eno16777736

#}

#  track_script {

#       chk_nginx

#        chk_online

#         }

   notify_master "/etc/keepalived/notify.sh master"

   notify_backup "/etc/keepalived/notify.sh backup"

   notify_fault "/etc/keepalived/notify.sh fault"

}

 

virtual_server 172.16.249.100 80 {  //定义vip地址和端口

    delay_loop 6  //定义调度器向后端每个多久

    lb_algo rr  //指明调度算法,支持rr|wrr|lc|wlc|lblc|sh|dh

    lb_kind DR  //指明lvs的模型,支持NAT|DR|TUN

#    persistence_timeout 50  //定义持久时长

    protocol TCP //定义使用哪种协议

 

#    sorry_server 192.168.200.200 1358  //定义sorr_server,当所有realserver都不在的时候提供提示的服务器。

 

    real_server 172.16.249.237 80 {  //定义一个realserver

        weight 1

        HTTP_GET { //定义健康状态监测的协议

                    // HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK

            url {

              path  /    用来指明健康状态监测时请求的测试页面

              status_code 200  如果请求时的响应码是200就认为后端服务器正常

            }

            connect_timeout 3  //健康状态监测时的请求超时时间

            nb_get_retry 3  //向后端请求几次才认为后端real-server联系不上

            delay_before_retry 3  //每一次超时前要等待多久时长

        }

    }

 

    real_server 172.16.249.233 80 {

        weight 1

        HTTP_GET {

            url {

              path /

              status_code 200

            }

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

        }

    }

}

 

 

在两个director上启动keepalived服务

#第一个director

[root@lpw1 keepalived]# systemctl start keepalived.service

[root@lpw1 keepalived]# ip addr list

[root@lpw1 keepalived]# ipvsadm -L -n

然后进行查看

wKiom1Yvne-zfnZ5AAVI7idq7KY451.jpg 

查看第二个director上的ipvs规则和是否有vip地址。

wKioL1YvnkbRw6lKAAS7dNNw9WI893.jpg 

此时第二个director上有ipvs规则但是没有vip地址

因此测试访问时通过第一个director进行调度的

wKioL1YvnoqDPHg7AAIsOIbfO-8018.jpg 

此时如果手动关闭一个realserverhttpd服务,过一会时间在启动,那么就会自动实现后端健康状态监测的功能。

此时如果关闭第一个directorkeepalived服务,vip地址将自动移动到第二个director上并继续提供调度服务。这就是keepalived高可用lvs的实现。

 

wKioL1YvnsOzPbrbAAOzi5ArS-4009.jpg

wKioL1YvnsXisRzDAAQGSl81_54126.jpg

wKiom1YvnpPR7NoHAAI3pg-GPYA580.jpg


附加:以上实例二采用HTTP_GET 方式对后端realserver做讲课状态监测,也可以使用tcp方式监测,只需修改监测方法为

 TCP_CHECK{                                                                    

         connect_ip <IP ADDRESS>  //指明后端realserverip地址,默认使用 real_server 后的地址

         connect_port <PORT>   //指明后端realserver的端口,默认使用 real_server 后的端口

         bindto <IP ADDRESS>  //如果本机有多个网卡,指明从哪个网卡发送检测报文                 

         bind_port <PORT>    //指明本机的那个端口发送检测报文               

         connect_timeout <INTEGER>  //指明检测报文的超时时间,只要指定这一项就可以达到健康状态监测功能。          

         fwmark <INTEGER>  //fwmark指的防火墙标记               

         warmup <INT> //如果后端有众多realserver时,如果按精确时间发送检测报文,可能会造成本机的网络堵塞,因此可以使用

}            // warmup 指定一个时间,表示将发送检测报文的精确时间差开一点的时间,以免造成本机堵塞。

 

实例三:使用keepalived实现双主模型:

! Configuration File for keepalived

 

global_defs {

   notification_email {

     root@localhost

     failover@firewall.loc

     sysadmin@firewall.loc

   }

   notification_email_from Alexandre.Cassen@firewall.loc

   smtp_server 127.0.0.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}

vrrp_script chk_online {

   script "[[ -f /etc/keepalived/down ]] && exit 1 || exit 0"

   interval 1

   weight -20

}

 

vrrp_script chk_nginx {

    script "killall -0 nginx &> /dev/null"

    interval 1

    weight -20

}

 

vrrp_instance VI_1 {

    state MASTER

    interface eno16777736

    virtual_router_id 100

    priority 100

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 100

    }

    virtual_ipaddress {

        172.16.125.100/16 dev eno16777736 label eno16777736:0

    }

    track_script {

        chk_nginx

        chk_online

   }

}

 

vrrp_instance VI_2 {

    state BACKUP

    interface eno16777736

    virtual_router_id 110

    priority 90

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 110

    }

    virtual_ipaddress {

        172.16.125.110/16 dev eno16777736 label eno16777736:1

    }

    track_script {

        chk_nginx

        chk_online

   }

}

 

 

 提示:keepalived 要实现lvs_NAT模型的高可用,根据NAT模型的原理,必须要实现VIP和DIP同时移动,因此可以定义一个vrrp_sync_group来实现多个ip绑定在一起随之在节点之间流动!

 vrrp_sync_group VG_1 {

           group {

             inside_network   # name of vrrp_instance (below)

             outside_network  # One for each moveable IP.

             ...

           }