keepalived+lvs 架构

keepalived+lvs 是比较常用的一种架构,它能够很容易地实现高可用和负载均衡,在互联网公司使用较为广泛,适用于 web ,ftp,缓存,数据库等多种场景。

一、keepalived

keepalived 官方网站:https://www.keepalived.org/

Keepalived 是一个用 C 语言编写的开源免费的路由软件,主要目的是为 Linux 平台上的系统提供简单、稳定、可靠的负载均衡和高可用功能,防止单点故障。其中负载均衡依赖于 Linux 虚拟服务器 Linux Virtual Server(IPVS)内核模块提供的 4 层负载均衡。Keepalived 实现了一组检查程序,根据服务器的运行状况动态地、自适应地维护和管理负载均衡服务器池。Keepalived 的高可用通过 VRRP 协议实现,VRRP 协议是故障转移的基础。

1.1 VRRP 协议

VRRP,虚拟路由冗余协议(Virtual Router Redundancy Protocol),简单点说,就是实现地址漂移,是一种容错协议。Keepalived 在部署时通常一个 Master,多个 Backup,Master 节点周期性地发送 VRRP 报文,在虚拟路由器中公布其配置信息(优先级等)和工作状况。Backup 节点通过接收到 VRRP 报文的情况来判断 Master 路由器是否工作正常,在不正常的情况下接管 Master 的工作。

VRRP 根据优先级来确定每个节点的角色(Master 或 Backup)。优先级越高,则越有可能成为Master,VRRP 优先级的可配置的取值范围为 1 到 254。

1.2 组播与单播

keepalived 早期版本只支持组播,从 1.2.8 版本开始支持单播,keepalived 组播模式下所有的信息都会向 224.0.0.18 的组播地址发送,产生众多的无用信息,可能导致干扰和冲突,尤其在一个网段内部署多组 keepalived 时更为严重,可以通过对 keepalived vrrp 协议抓包,查看网络情况:

tcpdump -iany vrrp

另外在某些云环境中,网络不支持组播,此时 keepalived Backup 节点收不到 Master 的 VRRP 通告,就会出现脑裂(split brain)现象,此时集群中会存在多个 Master 节点。这种情况就需要将组播改为单播,单播是一种更安全的方法,能够避免局域网内大量 keepalived 集群造成虚拟路由 id 的冲突。

单播模式,需要在配置中加入单播的源地址和目标地址,单播模式需要关闭 vrrp_strict,如下:

unicast_src_ip 172.20.27.10 #配置单播的源地址
unicast_peer {
    172.20.27.11 #配置单播的目标地址
}
1.3 virtuall_router_id 冲突问题

virtuall_router_id 取值在 0-255 之间,用来区分多个 instance 的 VRRP 组播,在同一网段内,如果有多组 keepalived 的话,每组的 virtuall_router_id 不能相同,否则会报错如下:

Sep  3 14:38:45 mydb01 Keepalived_vrrp[17228]: ip address associated with VRID not present in received packet : 192.168.2.103
Sep  3 14:38:45 mydb01 Keepalived_vrrp[17228]: one or more VIP associated with VRID mismatch actual MASTER advert
Sep  3 14:38:45 mydb01 Keepalived_vrrp[17228]: bogus VRRP packet received on eth0 !!!
Sep  3 14:38:45 mydb01 Keepalived_vrrp[17228]: VRRP_Instance(VI_1) ignoring received advertisment...

单播模式下,多个 keepalived 集群,其 virtuall_router_id 值可以相同,virtuall_router_id 值必须要设置,如果不设置该值,会在日志中看到如下错误:

VRRP_Instance(VI_1) the virtual id must be set!

二、lvs

lvs 官方网站:http://www.linux-vs.org/

lvs 是 Linux 虚拟服务器(Linux Virtual Server)的简称,与 virtual server 对应的是 real server,lvs 通过一组 real server 实现了系统的高可用和高可扩展性。用户通过 virtual server 进行业务访问,lvs 内部将连接转发到 real server,实现负载均衡和高可用。lvs 可用于 web,cache,mail,ftp,database 等多种场景。

lvs 因为使用了 virtual server,所以需要申请 vip 资源。vip 与 主机实际 ip 并没有太大的区别,都在一个网段内,实际 ip 与主机绑定,实际 ip 在主机的生命周期内不会发生变动,而 vip 与具体哪个主机绑定是不固定的,在满足一定条件下,会从一个主机漂移到另一个主机。

keepalived + lvs 能够实现负载均衡,业务只需要访问 vip,lvs 会根据实际的 real server 进行流量的转发。当有多个 real server 时,就实现了负载均衡,同时某个 real server 发生故障,这套架构会自动将故障 real server 摘除,该节点恢复后,能够重新加入到流量分发中。

keepalived 与 lvs 本身也是高可用的,可以部署在多个节点上,比如一个 master,一个 backup,master 节点挂掉,它会自动切到 backup 节点,实现 keepalived 和 lvs 的故障转移。

keepalived 与 lvs 可以独立部署,也可以与后端服务部署在一起,因为 keepalived 与 lvs 本身对资源消耗不大,为了节省资源,将其与后端服务部署在一起也是一种不错的选择。

2.1 lvs 的组成
  • lvs 由 2 部分程序组成,包括 ipvs 和 ipvsadm。ipvs(ip virtual server):工作在内核空间,是真正生效实现调度的代码。
  • ipvsadm:工作在用户空间,负责为 ipvs 内核框架编写规则,定义谁是集群服务,而谁是后端真实的服务器(real Server)。
2.2 lvs 相关术语
  • DS:Director Server, 指的是前端负载均衡器节点。
  • RS:Real Server, 后端真实的工作服务器。
  • VIP:向外部直接面向用户请求,作为用户请求的目标IP地址。
  • DIP:Director Server IP, 前端负载均衡器IP地址,主要用于和内部主机通信。
  • RIP:Real Server IP, 后端服务器的IP地址。
  • CIP:Client IP, 访问客户端的IP地址
2.3 lvs 工作模式

(1)LVS-DR 模式:

DR 模式(Virtual Server via Direct Routing),客户端向 vip 发送请求,vip 绑在 Director(调度器)上,Director 根据调度算法将这一请求转发给 real server,注意在转发的过程中,仅仅是修改了数据报文中的 mac 地址,所以这也是为什么我们要求Director 和 real server 必须在同一个物理网络内,就是为了保证可以通过修改 mac 地址而进行数据报文的转发。当 real server 处理请求,响应数据,发送响应数据给客户端,按理说此时的数据包的源 ip 为 real server 的 ip,目标 ip 为 client 的 ip,虽然能找到客户端,但是客户端是不收该数据包的,因为客户端并没有请求该 real server 的 ip,现在的做法就是进行 ip 欺骗,即就是修改源 ip 为 vip,但是不可以将 vip 设置在出口网卡上,否则会响应客户端的 arp request,造成 client/gateway arp table 紊乱,以至于整个 load balance 都不能正常工作。要在 lo 接口上配置 vip,并将此 vip 屏蔽。

LVS-DR 模式数据包流向分析:

  1. 用户发送请求到 Director Server,请求的数据报文(源 IP 是 CIP,目标 IP 是 VIP)到达内核空间。
  2. 由于 DS 和 RS 在同一个网络中,所以是通过二层数据链路层来传输。
  3. 内核空间判断数据包的目标 IP 是本机 IP,此时IPVS 比对数据包请求的服务是否为集群服务,若是,重新封装数据包,修改源 MAC 地址为 DIP 的 MAC 地址,目标 MAC 地址为 RIP 的 MAC 地址,源 IP 地址与目标 IP 地址没有改变,然后将数据包发送给 Real Server。
  4. RS 发现请求报文的 MAC 地址是自己的 MAC 地址,就接收此报文,重新封装报文(源 IP 地址为VIP,目标 IP 为 CIP),将响应报文通过 lo 接口传送给 eth0 网卡然后向外发出。
  5. RS 直接将响应报文传送到客户端。

LVS-DR 模式的特点:

  1. RS 和 DS 必须在同一个物理网络中。
  2. RS 可以使用私有地址,也可以使用公网地址,如果使用公网地址,可以通过互联网对 RIP 进行直接访问。
  3. 所有的请求报文经由 Director Server,但响应报文必须不能经过 Director Server。
  4. RS 的网关绝不允许指向 DIP (不允许数据包经过Director)。
  5. RS 上的 lo 接口配置 VIP 的 IP 地址。

LVS-DR 模式注意事项:

保证前端路由将目标地址为 VIP 报文统统发给 Director Server,而不是 RS。

解决方案是:修改 RS 上内核参数(arp_ignore 和 arp_announce)将 RS 上的 VIP 配置在 lo 接口的别名上,并限制其不能响应对VIP地址解析请求。arp_ignore=1 表示系统只响应目的 IP 为本地 IP 的 ARP 请求。arp_announce=2 表示系统不使用 IP 包的源地址来设置 ARP 请求的源地址,而选择发送接口的 IP 地址。

LVS-DR 模式设置内核参数如下:

  • net.ipv4.conf.lo.arp_ignore = 1
  • net.ipv4.conf.lo.arp_announce = 2
  • net.ipv4.conf.all.arp_ignore = 1
  • net.ipv4.conf.all.arp_announce = 2

(2)LVS-NAT 模式:

LVS-NAT 模式数据包流向分析:

  1. 用户发送请求到 Director Server,请求的数据报文(源 IP 是 CIP,目标 IP 是 VIP)到达内核空间。
  2. 内核空间判断数据包的目标 IP 是本机,此时 IPVS 比对数据包请求的服务是否为集群服务,若是,修改数据包的目标 IP 地址为后端服务器 IP,重新封装数据包(源 IP 为 CIP,目标 IP 为 RIP),然后选路将数据包发送给 Real Server。
  3. Real Server 比对发现目标 IP 是本机的 IP,重新封装报文(源 IP 为 RIP,目标 IP 为 CIP)发回给 Director Server。
  4. Director Server 重新封装数据包,将源 IP 地址修改为自己的 VIP 地址,然后响应给客户端。 此时报文的源 IP 为 VIP,目标 IP 为 CIP。

LVS-NAT 模式的特点:

  1. RS 必须使用私有 IP 地址,网关指向 DIP。
  2. DIP 与 RIP 必须在同一网段内。
  3. DS 作为所有服务器节点的网关,也就是说请求和响应报文都需要经过 Director Server。
  4. 支持端口映射
  5. 高负载场景中,Director Server 压力比较大,易成为性能瓶颈。
2.4 lvs的负载均衡调度算法

最常用的有四种;轮询(rr)、加权轮询(wrr)、最少连接(lc)和加权最少连接(wlc)。

  1. 轮询(rr):将收到的访问请求按照顺序轮流调度到不同的服务器上,不管后端真实服务器的实际连接数和系统负载。
  2. 加权轮询(wrr):给 RS 设置权重,权重越高,那么分发的请求数越多,权重的取值范围 0–100。根据每台服务器的性能,给每台服务器添加权值,如果 RS1 的权值为 1,RS2 的权值为 2,那么调度到 RS2 的请求会是 RS1 的 2 倍。权值越高的服务器,处理的请求越多。这种算法是对 rr 算法的一种优化和补充。
  3. 最少连接(lc):根据后端 RS 的连接数来决定把请求分发给谁,比 RS1 连接数比 RS2 连接数少,那么请求就优先发给 RS1。
  4. 加权最少连接(wlc):根据后端 RS 的权重和连接数来决定把请求分发给谁,权重较高,连接数少的 RS 会优先处理请求。

三、keepalived+lvs 常用示例

安装 keepalived:
yum install keepalived -y

安装 ipvsadm:
yum install ipvsadm -y

3.1 高可用

场景:
有两个数据库节点,1主1从,客户端通过 vip 查询数据库。vip 绑在 从库上,在从库挂掉的情况下,vip 自动漂移到主库,保证业务可用性。

  • 数据库主库(Keepalived Master):192.168.56.101
  • 数据库从库(Keepalived Backup):192.168.56.102
  • vip:192.168.56.103

数据库主库同时也是 keepalived 的 Master 节点,数据库从库同时也是 keepalived 的 Backup 节点,Master 节点配置如下:

/etc/keepalived/keepalived.conf

vrrp_script check1 {
    script "/opt/test1.sh"
    interval 2
    weight 1
}
vrrp_script check2 {
    script "/opt/test2.sh"
    interval 1
    weight 3
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 101
    priority 100
    advert_int 1
    track_script {
        check1
        check2
    }
    virtual_ipaddress {
       192.168.56.103
    }

    unicast_src_ip 192.168.56.101
    unicast_peer {
        192.168.56.102
    }
 }

由于使用了单播,主备节点的 keepalived 配置主要区别在于 unicast_src_ip 和 unicast_peer,分别配置为本机 IP 和 对端 IP。不使用单播的话,去掉 unicast_src_ip 和 unicast_peer 配置项,主备节点的 keepalived 配置完全相同。

keepalived 的主备角色可以通过自定义脚本 check1,check2 来决定,比如让数据库从节点获取更高的权重,那么业务通过 vip 访问数据库将优先连接到从库,从库挂掉后,vip 会自动漂移到主库,业务也随之连接到主库。

check1 和 check2 中定义了具体执行的脚本,脚本执行的时间间隔,以及权重值,当脚本返回 0 时,节点权重值增加,返回非 0 时,则不增加权重。

3.2 负载均衡
  • keepalived Master:192.168.56.99
  • keepalived Backup:192.168.56.100
  • 数据库主库:192.168.56.101
  • 数据库从库:192.168.56.102
  • vip:192.168.56.103

场景:

业务连接 vip,能够将业务流量均衡地转发到后端数据库主从节点上。

配置步骤:

(1)在 real server 上设置内核参数

  • net.ipv4.conf.lo.arp_ignore = 1
  • net.ipv4.conf.lo.arp_announce = 2
  • net.ipv4.conf.all.arp_ignore = 1
  • net.ipv4.conf.all.arp_announce = 2

(2)在 real server 的 lo 上配置 vip 地址

如果不需要持久化,直接执行下面命令即可:

ip addr add 192.168.56.103/32 dev lo

如果需要持久化虚拟网络配置,如下:

cd /etc/sysconfig/network-scripts/
cp ifcfg-lo ifcfg-lo:0
vim ifcfg-lo:0

DEVICE=lo:0
IPADDR=192.168.56.103
NETMASK=255.255.255.255   #子网掩码必须全为1
ONBOOT=yes 1

ifup lo:0
ifconfig

执行 ifconfig 查看 lo:0 虚拟网卡接口是否配置成功。

(3)在 director server 上开启路由功能,关闭Linux 内核重定向参数响应

vim /etc/sysctl.conf

net.ipv4.ip_forward=1
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.ens33.send_redirects = 0

sysctl -p #保存

(4)在 director server 上配置 keepalived

Master 节点:

 global_defs {
    notification_email {
    }
    notification_email_from mail@example.org
    smtp_connect_timeout 30
    router_id LVS_01        #指定名称,Backup节点名称不同         
}

 vrrp_instance VI_1 {       #定义VRRP热备实例
    state MASTER            #MASTER表示主调度器
    interface ens33         #承载VIP地址的物理接口
    virtual_router_id 51    #虚拟路由器的ID号,每个热备组保持一致
    priority 100            #主调度器优先级
    advert_int 1            #通告间隔秒数
    authentication {        #认证信息
        auth_type PASS      #认证类型
        auth_pass 1111      #字码密串
    }
    virtual_ipaddress {     #指定群集VIP地址,也就是漂移地址
        192.168.56.103
    }
}

virtual_server 3306 {                 #虚拟服务器VIP地址
    delay_loop 6                      #健康检查的间隔时间
    lb_algo rr                        #轮询rr的调度算法
    lb_kind DR                        #直接路由工作模式
    persistence_timeout 0             #连接保持时间
    protocol TCP                      #应用服务采用的是TCP协议

    real_server 192.168.56.101 3306 { #第一个mysql节点的服务器地址、端口
        weight 1
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306       
        }
    }

    real_server 192.168.56.102 3306 { #第二个mysql节点的服务器地址、端口
        weight 1
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
            connect_port 3306
        }
    }
}

Backup 节点:

  • router_id LVS_01 -> router_id LVS_02 #Backup节点名称
  • state MASTER -> state BACKUP #从调度器
  • priority 100 -> priority 90 #从调度器优先级

启动 keepalived:

#先主后从分别启动 keepalived
systemctl start keepalived

(4)动态添加删除real server:

ipvsadm -a -t $VIP:3306 -r $RIP1:3306 -g
ipvsadm -d -t $VIP:3306 -r $RIP1:3306 -g

以上是组播的 keepalived 负载均衡配置,如果网络环境不支持组播,需要配置单播:

unicast_src_ip 192.168.56.99 #配置单播的源地址
unicast_peer {
    192.168.56.100 #配置单播的目标地址
}

四、director server 与 real server 部署在同一台机器上

director server 与 real server 分开部署会浪费机器资源,尤其在访问量不大的情况下,资源浪费更为严重。这时可以考虑将 director server 和 real server 部署在同一台机器上,节点机器资源。

比如数据库1主1从,在两台数据库机器上同时部署两个 director server。但是由于 lvs-dr 模式下,负载均衡从一个 director server 转发到另外一个 director server,会产生循环转发,为了避免这个问题,需要在 director server 上为网络包打上标记(mark),区分哪些包需要负载均衡进行转发,哪些不再转发。

在 Master 节点,执行如下命令:

iptables -t mangle -I PREROUTING -d $VIP -p tcp -m tcp --dport 3306 -m mac ! --mac-source $backup_physical_addr -j MARK --set-mark 0x1

在 Backup 节点,执行如下命令:

iptables -t mangle -I PREROUTING -d $VIP -p tcp -m tcp --dport 3306 -m mac ! --mac-source $master_physical_addr -j MARK --set-mark 0x2

keepalived 配置文件上加上 fwmark,Master 节点为 1,Backup 节点为 2,如下所示:

virtual_server fwmark 1 {
        delay_loop 10
        lb_algo rr
        lb_kind DR
        protocol TCP
 
        real_server 192.168.56.101 3306 {
        ...
        }
}

设置 fwmark 后,动态增加删除 real server,使用如下命令:

Master节点:

  • ipvsadm -a -f 1 -r $real_server_ip:3306
  • ipvsadm -d -f 1 -r $real_server_ip:3306

Backup节点:

  • ipvsadm -a -f 2 -r $real_server_ip:3306
  • ipvsadm -d -f 2 -r $real_server_ip:3306

文章评论

0条评论