Keepalived用户指南

介绍

负载均衡(Load Balance)是一种跨真实服务器集群分发IP流量的方法,提供一个或多个高可用的虚拟服务。在设计负载均衡拓扑结构时,考虑负载均衡器本身和它背后真正服务器的可用性也是很重要的。

Keepalived提供了兼具负载均衡和高可用性的框架。负载均衡框架依赖于众所周知且广泛使用的Linux Virtual Server(IPVS)内核模块,该模块提供第4层负载均衡。Keepalived实现了一组健康检查程序,根据其健康状况动态地、自适应地维护和管理负载均衡的服务器池。高可用性是通过虚拟路由器冗余协议(VRRP)来实现的,VRRP是路由器故障转移的基础。此外,Keepalived实现了一组到VRRP有限状态机的钩子,提供low-level和高速的协议交互。每个Keepalived框架可以单独使用,也可以一起使用,以提供灵活的基础架构。

在本文的上下文中,负载均衡器也可能被称为导向器或LVS路由器。

简而言之,Keepalived提供了2个主要功能:

  • LVS系统的健康检查
  • 实现VRRPv2堆栈来处理负载均衡器的故障转移

软件设计

Keepalived是用纯ANSI/ISO C编写的。该软件围绕一个中央I/O多路复用器进行连接,以提供实时网络设计。主要的设计重点是在所有元素之间提供同质的模块化。这就是创建核心库来删除重复代码的原因。目标是生成安全可靠的代码,确保生产的健壮性和稳定性。

为了确保健壮性和稳定性,守护进程被切分为3个不同进程:

  • 一个极简的父进程,负责fork和监控子进程
  • 两个子进程,一个负责VRRP框架,另一个负责健康检查

每个子进程都有自己的调度I/O多路复用器,这种方式优化了VRRP调度抖动,因为VRRP调度比健康检查更敏感/关键。这种拆分设计最小化了健康检查依赖库的使用,并将其自己的操作最小化到空闲主循环,以避免由自身引起的故障。

父进程监控框架称为watchdog,设计是每个子进程打开一个accept unix域套接字,然后在守护进程引导时,父进程连接到那些unix域套接字并向子进程发送周期性(5秒)的hello数据包。如果父进程无法向远程连接的unix域套接字发送hello数据包,则只需重启子进程。

这种看门狗设计提供了2个好处,首先从父进程发送到远程连接子进程的hello数据包是通过I/O多路复用器调度程序完成的,它可以检测子进程调度框架中的deadloop。第二个好处是通过使用sysV信号来检测死亡的子进程。运行时,您将看到如下的进程列表:

PID    111    Keepalived        < - 监视子进程的父进程
       112    \ _ Keepalived    < - VRRP子进程
       113    \ _ Keepalived    < - 健康检查子进程

内核组件

Keepalived使用了4个Linux内核组件:

  1. LVS框架:使用getsockopt和setsockopt调用来获取和设置套接字上的选项
  2. Netfilter框架:支持NAT和Masquerading的IPVS代码
  3. Netlink接口:在网络接口上设置和删除VRRP虚拟IP
  4. 组播:VRRP通告发送到保留的VRRP组播组(224.0.0.18)

原子元素

_images/software_design.png

控制平面

Keepalived配置通过keepalived.conf文件完成。一个编译器设计用于解析。解析器使用关键字树层次结构来使用特定处理器映射每个配置关键字。中央多级递归函数读取配置文件并遍历关键字树。在解析期间,配置文件被转换为内部的内存表示。

调度程序-I/O多路复用器

所有事件都相同过程中进行调度。Keepalived是一个单一的过程。Keepalived是一个网络路由软件,它是如此地接近I/O。这里使用的设计是一个中央的select(…),负责调度所有内部任务。该框架提供了自己的线程抽象,针对网络目的进行了优化,没有使用POSIX线程库。

内存管理

此框架提供了对一些通用内存管理方法的访问,如allocation、reallocation和release等。此框架可用于两种模式:normal_mode和debug_mode。当使用debug_mode时,它提供了一种消除和跟踪内存泄露的强大方式。这种底层环境通过跟踪内存分配和释放来提供缓冲区欠载保护。使用的所有缓冲区都是固定长度的,以防止最终的缓冲区溢出。

核心组件

此框架定义了所有代码中使用的一些通用和全局库。这些库是:html解析,链表,定时器,向量,格式化字符串,缓冲区转储,网络工具,守护进程管理,pid处理,低级别4层TCP。这里的目标是尽可能地分解代码,以限制过多的冗余代码和增加模块化。

WatchDog

此框架提供子进程监控(VRRP和健康检查)。每个子进程都接受到自己的监视器unix域套接字的连接。父进程向子进程的该unix域套接字发送hello数据包。Hello数据包使用父进程的I/O多路复用器发送,并使用子进程的I/O多路复用器接收/处理。如果父进程检测到断开的管道,它将使用sysV信号测试子进程是否存活并重新启动子进程。

检查器

这是Keepalived的主要功能之一。检查器负责真实服务器的健康检测。检查器测试真实服务器是否处于活动状态,此测试以二元的决策结束:从LVS拓扑中移除或添加真实服务器。检查器内部设计为实时网络软件,它使用完全多线程的FSM(有限状态机)设计。此检查器堆栈提供对应4层到5/7层测试结果的LVS拓扑操作。它在由父进程监控的独立子进程中运行。

VRRP堆栈

Keepalived的另一个重要功能。VRRP(虚拟路由器冗余协议:RFC 2338)专注于导向器接管,它为路由器备份提供底层设计。它实现了完整的IETF RFC2338标准,其中包含为LVS和防火墙设计的一些规定和扩展。它实现了vrrp_sync_group扩展,可在协议接管后保证持久性路由路径。它使用MD5-96bit加密配置实现IPSEC-AH,以提供安全的协议通告交换。有关VRRP的更多信息,请阅读RFC。一个重要的事情就是:VRRP代码被设计为独立使用,因此可以在没有LVS支持的情况下工作。它在由父进程监控的独立子进程中运行。

系统调用

此框架提供了运行额外系统脚本的能力。它主要用于MISC检查器。在VRRP框架中,它提供了在协议状态转换期间启动额外脚本的能力。系统调用通过fork子进程来进行,以便不会扰乱全局调度定时器。

SMTP

SMTP协议用于管理通知。它使用多线程FSM设计实现了IEFT RFC 821。在健康检查活动和VRRP协议状态转换时进行管理通知。SMTP协议是很常用的,因此可以与任何其他通知子系统对接,如GSM-SMS,寻呼机等。

IPVS封装器

此框架用于将规则发送到内核IPVS代码。它提供Keepalived内部数据表示和IPVS rule_user表示之间的转换。它使用IPVS libipvs来保持与IPVS代码的通用集成。

IPVS

来自Wensong的LinuxVirtualServer.org开源项目提供的Linux内核代码。IPVS(IP Virtual Server)在Linux内核中实现传输层负载均衡,也称为第4层交换。

NETLINK

由Alexey Kuznetov 提供的Linux内核代码,具有非常好的高级路由框架和子系统功能。Netlink用于在内核和用户空间进程之间传输消息。它由用于用户空间进程的标准套接字接口和用于内核模块的内部内核API组成。

Syslog

所有的Keepalived守护进程通知消通过syslog服务进行记录。

健康检查框架

每个健康检查都注册到全局调度框架。这些健康检查工作线程实现了以下类型的运行状况检查:

TCP_CHECK

工作在4层。为确保检查,我们通过非阻塞/带超时时间的TCP连接进行常规检查。如果远程服务器未回复此请求(超时),则测试错误,服务器将从服务器池中移除。

HTTP_GET

工作在5层。对指定的URL执行HTTP GET。然后使用MD5算法对HTTP GET结果进行求和。如果此总和与预期值不匹配,则测试错误,服务器将从服务器池中移除。此模块实现了对同一服务的多URL get检查。如果您使用的服务器托管了多个应用服务,则此功能非常有用。此功能使您能检查应用服务是否正常运行。MD5摘要使用gethash工具(包含在Keepalived包中)生成。

SSL_GET

与HTTP_GET相同,但使用SSL连接到远程Web服务器。

MISC_CHECK

此检查允许用户定义的脚本作为运行状况检查程序运行。结果必须为0或1。脚本在导向器内运行,这是测试内部应用程序的理想方法。可以使用完整路径(例如/path_to_script/script.sh)调用不带参数的运行脚本。那些需要参数的必须用双引号括起来(例如“/path_to_script/script.sh arg 1 … arg n ”)

Keepalived的目标是定义一个易于扩展的通用框架,用于添加新的检查器模块。如果您对现有的检查器的开发感兴趣,请查看源代码中的keepalived/check目录:

故障切换(VRRP)框架

Keepalived实现了用于导向器故障切换的VRRP协议。在实现的VRRP堆栈中,VRRP数据包调度程序负责为每个VRRP实例多路分发特定的I/O。

在RFC2338中,VRRP被定义为:

VRRP指定一个选举协议,负责动态分配虚拟路由器到LAN上的一个VRRP路由器。控制与虚拟路由器关联的IP地址的VRRP路由器称为Master(主路由器), 对发送到这些IP地址的数据包进行转发。当Master不可用时,选举过程提供转发责任的动态故障切换。这允许终端主机将LAN上任何的虚拟路由器IP 地址作为默认的第一跳路由器。使用VRRP的优点就是,无需在每个终端主机上配置动态路由或路由发现协议,就可以获得更高可用性的默认路径。[rfc2338]

注解

该框架与LVS无关,因此您可以将其用于LVS路由器故障切换,即使对于其他需要热备用协议的Linux路由器也是如此。出于设计和健壮性原因,此框架已经完全集成在Keepalived守护进程中。

该框架提供的主要功能是:

  • 故障切换:原生的VRRP协议意图,基于漫游的VRRP VIP集;
  • VRRP实例同步:我们可以指定2个VRRP实例之间的状态监控,也称为VRRP同步组。它保证2个VRRP实例保持相同状态,同步实例间相互监视;
  • 漂亮的回退
  • 通告数据包完整性:使用使用IPSEC-AH ICV;
  • 系统调用:在VRRP状态转换期间,可以调用外部脚本/程序。

使用VRRP和虚拟MAC地址的注意事项

为了减少接管的影响,某些网络环境需要使用VRRP和 VMAC 地址。为了实现这一目标,Keepalived VRRP框架通过在配置文件中调用 use_mac 关键字来实现VMAC支持。

在内部,Keepalived代码会引入虚拟接口,每个接口专用于特定的 virtual_router。Keepalived使用Linux内核 macvlan 驱动程序来定义这些接口。因此,必须使用支持macvlan编译的内核。

此外,我们会提到VRRP VMAC仅适用于包含以下补丁的内核:

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=729e72a10930ef765c11a5a35031ba47f18221c4

默认情况下,macvlan接口处于 VEPA 模式,会过滤掉源MAC地址与macvlan接口匹配的数据包。设置为私有模式后macvlan接口就不会基于源MAC地址进行过滤了。

或者,您可以指定 vmac_xmit_base,这将导致VRRP消息在底层接口上传输和接收,而 ARP 将在VMAC接口上发生。

您可能还需要调整物理接口以解决众所周知的ARP问题。如果您遇到问题,请尝试以下配置:

  1. 全局配置

    net.ipv4.conf.all.arp_ignore = 1
    net.ipv4.conf.all.arp_announce = 1
    net.ipv4.conf.all.arp_filter = 0
    
  2. 物理接口配置

对于运行VRRP实例的物理以太网接口,请使用:

net.ipv4.conf.eth0.arp_filter = 1
  1. VMAC接口

考虑以下的VRRP配置:

vrrp_instance instance1 {
    state BACKUP
    interface eth0
    virtual_router_id 250
    use_vmac
        vmac_xmit_base         # Transmit VRRP adverts over physical interface
    priority 150
    advert_int 1
    virtual_ipaddress {
        10.0.0.254
    }
}

use_vmac 关键字将驱动Keepalived代码来创建一个名字如 vrrp.250 的macvlan接口(默认的内部范例是 vrrp.{virtual_router_id},您可以通过给 use_vmac 关键字赋一个参数来覆盖这个命名,例如:use_vmac vrrp250)。

然后,您需要配置接口:

net.ipv4.conf.vrrp.250.arp_filter = 0
net.ipv4.conf.vrrp.250.accept_local = 1 (this is needed for the address owner case)
net.ipv4.conf.vrrp.250.rp_filter = 0

您可以创建 notify_master 脚本来自动执行此配置步骤:

vrrp_instance instance1 {
    state BACKUP
    interface eth0
    virtual_router_id 250
    use_vmac
    priority 150
    advert_int 1
    virtual_ipaddress {
        10.0.0.254
    }
    notify_master "/usr/local/bin/vmac_tweak.sh vrrp.250"
}

负载均衡技术

基于NAT的虚拟服务器(VS/NAT)

当负载均衡器(或LVS路由器)具有两个网络接口卡(NIC)时,使用``NAT``路由,一个接口卡分配面向外部的IP地址,另一个分配私有的面向内部的IP地址。在此方法中,负载均衡器接收来自公共网络上的用户请求,并使用网络地址转换(NAT)将这些请求转发到位于专用网络上的真实服务器。当真实服务器响应用户的请求时,响应也会进行反向转换。

因此,带来的一个优点是真实服务器隐藏在负载均衡器后面而不受到公共网络的影响。另一个优点是IP地址保留,因为专用网络可以使用私有地址范围。

主要缺点是负载均衡器成为了瓶颈。它不仅要服务还要响应来自公共网络的用户请求,同时还要向私有的真实服务器进行转发。

基于隧道的虚拟服务器(VS/TUN)

待补充

基于直接路由的虚拟服务器(VS/DR)

在直接路由中,用户向负载均衡器上的 VIP 发出请求。负载均衡器使用其预定义的调度(分配)算法将请求转发到适当的真实服务器。与使用NAT路由不同,真实服务器直接将响应发送到公共用户,绕过了通过负载均衡器路由的需要。

此路由方法的主要优点是可扩展性,因为负载均衡器不承担将真实服务器的响应数据包路由到公共用户的额外责任。

这种路由方法的缺点在于其ARP限制。为了使真实服务器直接响应公共用户的请求,每个真实服务器在发送响应时必须使用VIP作为其源地址。因此,VIP和MAC地址的组合在负载均衡器和每个真实服务器之间共享,这可能导致真实服务器直接接收请求,绕过传入请求的负载均衡器。有一些方法可以解决这个问题,但代价是增加了配置的复杂性和可管理性。

安装Keepalived

我们可以从各种发行版的软件仓库安装Keepalived,或者从编代码编译安装。虽然从软件仓库进行安装通常是在系统上运行Keepalived的最快方法,但软件仓库中可用的Keepalived版本通常是最新的可用稳定版本之后的一些版本。

从软件仓库安装

在Red Hat Enterprise Linux上安装

Red Hat 6.4 开始,Red Hat和克隆版本已经将Keepalived包含在基本的软件仓库中。因此,运行以下命令以使用 YUM 安装Keepalived包和所有必需的依赖项:

yum install keepalived

在Debian上安装

运行如下命令以使用 DebianAPT 包处理实用程序安装Keepalived包和所有必需的依赖项:

apt-get install keepalived

从源代码编译和构建

要运行最新的稳定版本,请从源代码编译Keepalived。编译Keepalived需要编译器,OpenSSLNetlink 库。您可以选择安装 SNMP 支持所需的 Net-SNMP

在RHEL/Centos上安装先决条件

在RHEL上,安装如下先决条件:

yum install curl gcc openssl-devel libnl3-devel net-snmp-devel

在Debian上安装先决条件

在Debian上,安装如下先决条件:

apt-get install curl gcc libssl-dev libnl-3-dev libnl-genl-3-dev libsnmp-dev

构建和安装

使用 curl 或任何其他传输工具(如 wget)下载Keepalived。该软件可以从 Keepalived官网Github仓库 获得。然后,进行编译:

curl --progress http://keepalived.org/software/keepalived-1.2.15.tar.gz | tar xz
cd keepalived-1.2.15
./configure
make
sudo make install

从源代码编译时一般建议指定PREFIX。例如:

./configure --prefix=/usr/local/keepalived-1.2.15

这样,只需删除父目录即可轻松卸载Keepalived的编译版本。此外,这种安装方法允许安装多个版本的Keepalived,而不会互相覆盖。使用符号链接指向所需的版本。例如,您的目录结构可能如下所示:

[root@lvs1 ~]# cd /usr/local
[root@lvs1 local]# ls -l
total 12
lrwxrwxrwx. 1 root root   17 Feb 24 20:23 keepalived -> keepalived-1.2.15
drwxr-xr-x. 2 root root 4096 Feb 24 20:22 keepalived-1.2.13
drwxr-xr-x. 2 root root 4096 Feb 24 20:22 keepalived-1.2.14
drwxr-xr-x. 2 root root 4096 Feb 24 20:22 keepalived-1.2.15

设置Init脚本

编译之后,创建一个 Init 脚本以控制Keepalived守护进程。

在RHEL上:

ln -s /etc/rc.d/init.d/keepalived.init /etc/rc.d/rc3.d/S99keepalived

在Debian上:

ln -s /etc/init.d/keepalived.init /etc/rc2.d/S99keepalived

注意:该链接应该添加到默认的运行级别目录中。

Keepalived配置简介

Keepalived配置文件使用以下概要

全局定义概要

global_defs {
    notification_email {
        email
        email
    }
    notification_email_from email
    smtp_server host
    smtp_connect_timeout num
    lvs_id string
}
关键字 定义 类型
global_defs 标识全局定义配置块 Block
notification_email 用于收取邮件通知的电子邮箱 List
notification_email_from 处理“MAIL FROM:”SMTP命令时使用的电子邮箱 List
smtp_server 用于发送邮件通知的SMTP服务器 alphanum
smtp_connection_timeout 指定SMTP流处理的超时时间 numerical
lvs_id 指定LVS导向器的名字 alphanum

email类型:使用 SMTP RFC 中指定字符集的字符串,例如:user@domain.com

虚拟服务器定义概要

virtual_server (@IP PORT)|(fwmark num) {
    delay_loop num
    lb_algo rr|wrr|lc|wlc|sh|dh|lblc
    lb_kind NAT|DR|TUN
    (nat_mask @IP)
    persistence_timeout num
    persistence_granularity @IP
    virtualhost string
    protocol TCP|UDP

    sorry_server @IP PORT
    real_server @IP PORT {
        weight num
        TCP_CHECK {
            connect_port num
            connect_timeout num
        }
    }
    real_server @IP PORT {
        weight num
        MISC_CHECK {
            misc_path /path_to_script/script.sh
            (or misc_path “ /path_to_script/script.sh <arg_list>”)
        }
    }
}
real_server @IP PORT {
    weight num
    HTTP_GET|SSL_GET {
        url { # You can add multiple url block
            path alphanum
            digest alphanum
        }
        connect_port num
        connect_timeout num
        retry num
        delay_before_retry num
    }
}
关键字 定义 类型
virtual_server 标识虚拟服务器定义块 Block
fwmark 指定虚拟服务器是FWMARK  
delay_loop 以秒为单位指定检查之间的间隔时间 numerical
lb_algo 选择一个特定的调度程序(rr|wrr|lc|wlc…) string
lb_kind 选择一个特定的转发方法(NAT|DR|TUN) string
persistence_timeout 为持久连接指定超时时间 numerical
persistence_granularity 为持久连接指定粒度掩码  
virtualhost 指定用于HTTP|SSL_GET的虚拟主机 alphanum
protocol 指定协议类型(TCP|UDP) numerical
sorry_server 当所有真实服务器都宕掉时添加到池中的服务器  
real_server 指定一个真实服务器成员  
weight 为真实服务器指定负载均衡的权重 numerical
TCP_CHECK 使用TCP连接检查真实服务器的可用性  
MISC_CHECK 使用用户定义的脚本检查真实服务器的可用性  
misc_path 标识要运行脚本的完整路径 path
HTTP_GET 使用HTTP GET请求检查真实服务器的可用性  
SSL_GET 使用HTTPS GET请求检查真实服务器的可用性  
url 标识url定义块 Block
path 指定url路径 alphanum
digest 指定特定url路径的摘要 alphanum
connect_port 指定连接远程服务器的TCP端口 numerical
connect_timeout 指定连接远程服务器的超时时间 numerical
retry 最大重试次数 numerical
delay_before_retry 两次连续重试之间的延迟 numerical

注解

如果您没有将LVS与Linux内核2.2系统一起使用,那么“net_mask”关键字就是过时的。此标志使您能够定义反向NAT粒度。

注解

目前,健康检查框架只实现了基于TCP协议的服务监控。

注解

类型“path”指的是被调用脚本的完整路径。对于需要参数的脚本,路径和参数必须用双引号括起来。

VRRP实例定义概要

vrrp_sync_group string {
    group {
        string
        string
    }
    notify_master /path_to_script/script_master.sh
        (or notify_master “ /path_to_script/script_master.sh <arg_list>”)
    notify_backup /path_to_script/script_backup.sh
        (or notify_backup “/path_to_script/script_backup.sh <arg_list>”)
    notify_fault /path_to_script/script_fault.sh
        (or notify_fault “ /path_to_script/script_fault.sh <arg_list>”)
}
vrrp_instance string {
    state MASTER|BACKUP
    interface string
    mcast_src_ip @IP
    lvs_sync_daemon_interface string
    virtual_router_id num
    priority num
    advert_int num
    smtp_alert
    authentication {
        auth_type PASS|AH
        auth_pass string
    }
    virtual_ipaddress { # Block limited to 20 IP addresses
        @IP
        @IP
        @IP
    }
    virtual_ipaddress_excluded { # Unlimited IP addresses
        @IP
        @IP
        @IP
    }
    notify_master /path_to_script/script_master.sh
        (or notify_master “ /path_to_script/script_master.sh <arg_list>”)
    notify_backup /path_to_script/script_backup.sh
        (or notify_backup “ /path_to_script/script_backup.sh <arg_list>”)
    notify_fault /path_to_script/script_fault.sh
        (or notify_fault “ /path_to_script/script_fault.sh <arg_list>”)
}
关键字 定义 类型
vrrp_instance 标识VRRP实例定义块 Block
state 在标准使用中指定实例状态  
interface 指定实例运行所要用到的网络接口 string
mcast_src_ip 指定VRRP通告的IP头的源地址  
lvs_sync_daemon_inteface 指定LVS sync_daemon运行所要用到的网络接口 string
virtual_router_id 指定实例所属的VRRP路由器ID numerical
priority 指定实例在VRRP路由器中的优先级 numerical
advert_int 以秒为单位指定通告的间隔时间(设置为1) numerical
smtp_alert 激活MASTER状态转换的SMTP通知  
authentication 标识VRRP认证定义块 Block
auth_type 指定要使用哪种身份认证(PASS|AH)  
auth_pass 指定要使用的密码字符串 string
virtual_ipaddress 标识VRRP VIP定义块 Block
virtual_ipaddress_excluded 标识VRRP VIP排除定义块 Block
notify_master 指定在切换到master时要执行的脚本 path
notify_backup 指定在切换到backup时要执行的脚本 path
notify_fault 指定在切换到故障状态时要执行的脚本 path
vrrp_sync_group 标识VRRP同步组定义块 Block

path类型:脚本的系统路径,例如:/usr/local/bin/transit.sh <arg_list>

Keepalived程序简介

Keepalived包附带2个程序。

keepalived守护进程

keepalived命令行参数如下:

-f, –use-file=FILE
使用指定的配置文件,默认配置文件是“/etc/keepalived/keepalived.conf”。
-P, –vrrp
只运行VRRP子系统。这对于不使用IPVS负载均衡的配置很有用。
-C, –check
只运行健康检查子系统。这对于将IPVS负载均衡与单个导向器一起使用而没有故障切 换的配置很有用。
-l, –log-console
将消息记录到本地控制台。默认行为是将消息记录到syslog。
-D, –log-detail
详细的日志信息。
-S, –log-facility=[0-7]
设置syslog设施为LOG_LOCAL [0-7]。默认的syslog设施是LOG_DAEMON。
-V, –dont-release-vrrp
在守护进程停止时不要删除VRRP VIP和VROUTE。默认行为是在keepalived退出时删除 所有VIP和VROUTE.
-I, –dont-release-ipvs
在守护进程停止时不要删除IPVS拓扑。默认行为是在keepalived退出时,它将从IPVS 虚拟服务器表中删除所有条目。
-R, –dont-respawn
不要重新派生子进程。默认行为是如果任一进程退出,就重新启动VRRP和checker子 进程。
-n, –dont-fork
不要派生守护进程。此选项将导致keepalived在前台运行。
-d, –dump-conf
转储配置数据。
-p, –pid=FILE
将指定的pidfile文件用于父级keepalived进程。Keepalived的默认pid文件是 “/var/run/keepalived.pid”。
-r, –vrrp_pid=FILE
将指定的pidfile文件用于VRRP子进程。VRRP子进程的默认pid文件是 “/var/run/keepalived_vrrp.pid”。
-c, –checkers_pid=FILE
将指定的pidfile文件用于checker子进程。checker子进程的默认pid文件是 “/var/run/keepalived_checkers.pid”。
-x, –snmp
启用SNMP子系统。
-v, –version
显示版本并退出。
-h, –help
显示此帮助信息并退出。

genhash实用程序

genhash二进制文件用于生成只要字符串。genhash的命令行参数如下:

–use-ssl, -S
使用SSL连接到服务器。
–server <host>, -s
指定要连接的IP地址。
–port <port>, -p
指定要连接的端口。
–url <url>, -u
指定要生成哈希值的文件路径。
–use-virtualhost <host>, -V
指定要与HTTP请求头(host字段)一起发送的虚拟主机
–hash <alg>, -H
指定哈希算法以生成目标页面的摘要。请参阅帮助信息,查看带有默认标记的可用列表。
–verbose, -v
输出详细信息。
–help, -h
显示此帮助信息并退出。
–release, -r
显示版本号并退出。

运行keepalived守护进程

要运行keepalived,只需键入:

[root@lvs tmp]# /etc/rc.d/init.d/keepalived.init start
Starting Keepalived for LVS:                            [ OK ]

所有的守护进程消息都通过Linux syslog 进行记录。如果使用“转储配置数据”选项启动keepalived,您应该在 /var/log/messages (在Debian上可能是 /var/log/daemon.log,具体取决于您的syslog配置)中看到如下信息:

Jun 7 18:17:03 lvs1 Keepalived: Starting Keepalived v0.6.1 (06/13, 2002)
Jun 7 18:17:03 lvs1 Keepalived: Configuration is using : 92013 Bytes
Jun 7 18:17:03 lvs1 Keepalived: ------< Global definitions >------
Jun 7 18:17:03 lvs1 Keepalived: LVS ID = LVS_PROD
Jun 7 18:17:03 lvs1 Keepalived: Smtp server = 192.168.200.1
Jun 7 18:17:03 lvs1 Keepalived: Smtp server connection timeout = 30
Jun 7 18:17:03 lvs1 Keepalived: Email notification from = keepalived@domain.com
Jun 7 18:17:03 lvs1 Keepalived: Email notification = alert@domain.com
Jun 7 18:17:03 lvs1 Keepalived: Email notification = 0633556699@domain.com
Jun 7 18:17:03 lvs1 Keepalived: ------< SSL definitions >------
Jun 7 18:17:03 lvs1 Keepalived: Using autogen SSL context
Jun 7 18:17:03 lvs1 Keepalived: ------< LVS Topology >------
Jun 7 18:17:03 lvs1 Keepalived: System is compiled with LVS v0.9.8
Jun 7 18:17:03 lvs1 Keepalived: VIP = 10.10.10.2, VPORT = 80
Jun 7 18:17:03 lvs1 Keepalived: VirtualHost = www.domain1.com
Jun 7 18:17:03 lvs1 Keepalived: delay_loop = 6, lb_algo = rr
Jun 7 18:17:03 lvs1 Keepalived: persistence timeout = 50
Jun 7 18:17:04 lvs1 Keepalived: persistence granularity = 255.255.240.0
Jun 7 18:17:04 lvs1 Keepalived: protocol = TCP
Jun 7 18:17:04 lvs1 Keepalived: lb_kind = NAT
Jun 7 18:17:04 lvs1 Keepalived: sorry server = 192.168.200.200:80
Jun 7 18:17:04 lvs1 Keepalived: RIP = 192.168.200.2, RPORT = 80, WEIGHT = 1
Jun 7 18:17:04 lvs1 Keepalived: RIP = 192.168.200.3, RPORT = 80, WEIGHT = 2
Jun 7 18:17:04 lvs1 Keepalived: VIP = 10.10.10.3, VPORT = 443
Jun 7 18:17:04 lvs1 Keepalived: VirtualHost = www.domain2.com
Jun 7 18:17:04 lvs1 Keepalived: delay_loop = 3, lb_algo = rr
Jun 7 18:17:04 lvs1 Keepalived: persistence timeout = 50
Jun 7 18:17:04 lvs1 Keepalived: protocol = TCP
Jun 7 18:17:04 lvs1 Keepalived: lb_kind = NAT
Jun 7 18:17:04 lvs1 Keepalived: RIP = 192.168.200.4, RPORT = 443, WEIGHT = 1
Jun 7 18:17:04 lvs1 Keepalived: RIP = 192.168.200.5, RPORT = 1358, WEIGHT = 1
Jun 7 18:17:05 lvs1 Keepalived: ------< Health checkers >------
Jun 7 18:17:05 lvs1 Keepalived: 192.168.200.2:80
Jun 7 18:17:05 lvs1 Keepalived: Keepalive method = HTTP_GET
Jun 7 18:17:05 lvs1 Keepalived: Connection timeout = 3
Jun 7 18:17:05 lvs1 Keepalived: Nb get retry = 3
Jun 7 18:17:05 lvs1 Keepalived: Delay before retry = 3
Jun 7 18:17:05 lvs1 Keepalived: Checked url = /testurl/test.jsp,
Jun 7 18:17:05 lvs1 Keepalived: digest = 640205b7b0fc66c1ea91c463fac6334d
Jun 7 18:17:05 lvs1 Keepalived: 192.168.200.3:80
Jun 7 18:17:05 lvs1 Keepalived: Keepalive method = HTTP_GET
Jun 7 18:17:05 lvs1 Keepalived: Connection timeout = 3
Jun 7 18:17:05 lvs1 Keepalived: Nb get retry = 3
Jun 7 18:17:05 lvs1 Keepalived: Delay before retry = 3
Jun 7 18:17:05 lvs1 Keepalived: Checked url = /testurl/test.jsp,
Jun 7 18:17:05 lvs1 Keepalived: digest = 640205b7b0fc66c1ea91c463fac6334c
Jun 7 18:17:05 lvs1 Keepalived: Checked url = /testurl2/test.jsp,
Jun 7 18:17:05 lvs1 Keepalived: digest = 640205b7b0fc66c1ea91c463fac6334c
Jun 7 18:17:06 lvs1 Keepalived: 192.168.200.4:443
Jun 7 18:17:06 lvs1 Keepalived: Keepalive method = SSL_GET
Jun 7 18:17:06 lvs1 Keepalived: Connection timeout = 3
Jun 7 18:17:06 lvs1 Keepalived: Nb get retry = 3
Jun 7 18:17:06 lvs1 Keepalived: Delay before retry = 3
Jun 7 18:17:06 lvs1 Keepalived: Checked url = /testurl/test.jsp,
Jun 7 18:17:05 lvs1 Keepalived: digest = 640205b7b0fc66c1ea91c463fac6334d
Jun 7 18:17:06 lvs1 Keepalived: Checked url = /testurl2/test.jsp,
Jun 7 18:17:05 lvs1 Keepalived: digest = 640205b7b0fc66c1ea91c463fac6334d
Jun 7 18:17:06 lvs1 Keepalived: 192.168.200.5:1358
Jun 7 18:17:06 lvs1 Keepalived: Keepalive method = TCP_CHECK
Jun 7 18:17:06 lvs1 Keepalived: Connection timeout = 3
Jun 7 18:17:06 lvs1 Keepalived: Registering Kernel netlink reflector

IPVS调度算法

IPVS内核代码支持以下调度算法(大量内容摘自LVS网站)。

轮转(Round Robin, rr)

轮转调度算法将每个传入请求发送到其列表中的下一个服务器。因此,在三服务器集群(服务器A,B和C)中,请求1将转到服务器A,请求2将转到服务器B,请求3将转到服务器C,请求4将转到服务器A,这样就完成了服务器的循环或“轮转”。它对所有真实服务器都一视同仁,而不管每个服务器所经历的传入连接数量或响应时间。与传统的轮转DNS相比,虚拟服务器具有一些优势。轮转DNS将单个域名解析为不同的IP地址,调度粒度是基于主机的,并且DNS查询的缓存阻碍了基本算法,这些因素导致真实服务器之间的动态负载严重失衡。

加权轮转(Weighted Round Robin, wrr)

加权轮转调度旨在更好地处理具有不同处理能力的服务器。可以为每个服务器分配一个权重,权重就是用来表示处理能力的整数值。具有较高权重的服务器优先获取新连接,并且会获得更多连接,相同权重的服务器获取的连接数相同。举个栗子,真实服务器A,B和C分别具有权重4,3,2,在调度周期(mod sum(Wi))中,良好的调度序列将是 AABABCABC。在加权轮转调度的实现中,在修改虚拟服务器的规则之后,将根据服务器权重生成调度序列。

当真实服务器的处理能力不同时,加权轮转调度优于轮转调度。但是,如果请求的负载变化很大,则可能导致真实服务器之间的动态负载严重失衡。简而言之,大多数需要大量响应的请求可能会被引导到同一个真实服务器。

实际上,轮转调度是加权轮转调度的一个特殊实例,其中所有服务器的权重都相等。

最少连接(Least Connection, lc)

最少连接调度算法将网络连接定向到具有最少数量的已建立连接的服务器。这是动态调度算法之一,因为它需要动态计算每个服务器的实时连接。对于管理具有相似性能的服务器集群的虚拟服务器,且请求的负载变化很大时,最少连接调度可以进行平滑分发。虚拟服务器会将请求定向到具有最少活跃连接的真实服务器。

乍一看,即使存在各种计算能力的服务器,最少连接调度也可能表现良好,因为更快的服务器将获得更多的网络连接。事实上,由于TCP的 TIME_WAIT 状态,它无法很好地执行。TCP的TIME_WAIT通常是2分钟,在这2分钟,一个繁忙的网站经常收到数千个连接,例如,服务器A的计算能力是服务器B的2倍,服务器A处理数千个请求并使它们进入TCP的TIME_WAIT状态,但服务器B正在爬行以完成其数千个连接。因此,最少连接调度不能在具有各种处理能力的服务器之间很好地平衡负载。

加权最少连接(Weighted Least Connection, wlc)

加权最少连接调度是最少连接调度的超集,您可以在其中为每个真实服务器分配性能权重。具有较高权重值的服务器在任何时候都将获得更大比例的实时连接。虚拟服务器管理员可以为每个真实服务器分配权重,并且网络连接将被安排到每个服务器,其中每个服务器的当前活动连接数与其权重成正比。默认权重为1。

加权最少连接调度的工作原理如下:

假设有n个真实服务器,每个服务器i具有权重Wi(i=1,2,…,n),和活动连接数Ci(i=1,2,…,n),ALL_CONNECTIONS是Ci的总和(i=1,2,…,n),下一个网络连接将被定向到服务器j,其中

(Cj/ALL_CONNECTIONS)/Wj = min { (Ci/ALL_CONNECTIONS)/Wi } (i=1,..,n)

由于ALL_CONNECTIONS在此查找中是常量,因此不需要将Ci除以ALL_CONNECTIONS,它可以被优化为

Cj/Wj = min { Ci/Wi } (i=1,..,n)

加权最少连接调度算法相比最少连接调度算法需要额外的除法。为了在服务器具有相同的处理能力时最小化调度的开销,最少连接调度和加权最少连接调度算法都需要被实现。

基于局部性的最少连接(Locality-Based Least Connection, lblc)

基于局部性的最少连接调度算法用于目标IP负载均衡。它通常用于缓存集群。如果服务器处于活动状态且负载不足,那么此算法通常会将发往IP地址的数据包定向到其所在服务器。如果服务器过载(其活动连接数大于其权重)并且有其他服务器处于半负载状态,则将加权最少连接服务器分配给此IP地址。

带复制的基于局部性最少连接(Locality-Based Least Connection with Replication, lblcr)

带复制的基于局部性最少连接调度算法也用于目标IP负载均衡。它通常用于缓存集群。它与 LBLC 调度的区别在于:负载均衡器需要维护从一个目标IP地址到一组服务器的映射,而LBLC调度维护从一个目标IP地址到一台服务器的映射。对目标IP的请求将分配给对应的服务器组中的最少连接节点。如果服务器组中的所有节点都过载,那么从集群中挑选出最少连接节点,并将其添加到服务器组中。如果服务器组在指定时间内都未修改,则从服务器组中删除负载最高的节点,以避免高度复制。

目标地址哈希(Destination Hashing, dh)

目标地址哈希调度算法根据请求的目标IP地址查找静态分配的哈希表来为服务器分配网络连接。

源地址哈希(Source Hashing, sh)

源地址哈希调度算法根据请求的源IP地址查找静态分配的哈希表来为服务器分配网络连接。

最短预期延迟(Shortest Expected Delay, seq)

最短预期延迟调度算法以最短的预期延迟将网络连接分配给服务器。如果发送到第i个服务器,作业将经历的预期延迟为 (Ci + 1)/ Ui,其中Ci是第i个服务器上的连接数,Ui是第i个服务器的固定服务速率(权重)。

永不排队(Never Queue, nq)

永不排队调度算法采用双速模型。当有空闲服务器可用时,作业将被发送到空闲服务器,而不是等待快速服务器。当没有空闲服务器时,作业将被发送到最短预期延迟的服务器(最短预期延迟调度算法)。

溢出连接(Overflow-Connection, ovf)

溢出连接调度算法根据活动连接数实现“溢出”负载均衡,将所有连接发送到具有最高权重的节点,并且如果连接数超过节点的权重,就溢出到下一个节点。请注意,此调度算法可能不适用于UDP,因为它仅使用活动连接

IPVS协议支持

IPVS传输协议负载均衡支持

IPVS支持以下传输协议的负载均衡:

  • TCP
  • UDP
  • SCTP
  • ESP(Encapsulation Security Payload)
  • AH(Authentication Header)

IPVS应用助手

FTP协议助手

Netfilter连接追踪

SIP持久性引擎

取决于UDP和SIP netfilter连接追踪

待处理

提及Netfilter连接追踪

待处理

提及ipip内核模块

配置SNMP支持

Keepalived提供了一个 SNMP 子系统,可以收集有关 VRRP 堆栈和健康检查系统的各种指标。Keepalived MIB 位于项目的doc目录中。MIB的基本SNMP OID.1.3.6.1.4.1.9586.100.5,它由 IANA 分配的 Debian OID空间 托管。

先决条件

在系统上安装SNMP协议工具和库。这需要安装几个包:

yum install net-snmp net-snmp-utils net-snmp-libs

在您的系统上安装了SNMP后,请在配置keepalived时开启SNMP支持。编译keepalived时,添加–enable-snmp配置选项。例如:

./configure --enable-snmp

在编译过程的配置步骤中,您将在使用make构建之前获得配置摘要。例如,您可能会在Centos 6机器上看到类似的输出:

./configure --prefix=/usr/local/keepalived-1.2.15 --enable-snmp
Keepalived configuration
------------------------
Keepalived version       : 1.2.15
Compiler                 : gcc
Compiler flags           : -g -O2 -I/usr/include/libnl3
Extra Lib                : -Wl,-z,relro -Wl,-z,now -L/usr/lib64
-lnetsnmpagent -lnetsnmphelpers -lnetsnmpmibs -lnetsnmp -Wl,-E
-Wl,-rpath,/usr/lib64/perl5/CORE -lssl -lcrypto -lcrypt  -lnl-genl-3 -lnl-3
Use IPVS Framework       : Yes
IPVS sync daemon support : Yes
IPVS use libnl           : Yes
fwmark socket support    : Yes
Use VRRP Framework       : Yes
Use VRRP VMAC            : Yes
SNMP support             : Yes
SHA1 support             : No
Use Debug flags          : No

请注意配置摘要的 Extra Lib 部分。它列出了gcc将用于构建keepalived的各种库标志,其中一些与SNMP有关。

配置支持

通过在SNMP守护进程配置文件中包含以下行来启用 SNMP AgentX 支持,如果您在Centos 6机器上通过RPM进行安装,那么通常配置文件为 /etc/snmp/snmpd.conf:

master agentx

注解

请务必reload或重启SNMP服务,以确保配置更改生效。

添加MIB

您可以使用OID查询keepalived SNMP托管对象。例如:

snmpwalk -v2c -c public localhost .1.3.6.1.4.1.9586.100.5.1.1.0
SNMPv2-SMI::enterprises.9586.100.5.1.1.0 = STRING: "Keepalived v1.2.15 (01/10,2015)"

或者,使用keepalived MIB,您可以使用项目中提供的MIB进行查询。首先,将MIB复制到系统的全局MIB目录或用户的本地MIB目录:

cp /usr/local/src/keepalived-1.2.15/doc/KEEPALIVED-MIB /usr/share/snmp/mibs
或者
cp /usr/local/src/keepalived-1.2.15/doc/KEEPALIVED-MIB ~/.snmp/mibs

SNMP守护进程将检查两个目录中是否存在MIB。一旦MIB到位,SNMP查询可以如下所示:

snmpwalk -v2c -c public localhost KEEPALIVED-MIB::version
KEEPALIVED-MIB::version.0 = STRING: Keepalived v1.2.15 (01/10,2015)

MIB概述

Keepalived MIB有四个主要部分:

  • global
  • vrrp
  • check
  • conformance

Global

Global部分包含有关keepalived实例信息的对象,例如版本,路由器ID和管理电子邮箱。

VRRP

VRRP部分包含每个已配置的VRRP实例信息的对象。在每个实例中,都有包含实例名称,当前状态和虚拟IP地址的对象。

Check

Check部分包含有关每个已配置虚拟服务器信息的对象。它包括用于虚拟和真实服务器的服务器表,还包括配置的负载均衡算法,负载均衡方法,协议,状态,真实和虚拟服务器网络连接统计信息。

Comformance

待处理

完善comformance

注解

使用MIB浏览器(如mbrowse)查看可用于查询的托管对象,以监控LVS服务器的运行状况。

案例研究:健康检查

作为示例,我们可以引入如下LVS拓扑:

首先,您需要一个配置良好的LVS拓扑。在本文档的其余部分,我们假设已完成所有系统配置。这种拓扑通常在DMZ架构中实现。有关LVS NAT拓扑和系统配置的更多信息,请阅读非常详细的Joseph Mack的 LVS HOWTO

主要架构组件

  • LVS路由器:拥有负载均衡的IP类路由(192.168.100.0/24)
  • 网络路由器:整个内部网络的默认路由器。所有LAN工作站都通过此IP地址处理。
  • 网络DNS服务器:引用内部网络IP拓扑。
  • SMTP服务器:接收邮件报警的SMTP服务器。
  • 服务器池:一组承载负载均衡服务的服务器。

服务器池规格

在此示例配置中,我们有2个服务器池:

  • 服务器池1:托管HTTP和SSL服务。每个服务器拥有两个应用服务(IBM WEBSPHEREBEA WEBLOGIC
  • 服务器池2:托管SMTP服务。

Keepalived配置

您现在可以根据LVS拓扑来配置Keepalived守护进程了。整个配置在 /etc/keepalived/keepalived.conf 文件中完成。在我们的案例研究中,此文件如下所示:

# Configuration File for keepalived
global_defs {
    notification_email {
        admin@domain.com
        0633225522@domain.com
    }
    notification_email_from keepalived@domain.com
    smtp_server 192.168.200.20
    smtp_connect_timeout 30
    lvs_id LVS_MAIN
}
virtual_server 192.168.200.15 80 {
    delay_loop 30
    lb_algo wrr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    sorry_server 192.168.100.100 80

    real_server 192.168.100.2 80 {
        weight 2
        HTTP_GET {
            url {
                path /testurl/test.jsp
                digest ec90a42b99ea9a2f5ecbe213ac9eba03
            }
            url {
                path /testurl2/test.jsp
                digest 640205b7b0fc66c1ea91c463fac6334c
            }
            connect_timeout 3
            retry 3
            delay_before_retry 2
        }
    }
    real_server 192.168.100.3 80 {
        weight 1
        HTTP_GET {
            url {
                path /testurl/test.jsp
                digest 640205b7b0fc66c1ea91c463fac6334c
            }
            connect_timeout 3
            retry 3
            delay_before_retry 2
        }
    }
}
virtual_server 192.168.200.15 443 {
    delay_loop 20
    lb_algo rr
    lb_kind NAT
    persistence_timeout 360
    protocol TCP
    real_server 192.168.100.2 443 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
        }
    }
    real_server 192.168.100.3 443 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
        }
    }
}
virtual_server 192.168.200.15 25 {
    delay_loop 15
    lb_algo wlc
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    real_server 192.168.100.4 25 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
        }
    }
    real_server 192.168.100.5 25 {
        weight 2
        TCP_CHECK {
            connect_timeout 3
        }
    }
}

根据此配置示例,Keepalived守护进程将使用以下信息驱动内核:

  • LVS服务器将拥有名称:LVS_MAIN

  • 通知:

    • SMTP服务器将是:192.168.200.20
    • SMTP连接超时设置为:30秒
    • 通知电子邮箱将是:admin@domain.com和0633225522@domain.com
  • 负载均衡服务:

    • HTTP:VIP 192.168.200.15 端口 80

      • 负载均衡:使用NAT转发和加权轮转调度。每个TCP服务上的连接持久性设置为50秒。如果您使用的是Linux内核2.2,则需要指定NAT网络掩码来定义IPFW伪装的粒度(net_mask关键字)。延迟循环设置为30秒。
      • sorry服务器:如果所有的真实服务器都被从VS服务器池中移除了,我们添加sorry_server 192.168.100.100端口80来为客户端提供服务。
      • 真实服务器192.168.100.2端口80将加权为2。故障检测将基于2个URL上的HTTP_GET方法。服务的连接超时时间将被设置为3秒。重试3次后,真实服务器将被视为宕机。守护进程将等待2秒后再重试。
      • 真实服务器192.168.100.3端口80将加权为1。故障检测将基于1个URL上的HTTP_GET方法。服务的连接超时时间将被设置为3秒。重试3次后,真实服务器将被视为宕机。守护进程将等待2秒后再重试。
    • SSL:VIP 192.168.200.15 端口 443

      • 负载均衡:使用NAT转发和轮转调度。每个TCP服务上的连接持久性设置为360秒。延迟循环设置为20秒。
      • 真实服务器192.168.100.2端口443将加权为2。故障检测将基于TCP_CHECK方法。在3秒的连接超时时间后,真实服务器将被视为宕机。
      • 真实服务器192.168.100.3端口443将加权为2。故障检测将基于TCP_CHECK方法。在3秒的连接超时时间后,真实服务器将被视为宕机。
    • SMTP:VIP 192.168.200.15 端口 25

      • 负载均衡:在NAT拓扑中使用加权最少连接调度算法,连接持久性设置为50秒。延迟循环设置为15秒。
      • 真实服务器192.168.100.4端口25将加权为1。故障检测将基于TCP_CHECK方法。在3秒的连接超时时间后,真实服务器将被视为宕机。
      • 真实服务器192.168.100.5端口25将加权为2。故障检测将基于TCP_CHECK方法。在3秒的连接超时时间后,真实服务器将被视为宕机。

对于SSL服务器运行状况检测,我们可以使用SSL_GET方法。相应真实服务器的配置块如下所示:

virtual_server 192.168.200.15 443 {
    delay_loop 20
    lb_algo rr
    lb_kind NAT
    persistence_timeout 360
    protocol TCP
    real_server 192.168.100.2 443 {
        weight 1
        SSL_GET
        {
            url {
                path /testurl/test.jsp
                digest ec90a42b99ea9a2f5ecbe213ac9eba03
            }
            url {
                path /testurl2/test.jsp
                digest 640205b7b0fc66c1ea91c463fac6334c
            }
            connect_timeout 3
            retry 3
            delay_before_retry 2
        }
    }
    real_server 192.168.100.3 443 {
        weight 1
        SSL_GET
        {
            url {
                path /testurl/test.jsp
                digest 640205b7b0fc66c1ea91c463fac6334c
            }
            connect_timeout 3
            retry 3
            delay_before_retry 2
        }
    }
}

要生成一个URL的摘要和,只需执行以下操作:

[root@lvs /root]# genhash –s 192.168.100.2 –p 80 –u /testurl/test.jsp
--------------------------[ HTTP Header Buffer ]--------------------------
0000 48 54 54 50 2f 31 2e 31 - 20 34 30 31 20 55 6e 61 HTTP/1.1 401 Una
0010 75 74 68 6f 72 69 7a 65 - 64 0d 0a 44 61 74 65 3a uthorized..Date:
0020 20 4d 6f 6e 2c 20 32 33 - 20 41 70 72 20 32 30 30 Mon, 23 Apr 200
0030 31 20 31 35 3a 34 31 3a - 35 34 20 47 4d 54 0d 0a 1 15:41:54 GMT..
0040 41 6c 6c 6f 77 3a 20 47 - 45 54 2c 20 48 45 41 44 Allow: GET, HEAD
0050 0d 0a 53 65 72 76 65 72 - 3a 20 4f 72 61 63 6c 65 ..Server: Oracle
0060 5f 57 65 62 5f 4c 69 73 - 74 65 6e 65 72 2f 34 2e _Web_Listener/4.
0070 30 2e 38 2e 31 2e 30 45 - 6e 74 65 72 70 72 69 73 0.8.1.0Enterpris
0080 65 45 64 69 74 69 6f 6e - 0d 0a 43 6f 6e 74 65 6e eEdition..Conten
0090 74 2d 54 79 70 65 3a 20 - 74 65 78 74 2f 68 74 6d t-Type: text/htm
00a0 6c 0d 0a 43 6f 6e 74 65 - 6e 74 2d 4c 65 6e 67 74 l..Content-Lengt
00b0 68 3a 20 31 36 34 0d 0a - 57 57 57 2d 41 75 74 68 h: 164..WWW-Auth
00c0 65 6e 74 69 63 61 74 65 - 3a 20 42 61 73 69 63 20 enticate: Basic
00d0 72 65 61 6c 6d 3d 22 41 - 43 43 45 53 20 20 20 20 realm="ACCES
00e0 22 0d 0a 43 61 63 68 65 - 2d 43 6f 6e 74 72 6f 6c "..Cache-Control
00f0 3a 20 70 75 62 6c 69 63 - 0d 0a 0d 0a : public....
------------------------------[ HTML Buffer ]-----------------------------
0000 3c 48 54 4d 4c 3e 3c 48 - 45 41 44 3e 3c 54 49 54 <HTML><HEAD><TIT
0010 4c 45 3e 55 6e 61 75 74 - 68 6f 72 69 7a 65 64 3c LE>Unauthorized<
0020 2f 54 49 54 4c 45 3e 3c - 2f 48 45 41 44 3e 0d 0a /TITLE></HEAD>..
0030 3c 42 4f 44 59 3e 54 68 - 69 73 20 64 6f 63 75 6d <BODY>This docum
0040 65 6e 74 20 69 73 20 70 - 72 6f 74 65 63 74 65 64 ent is protected
0050 2e 20 20 59 6f 75 20 6d - 75 73 74 20 73 65 6e 64 . You must send
0060 0d 0a 74 68 65 20 70 72 - 6f 70 65 72 20 61 75 74 ..the proper aut
0070 68 6f 72 69 7a 61 74 69 - 6f 6e 20 69 6e 66 6f 72 horization infor
0080 6d 61 74 69 6f 6e 20 74 - 6f 20 61 63 63 65 73 73 mation to access
0090 20 69 74 2e 3c 2f 42 4f - 44 59 3e 3c 2f 48 54 4d it.</BODY></HTM
00a0 4c 3e 0d 0a - L>..
-----------------------[ HTML MD5 final resulting ]-----------------------
MD5 Digest : ec90a42b99ea9a2f5ecbe213ac9eba03

唯一要做的就是复制生成的MD5摘要值,并将其作为摘要值关键字粘贴到Keepalived的配置文件中。

案例研究:使用VRRP进行失败切换

作为示例,我们可以引入如下LVS拓扑:

架构描述

要使用VRRPv2协议创建虚拟LVS转发器,我们定义如下架构:

  • 2个处于主动-主动配置的LVS转发器。
  • 每个LVS转发器4个VRRP实例:2个处于MASTER状态的VRRP实例和2个处于BACKUP状态的VRRP实例。我们在每个LVS转发器上使用对称状态。
  • 2个处于相同状态的VRRP实例将进行同步,以定义持久化虚拟路由路径。
  • 强认证:IPSEC-AH用于保护我们的VRRP通告免受欺骗和回复攻击。

VRRP实例与以下IP地址混合:

  • VRRP实例VI_1:拥有VRRP VIPs VIP1和VIP2。此实例在LVS转发器1上默认为MASTER状态。它与VI_2保持同步。
  • VRRP实例VI_2:拥有DIP1。此实例在LVS转发器1上默认为MASTER状态。它与VI_1保持同步。
  • VRRP实例VI_3:拥有VRRP VIPs VIP3和VIP4。此实例在LVS转发器2上默认为MASTER状态。它与VI_4保持同步。
  • VRRP实例VI_4:拥有DIP2。此实例在LVS转发器2上默认为MASTER状态。它与VI_3保持同步。

Keepalived配置

整个配置在 /etc/keepalived/keepalived.conf 文件中完成。在我们的案例研究中,LVS转发器1上的该文件如下所示:

vrrp_sync_group VG1 {
    group {
        VI_1
        VI_2
    }
}
vrrp_sync_group VG2 {
    group {
        VI_3
        VI_4
    }
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type AH
        auth_pass k@l!ve1
    }
    virtual_ipaddress {
        192.168.200.10
        192.168.200.11
    }
}
vrrp_instance VI_2 {
    state MASTER
    interface eth1
    virtual_router_id 52
    priority 150
    advert_int 1
    authentication {
        auth_type AH
        auth_pass k@l!ve2
    }
    virtual_ipaddress {
        192.168.100.10
    }
}
vrrp_instance VI_3 {
    state BACKUP
    interface eth0
    virtual_router_id 53
    priority 100
    advert_int 1
    authentication {
        auth_type AH
        auth_pass k@l!ve3
    }
    virtual_ipaddress {
        192.168.200.12
        192.168.200.13
    }
}
vrrp_instance VI_4 {
    state BACKUP
    interface eth1
    virtual_router_id 54
    priority 100
    advert_int 1
    authentication {
        auth_type AH
        auth_pass k@l!ve4
    }
    virtual_ipaddress {
        192.168.100.11
    }
}

然后我们在LVS转发器2上定义对称配置文件。这意味着LVS转发器2上的VI_3和VI_4处于MASTER状态,具有更高的优先级150且从稳定状态开始。LVS转发器2上的VI_1和VI_2处于默认的BACKUP状态,优先级较低为100。此配置文件为每个物理网卡指定2个VRRP实例。当您在LVS转发器1上运行Keepalived而不在LVS转发器2上运行它时,LVS转发器1将拥有所有VRRP VIP。因此,如果您使用ip使用程序(在Debian上,ip实用程序是iprouter的一部分),您可能会看到类似的东西:

[root@lvs1 tmp]# ip address list
1: lo: <LOOPBACK,UP> mtu 3924 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:00:5e:00:01:10 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.5/24 brd 192.168.200.255 scope global eth0
    inet 192.168.200.10/32 scope global eth0
    inet 192.168.200.11/32 scope global eth0
    inet 192.168.200.12/32 scope global eth0
    inet 192.168.200.13/32 scope global eth0
3: eth1: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:00:5e:00:01:32 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.5/24 brd 192.168.201.255 scope global eth1
    inet 192.168.100.10/32 scope global eth1
    inet 192.168.100.11/32 scope global eth1

然后只需在LVS转发器2上启动Keepalived,您将看到:

[root@lvs1 tmp]# ip address list
1: lo: <LOOPBACK,UP> mtu 3924 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:00:5e:00:01:10 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.5/24 brd 192.168.200.255 scope global eth0
    inet 192.168.200.10/32 scope global eth0
    inet 192.168.200.11/32 scope global eth0
3: eth1: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:00:5e:00:01:32 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.5/24 brd 192.168.201.255 scope global eth1
    inet 192.168.100.10/32 scope global eth1

在LVS转发器2中你会看到对称的:

[root@lvs2 tmp]# ip address list
1: lo: <LOOPBACK,UP> mtu 3924 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:00:5e:00:01:10 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.5/24 brd 192.168.200.255 scope global eth0
    inet 192.168.200.12/32 scope global eth0
    inet 192.168.200.13/32 scope global eth0
3: eth1: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:00:5e:00:01:32 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.5/24 brd 192.168.201.255 scope global eth1
    inet 192.168.100.11/32 scope global eth1

所用到的VRRP VIP如下:

  • VIP1 = 192.168.200.10
  • VIP2 = 192.168.200.11
  • VIP3 = 192.168.200.12
  • VIP4 = 192.168.200.13
  • DIP1 = 192.168.100.10
  • DIP2 = 192.168.100.11

使用VRRP关键字 sync_instance 意味着我们已经为每个LVS转发器(VI_1,VI_2)和(VI_3,VI_4)定义了一对MASTER VRRP实例。这意味着如果LVS转发器1上的eth0失败,那么LVS转发器2上的VI_1进入MASTER状态,因此两个转发器上的MASTER实例分布将是:转发器1的(VI_2)和转发器2上的(VI_1,VI_3和VI_4)。使用 sync_instance,因此LVS转发器1上的VI_2将被强制进入BACKUP状态。最终的VRRP MASTER实例分布将是:LVS转发器1的(无)和LVS转发器2的(VI_1,VI_2,,VI_3和VI_4)。如果LVS转发器1上的eth0成为可用时,分布将转换回初始状态。

有关此状态转换的更多信息,请参阅 使用VRRPv2的Linux虚拟服务器的高可用性 (可从http://www.linux-vs.org/~acassen/获得)一文,该文章解释了此功能的实现。

使用此配置,两个LVS转发器都处于主动状态,因此为全局转发器共享LVS转发器。这样我们就引入了虚拟LVS转发器。

注解

此VRRP配置示例演示了高可用性路由器(不是特定于LVS的路由器)。它可以用于许多更常见/简单的需求。

案例研究:混合健康检查和失败切换

对于此示例,我们使用与失败切换部分中相同的拓扑。这里的想法是使用VRRP VIP作为LVS的VIP。这样我们将引入一个高可用性LVS转发器来执行LVS真实服务器池监控。

Keepalived配置

整个配置在 /etc/keepalived/keepalived.conf 文件中完成。在我们的案例研究中,LVS转发器1上的该文件如下所示:

# Configuration File for keepalived
global_defs {
    notification_email {
        admin@domain.com
        0633225522@domain.com
    }
    notification_email_from keepalived@domain.com
    smtp_server 192.168.200.20
    smtp_connect_timeout 30
    lvs_id LVS_MAIN
}
# VRRP Instances definitions
vrrp_sync_group VG1 {
    group {
        VI_1
        VI_2
    }
}
vrrp_sync_group VG2 {
    group {
        VI_3
        VI_4
    }
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass k@l!ve1
    }
    virtual_ipaddress {
        192.168.200.10
        192.168.200.11
    }
}
vrrp_instance VI_2 {
    state MASTER
    interface eth1
    virtual_router_id 52
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass k@l!ve2
    }
    virtual_ipaddress {
        192.168.100.10
    }
}
vrrp_instance VI_3 {
    state BACKUP
    interface eth0
    virtual_router_id 53
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass k@l!ve3
    }
    virtual_ipaddress {
        192.168.200.12
        192.168.200.13
    }
}
vrrp_instance VI_4 {
    state BACKUP
    interface eth1
    virtual_router_id 54
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass k@l!ve4
    }
    virtual_ipaddress {
        192.168.100.11
    }
}
# Virtual Servers definitions
virtual_server 192.168.200.10 80 {
    delay_loop 30
    lb_algo wrr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    sorry_server 192.168.100.100 80
    real_server 192.168.100.2 80 {
        weight 2
        HTTP_GET {
            url {
                path /testurl/test.jsp
                digest ec90a42b99ea9a2f5ecbe213ac9eba03
            }
            url {
                path /testurl2/test.jsp
                digest 640205b7b0fc66c1ea91c463fac6334c
            }
            connect_timeout 3
            retry 3
            delay_before_retry 2
        }
    }
    real_server 192.168.100.3 80 {
        weight 1
        HTTP_GET {
            url {
                path /testurl/test.jsp
                digest 640205b7b0fc66c1ea91c463fac6334c
            }
            connect_timeout 3
            retry 3
            delay_before_retry 2
        }
    }
}
virtual_server 192.168.200.12 443 {
    delay_loop 20
    lb_algo rr
    lb_kind NAT
    persistence_timeout 360
    protocol TCP
    real_server 192.168.100.2 443 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
        }
    }
    real_server 192.168.100.3 443 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
        }
    }
}

我们在LVS转发器2上定义对称的VRRP配置文件。这样两个转发器都处于活动状态,转发器1处理HTTP流,转发器2处理SSL流。

术语

待处理

把架构图放在这里

LVS代表“Linux Virtual Server”。LVS是一个打了补丁的Linux内核,它添加了负载均衡功能。有关LVS的更多信息,请参考项目主页:http://www.linux-vs.org。LVS充当网桥(使用NAT)来对TCP/UDP流进行负载均衡。LVS路由器组件是:

  • WAN接口:所有客户端都可以访问的以太网网络接口控制器。
  • LAN接口:以太网网络接口控制器,用于管理所有负载均衡的服务器。
  • Linux内核:内核使用最新的LVS进行修补,并用作路由器操作系统。

在本文档中,我们将使用以下关键字:

LVS组件

VIP
虚拟IP是所有客户端都将访问的IP地址,客户端仅访问此IP地址。
真实服务器
真实服务器托管客户端请求访问的应用程序,我们概要中的WEB SERVER 1和WEB SERVER 2。
服务器池
一组真实服务器。
虚拟服务器
服务器池的访问点。
虚拟服务
与VIP关联的TCP/UDP服务。

VRRP组件

VRRP
为转发器的失败切换/虚拟化实现的协议。
IP地址拥有者
使用IP地址作为实际接口地址的VRRP实例。当启动时,它将响应发往这些IP地址之一的ICMP,TCP连接的数据包。
MASTER状态
VRRP实例状态,负责转发发送到与VRRP实例关联的IP地址的报文。
BACKUP状态
VRRP实例状态,负责在当前处于MASTER状态的VRRP实例失败时转发数据包。
真实负载均衡器
运行一个或多个VRRP实例的LVS转发器。
虚拟负载均衡器
一组实际负载均衡器。
同步实例
我们想要进行同步的VRRP实例。这提供了VRRP实例监控。
通告
在MASTER状态下发送到一组VRRP实例的简单VRRPv2数据包的名称。

待处理

定义RIP,DIP,转向器,IPVS

许可证

Copyright (c) 2001-2015 Alexandre Cassen.

This document is released under the terms of the GNU General Public Licence. You can redistribute it and/or modify it under the terms of the GNU General Public Licence as published by the Free Software Foundation; either version 2 of the Licence, or (at your option) any later version.

关于这些文档

这些文档是由 SphinxreStructuredText 源生成的,Sphinx是专门为Python文档编写的文档处理器。

构建文档

要构建Keepalived文档,您需要在系统上安装最新版本的Sphinx。或者,您可以使用Python virtualenv。

从克隆的存储库的根目录运行以下命令以HTML格式构建文档:

cd keepalived-docs
make html

对于PDF,您还需要 docutils 和各种 texlive-* 包,用于将reStructuredText转换为LaTex,最后转换为PDF:

pip install docutils
cd keepalived-docs
make latexpdf

或者,您可以使用Sphinx包附带的 sphinx-build 命令:

cd keepalived-docs
sphinx-build -b html . build/html

待处理

编译latexpdf需要由RHEL6上的texlive-latex和Fedora21上的texlive-latex-bin-bin提供的pdflatex

待处理

编译linkcheck来检查链接是否损坏

TODO 清单

待处理

提及Netfilter连接追踪

(原始记录 见 /home/docs/checkouts/readthedocs.org/user_builds/keepalived-doc/checkouts/latest/IPVS协议支持.rst,第 33 行。)

待处理

提及ipip内核模块

(原始记录 见 /home/docs/checkouts/readthedocs.org/user_builds/keepalived-doc/checkouts/latest/IPVS协议支持.rst,第 35 行。)

待处理

编译latexpdf需要由RHEL6上的texlive-latex和Fedora21上的texlive-latex-bin-bin提供的pdflatex

(原始记录 见 /home/docs/checkouts/readthedocs.org/user_builds/keepalived-doc/checkouts/latest/关于这些文档.rst,第 31 行。)

待处理

编译linkcheck来检查链接是否损坏

(原始记录 见 /home/docs/checkouts/readthedocs.org/user_builds/keepalived-doc/checkouts/latest/关于这些文档.rst,第 33 行。)

待处理

把架构图放在这里

(原始记录 见 /home/docs/checkouts/readthedocs.org/user_builds/keepalived-doc/checkouts/latest/术语.rst,第 4 行。)

待处理

定义RIP,DIP,转向器,IPVS

(原始记录 见 /home/docs/checkouts/readthedocs.org/user_builds/keepalived-doc/checkouts/latest/术语.rst,第 66 行。)

待处理

完善comformance

(原始记录 见 /home/docs/checkouts/readthedocs.org/user_builds/keepalived-doc/checkouts/latest/配置SNMP支持.rst,第 106 行。)