程序员

Keepalived 相关分析与整理

2017-10-24  本文已影响308人  58bc06151329

文前说明

作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。

Keepalived 是集群管理中保证集群高可用的一个服务软件,用来防止单点故障。

1. VRRP

Keepalived 是以 VRRP (Virtual Router Redundancy Protocol)协议为实现基础的,即虚拟路由冗余协议。VRRP 协议是为消除在静态缺省路由环境下的缺省路由器单点故障引起的网络失效而设计的主备模式的协议,使得在发生故障而进行设备功能切换时可以不影响内外数据通信,不需要再修改内部网络的网络参数。VRRP 协议需要具有 IP 地址备份,优先路由选择,减少不必要的路由器间通信等功能。

1.1 VRRP 工作原理

1.2 VRRP 实现

1.2.1 master 选举方式

1.2.2 VRRP 协议状态

1)初始化状态(initialize)
2) 主机状态(master)
3)备份状态(backup)

1.2.3 ARP 查询处理

1.3 VRRP 协议定义

1.3.1 以太头

1.3.2 IP 头参数

1.3.3 VRRP 协议数据字段报文格式

属性 说明 宽度 默认值
Version 版本 4 位 在 RFC3768 中定义为 2
Type 类型 4 位 目前只定义一种类类型:通告数据,取值为 1
VRID(Virtual Rtr ID) 虚拟路由器 ID 8 位
Priority 优先级 8 位 具备冗余 IP 地址的设备的优先级为 255
Count IP Addrs VRRP 包中的 IP 地址数量 8 位
Auth Type 认证类型 8 位 RFC3768 中认证功能已经取消,此字段值定义 0(不认证),1 和 2 只作为对老版本的兼容。
Adver Int 通告包的发送间隔时间 8位 单位是秒,缺省是 1 秒。
Checksum 校验和 16 位 校验数据范围只是 VRRP 数据,即从 VRRP 的版本字段开始的数据,不包括 IP 头。
IP Address(es) 和虚拟路由器相关的 IP 地址,数量由 Count IP Addrs 决定 8 位
Authentication Data 认证数据 RFC3768 中定义该字段只是为了和老版本兼容,必须置 0

1.3.4 接收数据时的检查

2. Keepalived

2.1 Keepalived 的安装

使用 yum 源在线安装
yum install keepalived
离线 tar 包方式安装
[root@nodeA ~]# tar -zxvf keepalived-1.2.13.tar.gz
[root@nodeA ~]# cd keepalived-1.2.13
[root@nodeA keepalived-1.2.13]# ./configure
[root@nodeA keepalived-1.2.13]# make & make install
yum install mpfr-2.4.1-6.el6.x86_64.rpm
yum install cpp-4.4.7-18.el6.x86_64.rpm
yum install libgomp-4.4.7-18.el6.x86_64.rpm
yum install ppl-0.10.2-11.el6.x86_64.rpm
yum install cloog-ppl-0.15.7-1.2.el6.x86_64.rpm
yum install kernel-headers-2.6.32-696.el6.x86_64.rpm
yum install tzdata-2016j-1.el6.noarch.rpm
yum install glibc-2.12-1.209.el6.x86_64.rpm
yum install glibc-common-2.12-1.209.el6.x86_64.rpm
yum install glibc-headers-2.12-1.209.el6.x86_64.rpm
yum install glibc-devel-2.12-1.209.el6.x86_64.rpm
yum install libstdc++-4.4.7-18.el6.x86_64.rpm
yum isntall libstdc++-devel-4.4.7-18.el6.x86_64.rpm
yum install libgcc-4.4.7-18.el6.x86_64.rpm
yum install gcc-4.4.7-18.el6.x86_64.rpm
yum install gcc-c++-4.4.7-18.el6.x86_64.rpm
Keepalived configuration
------------------------
Keepalived version       : 1.2.13
Compiler                 : gcc
Compiler flags           : -g -O2
Extra Lib                : -lssl -lcrypto -lcrypt 
Use IPVS Framework       : Yes
IPVS sync daemon support : Yes
IPVS use libnl           : No
fwmark socket support    : Yes
Use VRRP Framework       : Yes
Use VRRP VMAC            : Yes
SNMP support             : No
SHA1 support             : No
Use Debug flags          : No
yum install -y libnl3.x86_64
yum install -y libnl3-devel.x86_64
yum install -y libnl3-cli.x86_64
yum install -y libnfnetlink.x86_64
yum install -y libnfnetlink-devel.x86_64
......
Make complete
make[1]: Leaving directory `/root/keepalived-1.2.13/keepalived'
make -C genhash
make[1]: Entering directory `/root/keepalived-1.2.13/genhash'
gcc -g -O2  -I/usr/src/linux/include -I/usr/src/linux/include -I../lib -Wall -Wunused -Wstrict-prototypes   -c -o main.o main.c
gcc -g -O2  -I/usr/src/linux/include -I/usr/src/linux/include -I../lib -Wall -Wunused -Wstrict-prototypes   -c -o sock.o sock.c
gcc -g -O2  -I/usr/src/linux/include -I/usr/src/linux/include -I../lib -Wall -Wunused -Wstrict-prototypes   -c -o layer4.o layer4.c
gcc -g -O2  -I/usr/src/linux/include -I/usr/src/linux/include -I../lib -Wall -Wunused -Wstrict-prototypes   -c -o http.o http.c
gcc -g -O2  -I/usr/src/linux/include -I/usr/src/linux/include -I../lib -Wall -Wunused -Wstrict-prototypes   -c -o ssl.o ssl.c
Building ../bin/genhash
strip ../bin/genhash

Make complete
make[1]: Leaving directory `/root/keepalived-1.2.13/genhash'

Make complete

2.2 Keepalived 模块

模块 说明
core keepalived 核心,复杂主进程的启动和维护,全局配置文件的加载解析等。
check 负责 healthchecker(健康检查),包括了各种健康检查方式,以及对应的配置的解析包括 LVS 的配置解析。
vrrp VRRP 子进程,实现 VRRP 协议。
libipfwc iptables(ipchains)库,配置 LVS 时用到。
libipvs 配置 LVS 用到。

2.3 Keepalived 配置

2.3.1 全局配置 Global Configuration

global_defs 区域
global_defs {
    notification_email {
        a@abc.com
        b@abc.com
        ...
    }
    notification_email_from admin@example.com
    smtp_server 127.0.0.1
    smtp_connect_timeout 30
    enable_traps
    router_id node1
}
配置项 说明
notification_email 故障发生时给谁发邮件通知。
notification_email_from 通知邮件从哪个地址发出。
smpt_server 通知邮件的 smtp 地址。
smtp_connect_timeout 连接 smtp 服务器的超时时间。
enable_traps 开启 SNMP 陷阱(Simple Network Management Protocol)。
router_id 标识本节点的字条串,通常为 hostname,但不一定非得是 hostname。故障发生时,邮件通知会用到。
static_ipaddress 和 static_routes 区域
static_ipaddress {
    10.210.214.163/24 brd 10.210.214.255 dev eth0
    ...
}
static_routes {
    10.0.0.0/8 via 10.210.214.1 dev eth0
    ...
}

2.3.2 VRRP 配置

vrrp_instance 和 vrrp_sync_group 区域
vrrp_sync_group VG_1 {
    group {
        inside_network   # name of vrrp_instance (below)
        outside_network  # One for each moveable IP.
        ...
    }
    notify_master /path/to_master.sh
    notify_backup /path/to_backup.sh
    notify_fault "/path/fault.sh VG_1"
    notify /path/notify.sh
    smtp_alert
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    use_vmac <VMAC_INTERFACE>
    dont_track_primary
    track_interface {
        eth0
        eth1
    }
    mcast_src_ip <IPADDR>
    lvs_sync_daemon_interface eth1
    garp_master_delay 10
    virtual_router_id 1
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 12345678
    }
    virtual_ipaddress {
        10.210.214.253/24 brd 10.210.214.255 dev eth0
        192.168.1.11/24 brd 192.168.1.255 dev eth1
    }
    virtual_routes {
        172.16.0.0/12 via 10.210.214.1
        192.168.1.0/24 via 192.168.1.1 dev eth1
        default via 202.102.152.1
    }
    track_script {
        check_running
    }
    nopreempt
    preempt_delay 300
    debug
    notify_master <STRING>|<QUOTED-STRING>
    notify_backup <STRING>|<QUOTED-STRING>
    notify_fault <STRING>|<QUOTED-STRING>
    notify <STRING>|<QUOTED-STRING>
    smtp_alert
}
配置项 说明
notify_master 分别表示切换为主时所执行的脚本。
notify_backup 分别表示切换为备时所执行的脚本。
notify_fault 分别表示切换出错时所执行的脚本。
notify 表示任何一状态切换时都会调用该脚本,并且该脚本在以上三个脚本执行完成之后进行调用,keepalived 会自动传递三个参数(1 = "GROUP"|"INSTANCE",2 = name of group or instance,$3 = target state of transition(MASTER/BACKUP/FAULT))。
smtp_alert 表示是否开启邮件通知(用全局区域的邮件设置来发通知)。
state 可以是 MASTER 或 BACKUP,不过当其他节点 keepalived 启动时会将 Priority(优先级)比较大的节点选举为 MASTER,因此该项其实没有实质用途。
interface 节点固有 IP(非 VIP)的网卡,用来发 VRRP 包。因为在配置虚拟 IP 的时候必须是在已有的网卡上添加的。
use_vmac 是否使用 VRRP 的虚拟 MAC 地址。不配置即不使用
dont_track_primary 忽略 VRRP 网卡错误。(默认未设置)
track_interface 设置额外的监控,监控以下网卡,如果任何一个不通就会切换到 FALT 状态。(可选项)
mcast_src_ip 修改 vrrp 组播包的源地址,默认源地址为 master 的 IP。(由于是组播,因此即使修改了源地址,该 master 还是能收到回应)。这里实际上就是在哪个地址上发送 VRRP 通告,一定要选择稳定的网卡端口来发送,如果没有设置那么就用默认的绑定的网卡的 IP,也就是 interface 指定的 IP 地址。
lvs_sync_daemon_interface 绑定 lvs syncd 的网卡。
garp_master_delay 当切为主状态后多久更新 ARP 缓存,默认 5 秒。
virtual_router_id 设置 VRID,取值在 0-255 之间,用来区分多个 instance 的 VRRP 组播(同一网段中 virtual_router_id 的值不能重复,否则会出错)。将决定多播的 MAC 地址
priority 用来选举 master,要成为 master,这个选项的值最好高于其他机器 50 个点,该项取值范围是 1-255(在此范围之外会被识别成默认值 100)。
advert_int 发 VRRP 包的时间间隔,即多久进行一次 master 选举(可以认为是健康查检时间间隔,默认为 1 秒)。
authentication 认证区域,认证类型(auth_type)有 PASS 和 HA(IPSEC),推荐使用 PASS(密码只识别前 8 位)。认证密码(auth_pass)。
virtual_ipaddress VIP(虚拟 IP 地址),随着 state 的变化而增加删除,当 state 为 master 的时候就添加,当 state 为 backup 的时候删除,主要由优先级来决定的,和 state 设置的值没有多大关系,可以设置多个 IP 地址。
virtual_routes 虚拟路由,当 IP 漂过来之后需要添加的路由信息。原理和 virtual ipaddress 一样,只不过这里是增加和删除路由。
virtual_ipaddress_excluded 发送的 VRRP 包里不包含的 IP 地址,为减少回应 VRRP 包的个数。在网卡上绑定的 IP 地址比较多的时候用。
lvs_sync_daemon_interface lvs syncd 绑定的网卡。
nopreempt 允许一个 priority 比较低的节点作为 master,即使有 priority 更高的节点启动。设置不抢占,只能设置在 state 为 backup 的节点上。次要实现类似于关闭 auto failback 的功能需要将所有节点的 state 都设置为 backup,或者将 master 节点的priority 设置的比 backup 低。
preempt_delay 抢占延迟,master 启动多久之后进行接管资源(VIP/Route 信息等),前提是没有 nopreempt 选项。
debug debug 级别。
track_script 引用健康检查脚本
vrrp_script 区域
vrrp_script check_running {
      script "/usr/local/bin/check_running"
      interval 10
      weight 10 
}
配置项 说明
script 健康检查脚本名称
interval 脚本执行间隔
weight 脚本结果导致的优先级变更:10 表示优先级 +10;-10 则表示优先级 -10。

VRRP 脚本 vrrp_script 和 VRRP 实例 vrrp_instance 属于同一个级别。

2.3.3 LVS 配置

virtual_server_group 区域
virtual_server_group <STRING> {
# VIP port
<IPADDR> <PORT>
<IPADDR> <PORT>
fwmark <INT>
}
virtual_server 区域
virtual_server IP Port {
    delay_loop <INT>
    lb_algo rr|wrr|lc|wlc|lblc|sh|dh
    lb_kind NAT|DR|TUN
    persistence_timeout <INT>
    persistence_granularity <NETMASK>
    protocol TCP
    ha_suspend
    virtualhost <STRING>
    alpha
    omega
    quorum <INT>
    hysteresis <INT>
    quorum_up <STRING>|<QUOTED-STRING>
    quorum_down <STRING>|<QUOTED-STRING>
    sorry_server <IPADDR> <PORT>
    real_server <IPADDR> <PORT> {
        weight <INT>
        inhibit_on_failure
        notify_up <STRING>|<QUOTED-STRING>
        notify_down <STRING>|<QUOTED-STRING>
        # HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK
        HTTP_GET|SSL_GET {
            url {
                path <STRING>
                # Digest computed with genhash
                digest <STRING>
                status_code <INT>
            }
            connect_port <PORT>
            connect_timeout <INT>
            nb_get_retry <INT>
            delay_before_retry <INT>
        }
    }
}
配置项 说明
delay_loop 延迟轮询时间(单位秒)。
lb_algo 后端调试算法(load balancing algorithm)。
lb_kind LVS 集群模式 NAT/DR/TUN。
persistence_timeout 会话保持时间(秒为单位),即以用户在指定秒内被分配到同一个后端 realserver。
persistence_granularity LVS 会话保持粒度,ipvsadm 中的 -M 参数,默认是 0xffffffff,即每个客户端都做会话保持。
protocol 健康检查用的是 TCP 还是 UDP。
virtualhost 用来给 HTTP_GET 和 SSL_GET 配置请求 header 的。
sorry_server 当所有 real server 宕掉时,sorry server 顶替。
real_server 真正提供服务的服务器。
weight 权重。
notify_up/down 当 real server 宕掉或启动时执行的脚本。
健康检查方式 健康检查方式一共有 HTTP_GET、SSL_GET、TCP_CHECK、SMTP_CHECK、MISC_CHECK。
path 请求 real serserver 上的路径。
digest/status_code 分别表示用 genhash 算出的结果和 http 状态码。
bindto 健康检查的 IP 地址。
connect_port 健康检查,如果端口通则认为服务器正常。
connect_timeout 表示超时时长。
nb_get_retry 重试次数。
delay_before_retry 下次重试的时间延迟。
misc_path <STRING>|<QUOTED-STRING> 外部程序或脚本。
misc_timeout <INT> 脚本或程序执行超时时间。
misc_dynamic 可以非常精确的来调整权重,是后端每天服务器的压力都能均衡调配,这个主要是通过执行的程序或脚本返回的状态代码来动态调整 weight 值,使权重根据真实的后端压力来适当调整。(返回 0:健康检查没问题,不修改权重;返回 1:健康检查失败,权重设置为 0;返回 2-255:健康检查没问题,但是权重却要根据返回代码修改为返回码 -2,例如如果程序或脚本执行后返回的代码为 200,那么权重这回被修改为 200-2。
TCP_CHECK {
    connect_port 80
    bindto 192.168.1.1
    connect_timeout 4
} 
SMTP_CHECK {
host {
    connect_ip <IP ADDRESS>
    connect_port <PORT> 
    14 KEEPALIVED
    bindto <IP ADDRESS>
}
connect_timeout <INTEGER>
retry <INTEGER>
delay_before_retry <INTEGER>
helo_name <STRING>|<QUOTED-STRING>
}
MISC_CHECK
{
      misc_path <STRING>|<QUOTED-STRING>   
      misc_timeout <INT>                                         
      misc_dynamic
}

2.4 使用 Keepalived 实现双机热备

使用 Keepalived 实现双机热备

准备工作

注意:务必要设置防火墙开放端口,VRRP 协议需要 master 不断发送 “状态正常” 的广播信息,一旦 backup 不能收到 master 的广播信息,backup 会尝试切换到 master 状态来接管 VIP。

iptables -I INPUT -i eth0 -d 224.0.0.0/8 -p vrrp -j ACCEPT
iptables -I OUTPUT -o eth0 -d 224.0.0.0/8 -p vrrp -j ACCEPT
service iptables restart

安装并配置 Keepalived

global_defs {
   router_id nodeA
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.102.30
    }
}
global_defs {
   router_id nodeB
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.102.30
    }
}
[root@nodeA keepalived]# tailf /var/log/messages 
Oct 26 02:30:13 nodeA Keepalived_vrrp[12147]: Configuration is using : 61594 Bytes
Oct 26 02:30:13 nodeA Keepalived_vrrp[12147]: Using LinkWatch kernel netlink reflector...
Oct 26 02:30:13 nodeA Keepalived_vrrp[12147]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)]
Oct 26 02:30:13 nodeA Keepalived_healthcheckers[12146]: Configuration is using : 6137 Bytes
Oct 26 02:30:13 nodeA Keepalived_healthcheckers[12146]: Using LinkWatch kernel netlink reflector...
Oct 26 02:30:14 nodeA Keepalived_vrrp[12147]: VRRP_Instance(VI_1) Transition to MASTER STATE
Oct 26 02:30:15 nodeA Keepalived_vrrp[12147]: VRRP_Instance(VI_1) Entering MASTER STATE
Oct 26 02:30:15 nodeA Keepalived_vrrp[12147]: VRRP_Instance(VI_1) setting protocol VIPs.
Oct 26 02:30:15 nodeA Keepalived_vrrp[12147]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.102.30
Oct 26 02:30:15 nodeA Keepalived_healthcheckers[12146]: Netlink reflector reports IP 192.168.102.30 added
Oct 26 02:30:20 nodeA Keepalived_vrrp[12147]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.102.30
[root@nodeA ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:06:15:3b brd ff:ff:ff:ff:ff:ff
    inet 192.168.102.31/21 brd 192.168.103.255 scope global eth0
    inet 192.168.102.30/32 scope global eth0
    inet6 fe80::20c:29ff:fe06:153b/64 scope link 
       valid_lft forever preferred_lft forever
Oct 26 06:57:52 nodeB Keepalived_vrrp[3333]: Opening file '/etc/keepalived/keepalived.conf'.
Oct 26 06:57:52 nodeB Keepalived_healthcheckers[3332]: Registering Kernel netlink reflector
Oct 26 06:57:52 nodeB Keepalived_healthcheckers[3332]: Registering Kernel netlink command channel
Oct 26 06:57:52 nodeB Keepalived_healthcheckers[3332]: Opening file '/etc/keepalived/keepalived.conf'.
Oct 26 06:57:52 nodeB Keepalived_healthcheckers[3332]: Configuration is using : 6115 Bytes
Oct 26 06:57:52 nodeB Keepalived_vrrp[3333]: Configuration is using : 61572 Bytes
Oct 26 06:57:52 nodeB Keepalived_vrrp[3333]: Using LinkWatch kernel netlink reflector...
Oct 26 06:57:52 nodeB Keepalived_vrrp[3333]: VRRP_Instance(VI_1) Entering BACKUP STATE
Oct 26 06:57:52 nodeB Keepalived_vrrp[3333]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)]
Oct 26 06:57:52 nodeB Keepalived_healthcheckers[3332]: Using LinkWatch kernel netlink reflector...
[root@nodeA ~]# lsmod | grep ip_vs
ip_vs                 141092  0 
nf_conntrack          133387  3 ip_vs,xt_conntrack,nf_conntrack_ipv4
libcrc32c              12644  3 xfs,ip_vs,nf_conntrack

2.5 防火墙配置

iptables -I INPUT -i ${interface} -d 224.0.0.0/8 -p vrrp -j ACCEPT
iptables -I OUTPUT -o ${interface} -d 224.0.0.0/8 -p vrrp -j ACCEPT
service iptables save
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface ${interface} --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 --out-interface ${interface} --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload

2.6 selinux 配置

上一篇 下一篇

猜你喜欢

热点阅读