Linux keepalived

Linux Keepalived
    Keepalived是一个用C编写的路由软件。该项目的主要目标是为Linux系统和基于Linux的基础架构提供简单而强大的负载平衡和高可用性设施。负载平衡框架依赖于众所周知且广泛使用的Linux虚拟服务器(IPVS)内核模块,提供Layer4负载均衡。Keepalived实现了一组检查器,以根据其健康状况动态地和自适应地维护和管理负载平衡的服务器池。另一方面,VRRP实现了高可用性协议。VRRP是路由器故障转移的基础。此外,Keepalived为VRRP有限状态机实现了一组挂钩,提供低级和高速协议交互。为了提供最快的网络故障检测,Keepalived实现了BFD协议。VRRP状态转换可以考虑BFD提示来驱动快速状态转换。Keepalived框架可以单独使用,也可以一起使用,以提供灵活的基础架构。
        keepalived由于其非常轻量所以常常与lvs或nginx反向代理一起使用,用于实现director的高可用,就像天造地设的一对儿!keepalived在功能上虽然没有HeartBeat和corosync等程序强大,往往需要借助一些外部的脚本文件来辅助完成各种细节上的功能,但是只是为了高可用director而不是大型成百上千台主机的话,还是keepalived比较好用;后两个由于其功能多且强大,所以适合更大型的高可用集群;
    keepalived角色:
        Active/Passive   活动节点和备用节点
    相对于lvs我们需要的资源只有两个:VIP地址和ipvs规则,其中ipvs规则可以在各个director上提前配置好,其实最不稳定的就是VIP地址,因为只有Active节点可以拥有VIP地址从而向外提供服务;所以keepalived的功能就是当Active节点上的服务出现故障时,Passive可以马上将VIP地址抢过来,配置到自己的网卡上,继续向外提供服务;但是Passive怎么知道Active是活动的、可提供服务的呢?这就需要作为Active的节点定期主动的向外发送自己还“活着“的消息(一般是通过组播的方式),通知Passive节点:只要朕不死,你永远是太子的信息;如果Passive过了指定的时间周期还没有收到Active的通知信息就认为其已经down掉了,然后自己取而代之,最为Active节点向外提供服务;
    Keepalived其实就是VRRP在Linux上以守护进程方式的实现;
        keepalived可以根据配置文件自动生成ipvs规则;
        keepalived还可以对各后端RS进行健康状态监测;
        VRRP:Virtual Route Redundant Protocol,虚拟路由冗余协议;
            vrrp协议可以将多个路由器虚拟成一个大的路由器,这个大的路由器对底层是透明的,用户并不知道其内部有多个路由器,这些路由器中有一个为Master路由器,真正对外服务的设备,其他的为Backup路由器(Master为Vip地址拥有者,向外提供服务),当Master路由器故障时Backup路由器可以通过选举机制再选出一个Master来继续提供服务(其实vrrp也可以实现负载均衡,也就是将所有路由器划分成虚拟的区域(一个虚拟区域即为一个虚拟路由器),每个路由器可以属于多个虚拟区域,不同的路由器在不同的区域担任的角色不同,比如:一个路由器在area1中为Master,则在area2中就为Backup;通过将不同地址段的主机划分到不同的Master上,来实现负载均衡从而减少路由器的负载和利用闲置路由器);可以看出这跟前面描述的Keepalived的工作机制是相似的;
            vrrp中关于Master和Backup的转换有两种模式:抢占模式和非抢占模式;其中抢占模式为优先级高者为Master,非抢占模式为只要当前的Master路由器是正常工作的就算有优先级更高的路由器也不会成为Master;
            vrrp还支持验证功能,对于同一个虚拟区域(也就是同一个虚拟路由器)需要使用相同的字符串进行签名;其中有三种模式:不验证,简单明文验证,md5加密验证;一般都是简单的明文验证,因为开销比较小;
            vrrp使用不同的vrrp id来标识不同的虚拟路由器;具有相同vrrp id的路由器为一个大的虚拟路由器;
            VRRP的先关信息可以在H3C或者华为的官网中查找相关的资料,有很多!
    配置前提:关闭防火墙,selinux;
        时间同步(ntp),ssh基于秘钥登录,基于主机名通信;
        安装相关软件;
            yum install keepalived -y
    配置文件:
        /etc/keepalived/keepalived.conf
            global_defs { }:全局配置段;
                
            vrrp_instance { }:vrrp实例段,也就是用来实现虚拟路由器的;
            vrrp_sync_group { }:vrrp同步组,可以实现多个ip地址一起迁移;
            vritual_server { }:虚拟服务器,也就是指定LVS后端RS服务器的;如果是高可用nginx就用不到这一块;
            global_defs {
                   notification_email {   指定将各种信息发送到指定邮箱
                     [email protected]    邮箱地址
                   }
                   notification_email_from [email protected]    发件人邮箱
                   smtp_server 192.168.200.1    指定邮件服务器地址
                   smtp_connect_timeout 30     指定邮件服务器的连接超时时间
                   router_id LVS_DEVEL         定义当前设备的ID号,唯一
                   vrrp_skip_check_adv_addr   是否检查来自同一个路由器的vrrp通告地址
                  vrrp_garp_interval 0    指定发送免费ARP的延时 单位为ms
                vrrp_mcast_group4 224.0.0.18    指定VRRP通告信息的组播地址,可以不配置;
            }

            vrrp_sync_group VG_1 {    vrrp同步组,可以将多个IP地址一起进行故障转移,比如使用lvs-nat模式时,面向外网的VIP需要和面向内网的DIP一起转移,才可以继续提供服务;
                group {
                     inside_network   # name of the vrrp_instance
                     outside_network  # One for each movable IP
                }
            }
                例子:
                    vrrp_instance OUTSIDE {
                        eth0
                        VIP
                    }
                    vrrp_instance INSIDE {
                        eth0
                        DIP
                    }
                    vrrp_sync_group VG_1 {
                        group {
                             INSIDE
                             OUTSIDE
                        }
                    }

            vrrp_instance VI_1 {        指定vrrp实例名称
                state MASTER         指定Master/Backup状态
                interface eth0         指定在哪块网卡接口上配置VIP地址
                virtual_router_id 51    指定虚拟路由器id
                priority 100           指定优先级
                   advert_int 1           VRRP通告间隔  单位为s
                preempt | nopreempt   指定keepalived的工作模式,默认为抢占模式
                notify_master | [username [groupname]]
                    当keepalived状态转变成Master时就执行后面的字符串(脚本)
                   notify_backup | [username [groupname]]
                    当keepalived状态转变成Backup时就执行后面的脚本
                   notify_fault | [username [groupname]]
                    当keepalived故障时就执行后面的脚本
                   notify_stop | [username [groupname]]
                    当keepalived停止时就执行后面的脚本
                   notify | [username [groupname]]
                    只要keepalived状态改变就执行后面的脚本
                Note:上面的notify后面一般都会接一个关于发送邮件的脚本,用于当keepalived出现各种情况时,能够马上通知管理员来进行检查;
                authentication {        VRRP验证配置段
                    auth_type PASS    指定验证类型
                    auth_pass 1111    指定验证时使用的字符串,建议更改一个复杂一点的
                }
                virtual_ipaddress {      指定虚拟IP地址(VIP)
                    192.168.200.16
                    192.168.200.17
                    192.168.200.18
                }
            }
        Note:如果实现的是nginx的高可用,则无需下面的配置;
            virtual_server 192.168.200.100 443 {    指定虚拟服务的地址及接口
                delay_loop 6    指定向RS服务器进行健康状态检测的轮询延迟时间
                lb_algo rr|wrr|lc|wlc|lblc|sh|dh       指定LVS调度器类型
                lb_kind NAT     LVS转发模式 NAT,TUN,DR
                persistence_timeout 50   LVS持久连接超时时间
                protocol TCP    指定所使用的传输层协议类型
                virtualhost   指定基于HTTP_GET或SSL_GET对后端RS中虚拟的主机进行健康状态检测;
                sorry_server 192.168.200.200 1358   指定sorry服务器地址,当RS服务器全部宕机以后,所有的访问都会被指向sorry服务器;sorry服务器上一般都是通告一些类似“服务器正在维修,暂时无法提供信息”这种信息;一般都是使用directory作为sorry服务器
                real_server 192.168.201.100 443 {   指定RS服务器地址及端口
                    weight 1   指定权重
                    notify_up | [username [groupname]]
                        当进行健康状态检测以后RS状态为UP后通过调用相关的脚本通知管理员;
                    notify_down | [username [groupname]]
                        当进行健康状态检测以后RS状态为DOWN后通过调用相关的脚本通知管理员;
                    SSL_GET|HTTP_GET|TCP_CHECK {  设置SSL_GET、HTTP_GET或TCP_CHECK等健康检查方式
                        url {   URL配置段
                              path /   设置请求指定信息页的地址路径
                              digest ff20ad2481f97b1754ef3e12ecd3a9cc  指定摘要信息
                        }
                        url {
                              path /mrtg/
                              digest 9b3a0c85a887a256d6939da88aabd8cd
                                作为健康状态监测页面的校验码,需要手动生成以后填写在这里,然后用它跟每次请求的页面做对比,如果相同就表示状态健康;
                        }
                        status_code 200    指定返回的HTTP头部中的状态码
                    Note:上面的设置是通过请求指定的信息,如果请求成功就表示后端服务器处于正常运行;
                        connect_timeout 3   超时连接时间
                        nb_get_retry 3       请求失败以后的重试次数
                        delay_before_retry 3  重试之前的延迟时间
                        connect_ip  指定欲进行健康状态检测的主机地址
                        connect_port  指定进行健康状态检测时使用的端口号
                        bindto  指定本机发送健康状态检测信息的地址
                        bind_port   指定本机进行健康状态检测时使用的端口号
                        connect_timeout  指定连接超时时间,默认为5s
                    }
                }
            }
            后面的配合类似,之所以列出是为了展示一个virtual_server中可以配置多个RS,便于仿照配置;
            virtual_server 10.10.10.2 1358 {
                delay_loop 6
                lb_algo rr 
                lb_kind NAT
                persistence_timeout 50
                protocol TCP
            sorry_server 192.168.200.200 1358
                real_server 192.168.200.2 1358 {
                    weight 1
                    HTTP_GET {
                        url { 
                              path /testurl/test.jsp
                              digest 640205b7b0fc66c1ea91c463fac6334d
                        }
                        url { 
                              path /testurl2/test.jsp
                              digest 640205b7b0fc66c1ea91c463fac6334d
                        }
                        url { 
                              path /testurl3/test.jsp
                              digest 640205b7b0fc66c1ea91c463fac6334d
                        }
                        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
                    }
                }
            }
    配置例子:我列出的仅为一端的配置,在另一边别忘做相关的修改
        global_defs {
               notification_email {
                root@localhost
               }
               notification_email_from guowei@localhost
               smtp_server 127.0.0.1
               smtp_connect_timeout 30
               router_id node2
        }
 
        vrrp_instance VI_1 {
            state MASTER
            interface ens33
            virtual_router_id 51
            priority 100
            advert_int 1
            authentication {
                auth_type PASS
                auth_pass e57b49ed
            }
            virtual_ipaddress {
                192.168.80.12
            }
        }
    添加日志文件;
        vim /etc/sysconfig/keepalived
            KEEPALIVED_OPTIONS="-D -S 3"
        vim /etc/rsyslog.conf
        local3.*                 /var/log/keepalived.log
    启动keepalived:
        systemctl restart rsyslog.service
        systemctl start keepalived.service
    维护方法:
        当Active升级keepalived版本时,一般需要停掉当前的keepalived服务,但这种方法明显是不太好的,我们可以通过外部的脚本手动的将其调度为备用服务器之后,再进行升级;
        在配置文件中添加以下一段:
        vim /etc/keepalived/keepalived.conf
            vrrp_script chk_schedown {
                script "/etc/keepalived/keepalived_down.sh"   指定欲运行的脚本
                    Note:script这个指令会执行外部的脚本,然后根据脚本执行成功与否的状态来决定下面指令的执行,一般都是与weight命令配合使用;如果weight命令为负值(其实正负都一样,为负就加负值,为正就加正值),则当script执行脚本失败时,此端的优先级(priority)就变为:原优先级与weight的和,即(100+(-2))=98,如果执行成功则优先级不变即100;何为脚本执行失败?答:echo $? 的值为非0(取值在0-255之间),即为失败;可以在脚本中使用exit来手动指定脚本执行成功与否;
                interval 2    指定脚本调用的间隔时间
                weight -2
                user root
            }
            vrrp_instance VI_1 {
                track_script {
                    chk_schedown
                   }
            }  此处的意思是track_script{ }要放在vrrp_instance{ }中;
        vim /etc/keepalived/keepalived_down.sh
            #!/bin/bash
            if [[ -f /etc/keepalived/down ]]
            then
                exit 1
            fi       
                exit 0
                当在/etc/keepalived/目录中创建down文件时,本端优先级就会减2,从而就会由Master转成Backup;
        chmod +x /etc/keepalived/keepalived_down.sh
    实现负载均衡:也就是将两台主机上的keepalived划分成两个虚拟主机VI_1和VI_2,其中一台主机在VI_1中为MASTER,在VI_2中为BACKUP;另一台主机在VI_1中为BACKUP,在VI_2中为MASTER;在上面的基础上再添加下面的内容即可:
        vrrp_instance VI_2 {
            state BACKUP
            interface ens33
            virtual_router_id 52
            priority 99
            advert_int 1
            authentication {
                auth_type PASS
                auth_pass r57b49rd
            }
            virtual_ipaddress {
                192.168.80.20
            }
            track_script {
                chk_schedown
               }
        }

    添加邮件通知功能:
        vim /etc/keepalived/keepalived.conf    在vrrp_instance VI_1中添加一下内容
            notify_master "/etc/keepalived/notify.sh master"
               notify_backup "/etc/keepalived/notify.sh backup"
               notify_fault "/etc/keepalived/notify.sh fault"
        脚本:
            #!/bin/bash
            vip=192.168.80.12
            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
    实现LVS负载均衡:
        实验环境:两个director(centos7:192.168.80.130和node2:192.168.80.136),两个RS(clone1:192.168.80.131和clone2:192.168.80.134),使用LVS的DR模式,其中director使用keepalived实现高可用;
        RS端:
            yum install httpd -y
            echo "

RS:clone1

" >  /var/www/html/index.html
            echo "

RS:clone2

" > /var/www/html/indec.html
            service httpd start
            sysctl net.ipv4.conf.all.arp_ignore=1
              sysctl net.ipv4.conf.lo.arp_ignore=1
              sysctl net.ipv4.conf.all.arp_announce=2
              sysctl net.ipv4.conf.lo.arp_announce=2
            ifconfig lo:0 192.168.80.12 netmask 255.255.255.255 broadcast 192.168.80.12 up
            route add -host 192.168.80.12 dev lo:0
            sysctl net.ipv4.ip_forward=1
        Director端:VIP为192.168.80.12
            上面已经配置好了vrrp实例(将实例2删除即可),我们接下来直接添加virtual_server即可;
            yum install httpd -y
            echo "

Sorry server:node2

" > /var/www/html/index.html
            echo "

Sorry server:centos7

" > /var/www/html/index.html
            systemctl start httpd.service
            virtual_server 192.168.80.12  80  {
                delay_loop 6
                lb_algo wrr
                lb_kind DR
                protocol TCP
                sorry_server 192.168.80.136 80
                real_server 192.168.80.131 80 {
                    weight 1
                    HTTP_GET {
                        url {
                              path /
                              status_code 200
                        }
                        connect_timeout 3
                        nb_get_retry 3
                        delay_before_retry 3
                    }
                }
                real_server 192.168.80.134 80 {
                    weight 2
                    HTTP_GET {
                        url {
                              path /
                              status_code 200
                        }
                        connect_timeout 3
                        nb_get_retry 3
                        delay_before_retry 3
                    }
                }
            }
            systemctl start keepalived.service
            Note:各个主机都要进行配置,此处的配置仅为一端的;
            搭建完成以后使用浏览器访问192.168.80.12即可;
    实现nginx负载均衡:
        keepalived本身的功能只可以实现出当节点故障时作出转移操作,但是当nginx服务自己故障时,keepalived是不会知道状态的,也就无法作出相应的故障转移了;面对这种情况我们可以使keepalived调用外部脚本,让这个脚本检测当nginx服务出现问题以后对其重启或进行优先级的降低,然后进行故障转移;
        配置过程:还是以上面的例子为基础
            RS端无需做什么更改;
            Director端:
                首先将vrrp_instance VI_2和virtual_server都删除或者注释掉;
                yum install nginx.x86_64
                vim /etc/nginx/nginx.conf
                    http {
                        upstream webserver {
                            server 192.168.80.131:80 weight=1;
                            server 192.168.80.134:80 weight=1;
                        }
                        server {
                            location / {
                                proxy_pass http://webserver/;
                            }
                        }
                    }
                vim /etc/keepalived/keepalived.conf
                    vrrp_script chk_nginx {
                        script "/etc/keepalived/keepalived_nginx_chk.sh"
                            Note:killall -0 nginx可以实现探测nginx服务是否存在,如果存在exit为0,否则为1;如果返回为1 怎么权重-20;
                        interval 1
                           weight -20
                    }
                    vrrp_instance VI_1 {
                        track_script {
                            chk_nginx
                        }
                    }
                vim keepalived_nginx_chk.sh
                    #!/bin/bash
                    killall -0 nginx &> /dev/null
                    EXIT=`echo $?`
                    if [[ $EXIT -ne 0 ]]
                    then
                        exit 1
                    fi
                        exit 0
            对于nginx的脚本优化:可以实现当Master端的nginx服务被关掉时,VIP转移至Backup端,如果Backup端nginx服务被关掉时,VIP又可以返回Master端(如果Master端的nginx服务一直没有启动VIP就会一直在Backup端,除非手动重启启动nginx服务或者Backup端nginx关闭)
                MASTER端:
                #!/bin/bash
                vip=192.168.80.12
                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
                        systemctl restart nginx.service
                        exit 0
                    ;;
                    backup)
                        notify backup
                        exit 0
                    ;;
                    fault)
                        notify fault
                        exit 0
                    ;;
                    *)
                        echo 'Usage:`basename $0` {master|backup|fault}'
                        exit 1
                    ;;
                esac
                BACKUP端:
                #!/bin/bash
                vip=192.168.80.12
                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
                        systemctl restart nginx.service
                        exit 0
                    ;;
                    fault)
                        notify fault
                        exit 0
                    ;;
                    *)
                        echo 'Usage:`basename $0` {master|backup|fault}'
                        exit 1
                    ;;
                esac
        
           注:根据马哥视频做的学习笔记,如有错误,欢迎指正;侵删;

           借鉴文章:https://blog.csdn.net/hzsunshine/article/details/62041036

      
 

你可能感兴趣的:(学习笔记,Linux,keepalived)