负载均衡

当单服务器的性能无法满足业务需求时,就需要把多台服务器组成集群系统提高整体的处理性能。不过我们要使用统一的入口方式对外提供服务,所以需要一个流量调度器 通过均衡的算法,将用户大量的请求均衡地分发到后端集群不同的服务器上。这就是我们后边要说的负载均衡
广义上的负载均衡器大概可以分为 3 类,包括:DNS 方式实现负载均衡、硬件负载均衡、软件负载均衡。

DNS实现负载均衡
DNS实现负载均衡

优点:

  • 实现简单,成本低,无需自己开发或维护负载均衡设备;

缺点:

  • 服务器故障切换延迟大,服务器升级不方便;
  • 流量调度不均衡,粒度太粗;
  • 流量分配策略比较简单,支持的算法较少;

硬件负载均衡

目前业界典型的硬件负载均衡设备有两款:F5 和 A10。这类设备性能强劲、功能强大,但价格非常昂贵。
优点:

  • 功能强大:全面支持各层级的负载均衡,支持全面的负载均衡算法;
  • 性能强大:性能远超常见的软件负载均衡器;
  • 稳定性高:商用硬件负载均衡,经过了良好的严格测试,经过大规模使用,稳定性高;
  • 安全防护:除了具备负载均衡外,还具备防火墙、防 DDoS 攻击等安全功能;

缺点:

  • 价格昂贵,就是贵;
  • 扩展性差,无法进行扩展和定制;
  • 调试和维护比较麻烦,需要专业人员服务器故障切换延迟大,服务器升级不方便;

软件负载均衡

目前常见的有 Nginx、HAproxy、LVS。LVS是纯4层的负载均衡,是基于Linux内核中netfilter框架实现的负载均衡系统,运行在内核态,性能是软件负载均衡中最高的。


网络7层模型

优点:

  • 简单:无论是部署还是维护都比较简单;
  • 便宜:买个 Linux 服务器,装上软件即可;
  • 灵活:4 层和 7 层负载均衡可以根据业务进行选择,也可以根据业务特点,比较方便进行扩展和定制功能;

netfilter

netfilter是集成在内核中的,用来定义存储各种规则的。iptable是修改这些规则的工具,修改后存在netfilter里面。
数据包进入Linux服务器时,先进入服务器的netfilter模块中进行判断处理。Linux将用户规则依据功能和规则所处链路位置进行分组,包含四表五链。


四表

  • filter表:过滤数据包,定义允许或者不允许的;
  • nat表:network address translation,网络地址转换功能,主要处理源与目的地址IP和端口的转换;
  • mangle表:用于高级路由信息包,如包头内有更改(如tos改变包的服务类型,ttl包的生存时间,mark特殊标记);
  • raw表:决定数据包是否被状态跟踪机制处理;

  • PREROUTING:对数据包作路由选择前应用此链中的规则;
  • INPUT:进来的数据包应用此规则链中的规则;
  • FORWARD:转发数据包时应用此规则链中的规则;
  • OUTPUT:外出的数据包应用此规则链中的规则;
  • POSTROUTING:对数据包作路由选择后应用此链中的规则;

任何一个数据包,只要经过本机,必将经过这五个链中的其中一个链,来作控制。


netfilter基本原理
LVS的三种工作模式对比
模式 优点 缺点
DR模式 响应数据不经过lvs,性能高;
对数据包修改小,信息保存完整(携带客户端源 IP)
lvs与rs必须在同一个物理网络(不支持跨机房)
rs上必须配置lo和其它内核参数
不支持端口映射
NAT模式 能够支持windows操作系统;支持端口映射。如果rs端口与 vport不一致,lvs除了修改目的IP,也会修改 dport 以支持端口映射。 后端RS需要配置网关;双向流量对lvs负载压力比较大
Tunnel模式 单臂模式,对lvs负载压力小;对数据包修改较小,信息保存完整;可跨机房(不过在国内实现有难度) 需要在后端服务器安装配置ipip模块;需要在后端服务器tunl0配置vip;隧道头部的加入可能导致分片,影响服务器性能;隧道头部IP地址固定,后端服务器网卡hash可能不均;不支持端口映射
缩写

CIP:Client IP,表示的是客户端 IP 地址。
VIP:Virtual IP,表示负载均衡对外提供访问的 IP 地址,一般负载均衡 IP 都会通过 Virtual IP 实现高可用。
RIP:RealServer IP,表示负载均衡后端的真实服务器 IP 地址。
DIP:Director IP,表示负载均衡与后端服务器通信的 IP 地址。
CMAC:客户端的 MAC 地址,准确的应该是 LVS 连接的路由器的 MAC 地址。
VMAC:负载均衡 LVS 的 VIP 对应的 MAC 地址。
DMAC:负载均衡 LVS 的 DIP 对应的 MAC 地址。
RMAC:后端真实服务器的 RIP 地址对应的 MAC 地址。


当客户端请求 www.sina.com.cn 主页,经过 DNS 解析到 IP 后,向新浪服务器发送请求数据,数据包经过层层网络到达新浪负载均衡 LVS 服务器,到达 LVS 网卡时,数据包如下:

  • 源IP地址:即客户端IP地址(CIP,Client IP);
  • 源MAC地址:客户端MAC地址(CMAC,Client MAC),其实是 LVS 连接的路由器的MAC地址(ADSL的路由器,为了容易理解记为 CMAC)
  • 目的IP:即新浪对外服务器的IP地址(VIP,Virtual IP);
  • 目标MAC地址:即新浪对外的服务器的MAC地址(VMAC,Virtual MAC);

数据包到达网卡后,经过链路层到达 PREROUTING 位置(刚进入网络层),查找路由发现目的 IP 是 LVS 的 VIP,就会递送到 INPUT 链上,此时数据包 MAC、IP、Port 都没有修改。

DR模式原理
DR模式
  1. 数据包到达 INPUT 链,INPUT 是 LVS 主要工作的位置。此时 LVS 会根据目的 IP 和 Port 来确认是否是 LVS 定义的服务,如果是定义过的 VIP 服务,就会根据配置的 Service 信息,从 RealServer 中选择一个作为后端服务器 RS1,然后以 RS1 作为目标查找 Out 方向的路由,确定下一跳信息以及数据包要通过哪个网卡发出。最后将数据包通过 INET_HOOK 到 OUTPUT 链上(Out 方向刚从四层进入网络层)。
  2. 数据包通过 POSTROUTING 链后,从网络层转到链路层,将目的 MAC 地址修改为 RealServer 服务器 MAC 地址,记为 RMAC;而源 MAC 地址修改为 LVS 与 RS 同网段的 selfIP 对应的 MAC 地址,记为 DMAC。此时,数据包通过交换机转发给了 RealServer 服务器(注:为了简单图中没有画交换机)。
  3. 请求数据包到达 RealServer 服务器后,链路层检查目的 MAC 是自己网卡地址。到了网络层,查找路由,目的 IP 是 VIP(lo 上配置了 VIP),判定是本地主机的数据包,经过协议栈后拷贝至应用程序(比如这里是 nginx 服务器),nginx 响应请求后,产生响应数据包。以目的 VIP 为 dst 查找 Out 路由,确定吓一跳信息和发送网卡设备信息,发送数据包。此时数据包源、目的 IP 分别是 VIP、CIP,而源 MAC 地址是 RS1 的 RMAC,目的 MAC 是下一跳(路由器)的 MAC 地址,记为 CMAC(为了容易理解,记为 CMAC)。然后数据包通过 RS 相连的路由器转发给真正客户端。
NAT模式原理
NAT模式
  1. 到达 lvs 后,通过目的 IP 和目的 port 查找是否为 IPVS 服务。若是 IPVS 服务,则会选择一个 RS 作为后端服务器,将数据包目的 IP 修改为 RIP,并以 RIP 为目的 IP 查找路由信息,确定下一跳和出口信息,将数据包转发至 output 上。
  2. 修改后的数据包经过 postrouting 和链路层处理后,到达 RS 服务器,此时的数据包源 IP 是 CIP,目的 IP 是 RIP。
  3. 到达 RS 服务器的数据包经过链路层和网络层检查后,被送往用户空间 nginx 程序。nginx 程序处理完毕,发送响应数据包,由于 RS 上默认网关配置为 lvs 设备 IP,所以 nginx 服务器会将数据包转发至下一跳,也就是 lvs 服务器。此时数据包源 IP 是 RIP,目的 IP 是 CIP。
  4. lvs 服务器收到 RS 响应数据包后,根据路由查找,发现目的 IP 不是本机 IP,且 lvs 服务器开启了转发模式,所以将数据包转发给 forward 链,此时数据包未作修改。
  5. lvs 收到响应数据包后,根据目的 IP 和目的 port 查找服务和连接表,将源 IP 改为 VIP,通过路由查找,确定下一跳和出口信息,将数据包发送至网关,经过复杂的网络到达用户客户端,最终完成了一次请求和响应的交互。
Tunnel模式原理
Tunnel模式
  1. 到达 lvs 后,通过目的 ip 和目的 port 查找是否为 IPVS 服务。若是 IPVS 服务,则会选择一个 rs 作为后端服务器,以 rip 为目的 ip 查找路由信息,确定下一跳、dev 等信息,然后 IP 头部前边额外增加了一个 IP 头(以 dip 为源,rip 为目的 ip),将数据包转发至 output 上。
  2. 数据包根据路由信息经最终经过 lvs 网卡,发送至路由器网关,通过网络到达后端服务器。
  3. 后端服务器收到数据包后,ipip 模块将 Tunnel 头部卸载,正常看到的源 ip 是 cip,目的 ip 是 vip,由于在 tunl0 上配置 vip,路由查找后判定为本机 ip,送往应用程序。应用程序 nginx 正常响应数据后以 vip 为源 ip,cip 为目的 ip 数据包发送出网卡,最终到达客户端。
iptables使用示例
iptables -L            // 列出filter表下的规则
iptables -L -t nat     // 列出nat表下的规则

// 允许本机开放从TCP端口20-1024提供的应用服务
iptables -A INPUT -p tcp -m state --state NEW --dport 20:1024 -j ACCEPT

// 屏蔽来自外部的ping(禁止外部机器ping本机)
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j DROP

// 允许本机对外开放TCP端口20、21、25、110以及被动模式FTP端口1250-1280
iptables -A INPUT -p tcp -m multiport --dport 20,21,25,110,1250:1280 -j ACCEPT

// 防止DDos攻击
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
  • 实现内网多个用户用同一个公网地址上网场景,可使用SNAT源地址转换。
    目标地址不变,重新改写源地址,并在本机建立NAT表项,当数据返回时,根据NAT表将目的地址数据改写为数据发送出去时候的源地址,并发送给主机。
  • 实现用一个公网地址(防火墙)做不同内网服务的场景,可用NAT的方式可以隐藏后端服务器的真实地址,更加的安全,使用DNAT目标地址转换。
    源地址不变,重新修改目标地址,在本机建立NAT表项,当数据返回时,根据NAT表将源地址修改为数据发送过来时的目标地址,并发给远程主机。
// 把所有10.8.0.0网段的数据包SNAT成192.168.5.3的ip,然后发出去
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source 192.168.5.3


// 启用DNAT转发,把本机192.168.1.17来自422端口的流量转发到22端口(来自422端口的SSH连接请求与来自22端口的请求等效)
iptables -t nat -A PREROUTING -p tcp -d 192.168.1.17 --dport 422 -j DNAT --to-destination 192.168.1.17:22
// 允许连接到422端口的请求
iptables -t filter -A INPUT -p tcp -m state --state NEW --dport 422 -j ACCEPT
// 保存规则
service iptables save
service iptables restart

你可能感兴趣的:(负载均衡)