• lvs和keepalived搭建高可用性系统


    高可用性系统包含两个最基本条件

    1. 负载均衡,使请求能够快速处理响应

    2. 容灾,当集群中某个节点发生故障的时候,业务能够自动剔除故障机。当故障修复之后,能自动添加到集群中。

     

    本文将使用lvs + keepalived来搭建高可用性系统,会以web服务为例,给出详细的解决方案。

     

    系统要求

    1. linux内核2.6及以上

    2. 四台linux服务器,要求至少两台在同一子网中,用于部署keepalived服务

    3. 要求该子网有空闲的IP地址

     

    keepalived介绍

    keepalived用于解决容灾需求。一个keepalived集群中,会有一台MASTER主机,其他的都是BACKUP机器。当MASTER主机发生故障的时候,其他的BACKUP机器没有收到MASTER的广告报文,此时会重新根据优先级协商出新的MASTER主机,然后新的MASTER会重新发送广告报文,通告主机的状态。keepalived实现了VRRP(虚拟路由器冗余协议),并且通信的报文也是加密的。

     

    lvs介绍

    lvs是Linux Virtual Server的缩写,lvs主要用于负载均衡,根据具体的调度策略,当请求过来的时候,分配到相应的真实负载服务器上面,进行处理。lvs机器对外暴露的是一个虚拟的IP地址,该地址绑定在负载分配机器(LD)上,lvs有三种方式把用户的报文转发到真实的负载服务器(RealServer)上。

    第一种是NAT(网络地址转换)方式,LD收到真实用户请求的时候,LD会根据当前配置的调度策略,选取一台RealServer,修改请求报文目的IP地址,将数据包路由到Real Server上处理,此种方式RealServer不需要进行特殊配置。当RealServer回包的时候,LD会将数据包的源IP修改为虚拟的那个IP地址。由于收包和回包都需要LD参与,当整个系统的负载很大的时候,单点的LD显然会成为系统的瓶颈。

    第二种是DR(直接路由)方式,当LD和RealServer处于同一子网中的,可以以直接路由的方式把数据包传送到目的主机。直接路由其实就是将原始数据包添加上目的主机的MAC地址,然后将数据转发到RealServer上。直接路由的方式数据包不能跨路由,跨路由后会拆包重新填写目标MAC地址。lvs的LD上绑定了虚拟IP,同时要求RealServer在回环设备上绑定虚拟IP。当RealServer收到数据包之后,由于目的IP地址是虚拟IP的地址,并且自身也将这个IP绑定到了回环设备上,因此就可以处理该数据包。回包的时候,直接返回给用户,不需要经过LD。

    第三中方式IP tunnling(IP隧道)方式,当LD和RealServer不在同一子网中的时候,请求到达LD的时候,LD挑选一个RealServer,将请求的数据包重新封装成一个IP数据包,路由到目的主机上。IP隧道就是在两台特定的主机之间建立一个连接,把一端收到的数据包直接传递到另一端,然后拆包获取原始的请求数据包,进行后续的处理。此种方式需要在LD和RealServer上配置上隧道VIP,同时需要禁用RealServer上ARP响应,因为LD和RealServer绑定了同样的IP,而数据包只能到LD上,也就是只有LD能响应ARP查询。

     

    第二种和第三种转发方式,lvs的效率基本上能达到系统硬件性能。

    lvs的调度算法有八种,后续再讲解。

     

    lvs和keepalived的关系

    1. lvs可以处理负载均衡,但当其中一台RealServer发生故障的时候,并不能实时检测并剔除掉发生故障的RealServer,也不能当RealServer恢复正常后自动添加到lvs集群中。

    2. keepalived用于容灾,当集群中的节点发生故障的时候,会自动转移业务到可用的节点,但并不能将请求平均分配到集群中空闲的节点。

    3. lvs可以和有容灾功能的模块结合,组成高可用系统。例如lvs + heartbeat, lvs + keepalived等。keepalived可以和有负载均衡功能的模块结合,组成高可用系统。例如keepalived + lvs, keepalived + haproxy等。

    4. lvs单独运行,有负载均衡的作用。keepalived单独运行,有容灾的作用。这两个模块,都可以单独运行或者同其他模块结合,组成高可用系统。

    5. keepalived可以运行在lvs之上,由于liunx2.6之后的内核中已经包含了lvs模块,keepalived编译的时候,可以将lvs的管理接口编译到keepalived中。在keepalived的配置文件中,如果配置lvs模块的功能,就会启用lvs。如果不配置lvs的模块,那就不会启用lvs。lvs的管理接口也可以单独安装ipvsadm软件,来完成和lvs模块的交互。

     

    keepalived的源码安装及启动步骤

     

    如果keepalived已经安装成功,可以跳过安装,直接查看配置。

     

    Step 1. 内核源码准备

    keepalived安装的时候,我们需要使用系统的lvs功能,因此需要将lvs管理接口编译进来。lvs管理接口需要linux内核的头文件,最好有内核的源码文件。

    内核的源码可以直接从linux社区下载对应版本的linux内核源码

    假设内核源码的位置在/home/sliverdang/linux-2.6/目录下,编译keepalived的时候,可以做一个软链接,将/home/sliverdang/linux-2.6/ 软链接到/usr/src/linux目录。

    ln -s /home/sliverdang/linux-2.6/ /usr/src/linux

     

    Step 2. 下载keepalived源码

    linux64位的可以安装keepalived-1.2.9

    linux32位的可以安装keepalived-1.1.20

    查看linux位数命令: getconf LONG_BIT

     

    Step3. Openssl安装

    keepalived依赖openssl库,可以到openssl官网上下载openssl-1.0.1g.tar.gz版本的openssl,然后安装。

    tar zxvf openssl-1.0.1g.tar.gz 

    cd openssl-1.0.1g

    ./config shared --prefix=/usr/local/openssl

    make && make install

     

    Step4. keepalived安装

    之前已经将linux的源码软连接到/usr/src/linux目录下,同时也安装了keepalived依赖的openssl库。自己安装过程中,keepalived只依赖了这个库,如果还有其他依赖,可以上网上查一下,安装方法大同小异。

    keepalived的配置文件没有选项去指定openssl的路径,因此我们只能通过编译选项去指定openssl的头文件和库文件的位置。

    export CFLAGS="-I/usr/local/openssl/include/"

    export LDFLAGS="-L/usr/local/openssl/lib/" 

    然后进行configure,生成makefile文件

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

    configure的结果如下图:

    其中Use IPVS Framework和Use VRRP Framework这两个选项要为Yes,说明使用了lvs和VRRP特性。

    然后make && make install

    本人编译过程中也没有出现错误,如果编译不过去,可以根据报错去查找相应的解决方案。

     

    Step 5. 拷贝配置文件

    首先创建/etc/keepalived/目录

    将/usr/local/keepalived/etc/keepalived/keepalived.conf拷贝到/etc/keepalived/目录下,keepalived启动的时候,会默认读取此路径下的配置。以后改配置的话,都是指改此目录下的配置文件。

    本文讲解的例子中,不需要keepalived开机启动,不会将相应的启动脚本拷贝到启动运行的目录下,也不会添加到启动运行检查命令中。如果需要keepalived开机启动,自行查找拷贝的脚本及路径。

    将/usr/local/keepalived/sbin/keepalived文件拷贝到/usr/sbin/目录下,方便直接运行该命令。

    Step 6. 配置keepalived的启动配置

    本文中用到了4台服务器

    静态IP分别是:

    10.12.196.196(Load Balancer  Director Server,简称LD)

    10.12.196.198(LD)

    10.12.100.224(RealServer,简称RS)

    10.12.100.225(RS)

    10.12.196.5(虚拟的IP,简称VIP)

    首先看LD的配置,LD中又分为主LD和备LD。主LD和备LD的配置几乎相同,除了优先级和是否抢占这两个选项不一样。

    备LD的配置如下

     

    keepalived的配置都是一对花括号括起来的,一块一块组合起来。

    global_defs定义了路由节点的名称,默认配置即可,删除该节点下的email配置,本例中用不到。

    vvrp_instance是VRRP协议实现的一个实例,需要配置关键的信息。

      state 取值有BACKUP和MASTER,主备配置都配置为BACKUP,让他们根据优先级自己决定出主机。

      interface 虚拟IP绑定的网卡,可以为eth0或eth1

      virtual_router_id 虚拟路由节点,要求主备配置相同

      priority 优先级,要求主备之间至少相差50

      advert_int 发送广告报文的间隔

      nopreemet 是否抢占,当主机发生故障,修复后变成备机后,是否重新抢占主机。可以在优先级较高的LD上配置该选项,优先级低的不需要配置。主要是为了防止来回切换主机,影响服务的连续性和稳定性。

      authentication 验证的方式,当keepalived收到广告包的时候,会检查是否匹配合法,密码长度最长为8,密码不一致时keepalived会在日志中记录。修改密码的话,修改auth_pass的值即可。

      virtual_ipaddress 虚拟IP的地址,可以配置一组虚拟IP,最多20个虚拟IP组,配置多个虚拟IP的时候,请求这些虚拟IP的数据包,都会到主LD上。

    virtual_server节点是lvs的配置,如果不配置该节点,那么请求就直接被主LD处理,不会再进行转发。如果配置了该节点,那么就是用lvs特性,将数据包进行负载均衡,路由到真实的服务器上。

         delay_loop RealServer健康检查的时间间隔

         lb_algo 负载均衡调度的算法,负载均衡分为动态调度和静态调度。

           静态调度算法

          1. Round-Robin : 轮询,简称RR。每次请求依次分配到RS上,无状态

           2. Weighted Round-Robin : 加权轮询,简称WRR。加权轮询表示根据服务器的权重来分配处理次数。例如RS1服务器的处理性能是RS2服务器的处理性能的两倍,那么RS1的权重可以配置为6,RS2的权重配置为3,无状态。

           3. Destination Hashing : 目标地址散列,简称DH。根据用户请求的目的IP,计算HASH值,映射到固定的RS上,如果该RS还没有超载的话。

           4. Source Hashing : 源地址散列,简称SH。根据用户的IP,计算HASH值,映射到固定的RS上,如果该RS还没有超载的话。

           动态调度算法

           1. Least Connections : 最少链接,简称LC,根据RS的连接状态,选择连接最少的RS。lvs有每个RS连接数的统计,可以使用ipvsadm -l查看当前lvs的状态数据。

           2. Weighted Least Connections :加权最少连接,简称WLC。同样结合了服务器性能权重和连接数两个方面,来选择RS。

           3.  Shortest Expected Delay Scheduling : 最短的期望的延迟,简称SED。分配一个接踵而来的请求以最短的期望的延迟方式到服务器。计算当前RS的负载情况计算方法:(active+1)*256/weight=overhead。

           4. Never Queue Scheduling :最小队列调度,简称NQ。分配一个接踵而来的请求到一台空闲的服务器,此服务器不一定是最快的那台,如果所有服务器都是繁忙的,它采取最短的期望延迟分配请求。

           动态调度算法还有其他的,有兴趣可以去了解。

           此处lb_algo配置时加权最少连接算法

         lb_kind是lvs的转发方式,是前文介绍的NAT/DR/TUN三种方式,此处由于RS和LD不在一个子网,需要使用IP隧道的方式。

         persistence_timeout lvs会话保持时间。

         protocol 连接使用的协议,本例中使用的是HTTP服务,是TCP协议

         ha_suspend suspend healthchecker’s activity,挂起检查进程的活动

         real_server节点是需要配置具体的RS信息,格式是“IP + 端口”,此处使用的是http服务,端口是80。要求RS上必须要开启这个服务,否则keepalived的健康检查进程会报错,从LVS中剔除掉该主机。

             weight 权重,我们此处配置的调度算法是动态调度的加权连接最少算法,需要配置每个RS的权重。此处配置的权值一样,其实就是LC算法。

             TCP_CHECK 健康检查方法,此处选择了TCP CHECK检查方法,该方法会使用TCP去连接RS的IP和端口,需要配置一个超时时间,如果三次都连接失败,会从LVS中将该RS剔除。剔除后还会检查该RS,如果连接成功,会重新将该RS添加到lvs集群中。

             两个RS都是这样配置的,只是IP地址不同。要求两台RS上都运行着HTTP服务,如果一台挂了,那么keepalived会主动剔除故障机。故障机修复后,keepalived也会重新将它添加到lvs集群中。

    每个virtual_server对应vrrp_instance中virtual_ipaddress的配置。本例中virtual_ipaddress中配置了一个VIP,所以virtual_server也配置了一个节点,对应该VIP。

     

    另一台LD上同样配置,优先级和是否抢占配置不同。

     

     

    两台LD配置好了,RS上也要配置。由于本例中使用的是IP隧道的方式转发数据包,需要在RS上启用IP隧道,并且禁止ARP响应。

    启动LVS RealServer的脚本real_server_iptunning.sh:

    运行该脚本 ./real_server_iptunning.sh start

    运行该脚本后,可以使用ifconfig命令查看ip的配置

     

    Step 7. keepalived的启动与停止

    keepalived -D 启动keepalived,之前已经把该文件拷贝到/usr/sbin/目录下,因此可以直接使用该命令。keepalived读取的配置文件是/etc/keepalived/keepalived.conf,日志输出到/var/log/messages该文件

    停止keepalived服务 killall keepalived

     

    同时启动两台LD上的keepalived服务,看日志可以看到每个keepalived的主备状态及绑定的VIP。

    LD启动完成后,需要启动每个RS上的LVS配置,就是运行上文的real_server_iptunnling.sh脚本。

     

    Step 8. 测试容灾与负载均衡

    两台RS上都运行着HTTP服务

     

    访问http://10.12.196.5/

    可以查看两台RS的apche的access日志,看请求落到哪一台了。停止掉刚才访问的那台RS,此时可以看到keepalived的健康检测程序探测到一台RS不可用,主动剔除。

    此时再访问http://10.12.196.5/

    http服务并没有受影响,请求被分配到另外一台RS上。此时重新启动刚才主动停止的RS,继续观察主LD的日志

    RS被重新添加到lvs集群中。

    当主LD挂掉之后,可以看之前BACKUP的LD日志

    该LD启动的时候是备机状态,20s之后主机被关闭,备机接管LD的工作,成为主LD

    容灾分为两部分,一部分是LD的容灾,LD是负责处理请求转发的,这个节点很重要,要保证高可用性。当主LD挂掉的时候,keepalived会自动协商出新的主LD,保证LD的高可用性。当具体的业务主机宕机或者服务不可用的时候,keepalived会控制lvs的配置,将该主机从lvs集群中剔除,保证lvs集群服务的可用性。当业务主机修复后,keepalived不停地探测业务主机的状态,一旦修复,会自动重新加入到lvs集群中。而我们需要做的就是尽快修复业务主机,然后观察业务是否正常。

     

    负载均衡与容灾是个比较大的话题,各种开源的框架为高可用性提供了软件层次上的可能性。keepalived又可以运行在lvs之上,配置也相对简单,是一个比较好的选择。

     

    千里之行,始于足下,共勉。

  • 相关阅读:
    字节和字符,对信息进行编码
    关于TCP的可靠性
    TCP和流
    Socket:流,TCP连接,TCP可靠性概述
    C#中的泛型 Part1
    C# 泛型理解0
    2010 Stanford Local ACM Programming ContestH解题报告
    母函数模板
    poj 1385Lifting the Stone解题报告
    poj 1015Jury Compromise解题报告
  • 原文地址:https://www.cnblogs.com/sliverdang/p/lvs_keepalived.html
Copyright © 2020-2023  润新知