keepalived install

keepalived install

Download

  1. keepalived 介绍

    1
    2
    Keepalived是一个基于VRRP协议来实现的LVS服务高可用方案,可以利用其来避免单点故障.
    一个LVS服务会有2台服务器运行Keepalived,一台为主服务器(MASTER),一台为备份服务器(BACKUP),但是对外表现为一个虚拟IP,主服务器会发送特定的消息给备份服务器,当备份服务器收不到这个消息的时候,即主服务器宕机的时候,备份服务器就会接管虚拟IP,继续提供服务,从而保证了高可用性
  2. VRRP协议简介

    1
    2
    3
    4
    5
    在现实的网络环境中,两台需要通信的主机大多数情况下并没有直接的物理连接.对于这样的情况,它们之间路由怎样选择?主机如何选定到达目的主机的下一跳路由,这个问题通常的解决方法有二种:
    * 在主机上使用动态路由协议(RIP、OSPF等)
    * 在主机上配置静态路由

    很明显,在主机上配置动态路由是非常不切实际的,因为管理,维护成本以及是否支持等诸多问题.配置静态路由就变得十分流行,但路由器(或者说默认网关default gateway)却经常成为单点故障.VRRP的目的就是为了解决"静态路由单点故障"问题,VRRP通过一竞选(election)协议来动态的将路由任务交给LAN中虚拟路由器中的某台VRRP路由器
  3. VRRP工作机制

    1
    2
    3
    4
    5
    在一个VRRP虚拟路由器中,有多台物理的VRRP路由器,但是这多台的物理的机器并不能同时工作,而是由一台称为MASTER的负责路由工作,其它的都是BACKUP,MASTER并非一成不变,VRRP让每个VRRP路由器参与竞选,最终获胜的就是MASTER.MASTER拥有一些特权,比如:拥有虚拟路由器的IP地址,我们的主机就是用这个IP地址作为静态路由的.拥有特权的MASTER要负责转发发送给网关地址的包和响应ARP请求

    VRRP通过竞选协议来实现虚拟路由器的功能,所有的协议报文都是通过IP多播(multicast)包(多播地址224.0.0.18)形式发送的.虚拟路由器由VRID(范围0-255)和一组IP地址组成,对外表现为一个周知的MAC地址.所以,在一个虚拟路由器中,不管谁是MASTER,对外都是相同的MAC和IP(称之为VIP).客户端主机并不需要因为MASTER的改变而修改自己的路由配置,对客户端来说,这种主从的切换是透明的.

    在一个虚拟路由器中,只有作为MASTER的VRRP路由器会一直发送VRRP通告信息(VRRPAdvertisement message),BACKUP不会抢占MASTER,除非它的优先级(priority)更高.当MASTER不可用时(BACKUP收不到通告信息),多台BACKUP中优先级最高的这台会被抢占为MASTER.这种抢占是非常快速的(<1s),以保证服务的连续性.由于安全性考虑,VRRP包使用了加密协议进行加密.
  4. VRRP工作流程

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    1.初始化:    
    路由器启动时,如果路由器的优先级是255(最高优先级,路由器拥有路由器地址),要发送VRRP通告信息,并发送广播ARP信息通告路由器IP地址对应的MAC地址为路由虚拟MAC,设置通告信息定时器准备定时发送VRRP通告信息,转为MASTER状态;否则进入BACKUP状态,设置定时器检查定时检查是否收到MASTER的通告信息
    2.Master
    * 设置定时通告定时器
    * 用VRRP虚拟MAC地址响应路由器IP地址的ARP请求
    * 转发目的MAC是VRRP虚拟MAC的数据包
    * 如果是虚拟路由器IP的拥有者,将接受目的地址是虚拟路由器IP的数据包,否则丢弃
    * 当收到shutdown的事件时删除定时通告定时器,发送优先权级为0的通告包,转初始化状态
    * 如果定时通告定时器超时时,发送VRRP通告信息
    * 收到VRRP通告信息时,如果优先权为0,发送VRRP通告信息,否则判断数据的优先级是否高于本机,或相等而且实际IP地址大于本地实际IP,设置定时通告定时器,复位主机超时定时器,转BACKUP状态;否则的话,丢弃该通告包
    3.Backup
    * 设置主机超时定时器
    * 不能响应针对虚拟路由器IP的ARP请求信息
    * 丢弃所有目的MAC地址是虚拟路由器MAC地址的数据包
    * 不接受目的是虚拟路由器IP的所有数据包
    * 当收到shutdown的事件时删除主机超时定时器,转初始化状态
    * 主机超时定时器超时的时候,发送VRRP通告信息,广播ARP地址信息,转MASTER状态
    * 收到VRRP通告信息时,如果优先权为0,表示进入MASTER选举;否则判断数据的优先级是否高于本机,如果高的话承认MASTER有效,复位主机超时定时器;否则的话,丢弃该通告包
  5. ARP查询处理

    1
    当内部主机通过ARP查询虚拟路由器IP地址对应的MAC地址时,MASTER路由器回复的MAC地址为虚拟的VRRP的MAC地址,而不是实际网卡的MAC地址,这样在路由器切换时让内网机器觉察不到;而在路由器重新启动时,不能主动发送本机网卡的实际MAC地址.如果虚拟路由器开启的ARP代理(proxy_arp)功能,代理的ARP回应也回应VRRP虚拟MAC地址

keepalived 安装

  1. keepalived master/slave install

    1
    yum -y install keepalived ipvsadm
  2. keepalived master conf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    [root@master ~]# cat /etc/keepalived/keepalived.conf  
    ! Configuration File for keepalived
    global_defs {
    notification_email {
    smallasa@sina.com #配置管理员邮箱
    }
    notification_email_from root #配置发件人
    smtp_server 127.0.0.1 #配置邮件服务器
    smtp_connect_timeout 30
    router_id LVS_DEVEL
    }
    vrrp_instance VI_1 {
    state MASTER #配置模式
    interface eth0
    virtual_router_id 51
    priority 101 #配置优先级
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass 1111
    }
    virtual_ipaddress {
    192.168.18.200 #配置虚拟IP地址
    }
    }
    virtual_server 192.168.18.200 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    #persistence_timeout 50
    protocol TCP
    real_server 192.168.18.201 80 { #配置realaserver
    weight 1
    HTTP_GET { #监控配置
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    real_server 192.168.18.202 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    }
    sorry_server 127.0.0.1 80 #增加一行sorry_server
  3. keepalived slave conf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    [root@slave keepalived]# cat keepalived.conf  
    ! Configuration File for keepalived
    global_defs {
    notification_email {
    smallasa@sina.com
    }
    notification_email_from root
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id LVS_DEVEL
    }
    vrrp_instance VI_1 {
    state BACKUP #修改为BACKUP
    interface eth0
    virtual_router_id 51
    priority 100 #修改优先级
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass 1111
    }
    virtual_ipaddress {
    192.168.18.200
    }
    }
    virtual_server 192.168.18.200 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    #persistence_timeout 50
    protocol TCP
    real_server 192.168.18.201 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    real_server 192.168.18.202 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    }
    sorry_server 127.0.0.1 80 #增加一行sorry_server
  4. keepalived master/slave start

    1
    2
    3
    4
    5
    [root@master ~]# systemctl start keepalived
    [root@master ~]# systemctl enable keepalived

    [root@slave ~]# systemctl start keepalived
    [root@slave ~]# systemctl enable keepalived
  5. 查看LVS状态

    1
    2
    3
    4
    5
    6
    [root@master ~]# ipvsadm -L -n  
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
    -> RemoteAddress:Port Forward Weight ActiveConn InActConn
    TCP 192.168.18.200:80 rr
    -> 192.168.18.202:80 Route 1 0 0
  6. 通过stop keepalived 服务进行验证


keepalived 在不关闭keepalived情况下实现维护

  1. keepalived master conf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    [root@master ~]# cat /etc/keepalived/keepalived.conf  
    ! Configuration File for keepalived
    global_defs {
    notification_email {
    smallasa@sina.com
    }
    notification_email_from root
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id LVS_DEVEL
    }
    vrrp_script chk_schedown { #定义vrrp执行脚本
    script "[ -e /etc/keepalived/down ] && exit 1 || exit 0" #查看是否有down文件,有就进入维护模式
    interval 1 #监控间隔时间
    weight -5 #降低优先级
    fall 2 #失败次数
    rise 1 #成功数次
    }
    vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 101
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass 1111
    }
    virtual_ipaddress {
    192.168.18.200
    }
    track_script { #执行脚本
    chk_schedown
    }
    }
    virtual_server 192.168.18.200 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    protocol TCP
    real_server 192.168.18.201 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    real_server 192.168.18.202 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    sorry_server 127.0.0.1 80
    }
  2. keepalived slave conf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    [root@slave ~]# cat /etc/keepalived/keepalived.conf  
    ! Configuration File for keepalived
    global_defs {
    notification_email {
    smallasa@sina.com
    }
    notification_email_from root
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id LVS_DEVEL
    }
    vrrp_script chk_schedown {
    script "[ -e /etc/keepalived/down ] && exit 1 || exit 0"
    interval 1
    weight -5
    fall 2
    rise 1
    }
    vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass 1111
    }
    virtual_ipaddress {
    192.168.18.200
    }
    track_script {
    chk_schedown
    }
    }
    virtual_server 192.168.18.200 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    protocol TCP
    real_server 192.168.18.201 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    real_server 192.168.18.202 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    sorry_server 127.0.0.1 80

3.测试

1
2
3
4
5
[root@master ~]# cd /etc/keepalived
[root@master keepalived ~]# touch down

[root@master keepalived ~]# tail -f /var/log/messages
[root@master keepalived ~]# ip add show


keepalived 邮件报警通知

  1. keepalived master/slave 编辑报警邮件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    [root@x ~]#vim /etc/keepalived/notify.sh
    #!/bin/bash
    # Author: freeloda
    # description: An example of notify script
    # Usage: notify.sh -m|--mode {mm|mb} -s|--service SERVICE1,... -a|--address VIP -n|--notify {master|backup|falut} -h|--help
    contact='smallasa@sina.com'
    helpflag=0
    serviceflag=0
    modeflag=0
    addressflag=0
    notifyflag=0
    Usage() {
    echo "Usage: notify.sh [-m|--mode {mm|mb}] [-s|--service SERVICE1,...] <-a|--address VIP> <-n|--notify {master|backup|falut}>"
    echo "Usage: notify.sh -h|--help"
    }
    ParseOptions() {
    local I=1;
    if [ $# -gt 0 ]; then
    while [ $I -le $# ]; do
    case $1 in
    -s|--service)
    [ $# -lt 2 ] && return 3
    serviceflag=1
    services=(`echo $2|awk -F"," '{for(i=1;i<=NF;i++) print $i}'`)
    shift 2 ;;
    -h|--help)
    helpflag=1
    return 0
    shift
    ;;
    -a|--address)
    [ $# -lt 2 ] && return 3
    addressflag=1
    vip=$2
    shift 2
    ;;
    -m|--mode)
    [ $# -lt 2 ] && return 3
    mode=$2
    shift 2
    ;;
    -n|--notify)
    [ $# -lt 2 ] && return 3
    notifyflag=1
    notify=$2
    shift 2
    ;;
    *)
    echo "Wrong options..."
    Usage
    return 7
    ;;
    esac
    done
    return 0
    fi
    }
    #workspace=$(dirname $0)
    RestartService() {
    if [ ${#@} -gt 0 ]; then
    for I in $@; do
    if [ -x /etc/rc.d/init.d/$I ]; then
    /etc/rc.d/init.d/$I restart
    else
    echo "$I is not a valid service..."
    fi
    done
    fi
    }
    StopService() {
    if [ ${#@} -gt 0 ]; then
    for I in $@; do
    if [ -x /etc/rc.d/init.d/$I ]; then
    /etc/rc.d/init.d/$I stop
    else
    echo "$I is not a valid service..."
    fi
    done
    fi
    }
    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
    }
    # Main Function
    ParseOptions $@
    [ $? -ne 0 ] && Usage && exit 5
    [ $helpflag -eq 1 ] && Usage && exit 0
    if [ $addressflag -ne 1 -o $notifyflag -ne 1 ]; then
    Usage
    exit 2
    fi
    mode=${mode:-mb}
    case $notify in
    'master')
    if [ $serviceflag -eq 1 ]; then
    RestartService ${services[*]}
    fi
    Notify master
    ;;
    'backup')
    if [ $serviceflag -eq 1 ]; then
    if [ "$mode" == 'mb' ]; then
    StopService ${services[*]}
    else
    RestartService ${services[*]}
    fi
    fi
    Notify backup
    ;;
    'fault')
    Notify fault
    ;;
    *)
    Usage
    exit 4
    ;;
    esac
    [root@x ~]#chmod +x /etc/keepalived/notify.sh
    [root@x ~]#/etc/keepalived/notify.sh -m mb -a 1.1.1.1 -n master


    help:
    -s, --service SERVICE,...:指定服务脚本名称,当状态切换时可自动启动,重启或关闭此服务
    -a, --address VIP: 指定相关虚拟路由器的VIP地址
    -m, --mode {mm|mb}:指定虚拟路由的模型,mm表示主主,mb表示主备;它们表示相对于同一种服务而方,其VIP的工作类型
    -n, --notify {master|backup|fault}:指定通知的类型,即vrrp角色切换的目标角色
    -h, --help:获取脚本的使用帮助;
  2. keepalived master conf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    [root@master keepalived]# cat keepalived.conf  
    ! Configuration File for keepalived
    global_defs {
    notification_email {
    smallasa@sina.com
    }
    notification_email_from root
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id LVS_DEVEL
    }
    vrrp_script chk_schedown {
    script "[ -e /etc/keepalived/down ] && exit 1 || exit 0"
    interval 1
    weight -5
    fall 2
    rise 1
    }
    vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 101
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass 1111
    }
    virtual_ipaddress {
    192.168.18.200
    }
    track_script {
    chk_schedown
    }
    #增加以下三行
    notify_master "/etc/keepalived/notify.sh -n master -a 192.168.18.200"
    notify_backup "/etc/keepalived/notify.sh -n backup -a 192.168.18.200"
    notify_fault "/etc/keepalived/notify.sh -n fault -a 192.168.18.200"
    }
    virtual_server 192.168.18.200 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    protocol TCP
    real_server 192.168.18.201 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    real_server 192.168.18.202 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    sorry_server 127.0.0.1 80
    }
  3. keepalived slave conf

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    [root@slave keepalived]# cat keepalived.conf  
    ! Configuration File for keepalived
    global_defs {
    notification_email {
    smallasa@sina.com
    }
    notification_email_from root
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    router_id LVS_DEVEL
    }
    vrrp_script chk_schedown {
    script "[ -e /etc/keepalived/down ] && exit 1 || exit 0"
    interval 1
    weight -5
    fall 2
    rise 1
    }
    vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
    auth_type PASS
    auth_pass 1111
    }
    virtual_ipaddress {
    192.168.18.200
    }
    track_script {
    chk_schedown
    }
    #增加以下三行
    notify_master "/etc/keepalived/notify.sh -n master -a 192.168.18.200"
    notify_backup "/etc/keepalived/notify.sh -n backup -a 192.168.18.200"
    notify_fault "/etc/keepalived/notify.sh -n fault -a 192.168.18.200"
    }
    virtual_server 192.168.18.200 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.0
    protocol TCP
    real_server 192.168.18.201 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    real_server 192.168.18.202 80 {
    weight 1
    HTTP_GET {
    url {
    path /
    status_code 200
    }
    connect_timeout 2
    nb_get_retry 3
    delay_before_retry 1
    }
    }
    sorry_server 127.0.0.1 80
    }