当单服务器的性能无法满足业务需求时,就需要把多台服务器组成集群系统提高整体的处理性能。不过我们要使用统一的入口方式对外提供服务,所以需要一个流量调度器 通过均衡的算法,将用户大量的请求均衡地分发到后端集群不同的服务器上。这就是我们后边要说的负载均衡。
广义上的负载均衡器大概可以分为 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模式
- 数据包到达 INPUT 链,INPUT 是 LVS 主要工作的位置。此时 LVS 会根据目的 IP 和 Port 来确认是否是 LVS 定义的服务,如果是定义过的 VIP 服务,就会根据配置的 Service 信息,从 RealServer 中选择一个作为后端服务器 RS1,然后以 RS1 作为目标查找 Out 方向的路由,确定下一跳信息以及数据包要通过哪个网卡发出。最后将数据包通过 INET_HOOK 到 OUTPUT 链上(Out 方向刚从四层进入网络层)。
- 数据包通过 POSTROUTING 链后,从网络层转到链路层,将目的 MAC 地址修改为 RealServer 服务器 MAC 地址,记为 RMAC;而源 MAC 地址修改为 LVS 与 RS 同网段的 selfIP 对应的 MAC 地址,记为 DMAC。此时,数据包通过交换机转发给了 RealServer 服务器(注:为了简单图中没有画交换机)。
- 请求数据包到达 RealServer 服务器后,链路层检查目的 MAC 是自己网卡地址。到了网络层,查找路由,目的 IP 是 VIP(lo 上配置了 VIP),判定是本地主机的数据包,经过协议栈后拷贝至应用程序(比如这里是 nginx 服务器),nginx 响应请求后,产生响应数据包。以目的 VIP 为 dst 查找 Out 路由,确定吓一跳信息和发送网卡设备信息,发送数据包。此时数据包源、目的 IP 分别是 VIP、CIP,而源 MAC 地址是 RS1 的 RMAC,目的 MAC 是下一跳(路由器)的 MAC 地址,记为 CMAC(为了容易理解,记为 CMAC)。然后数据包通过 RS 相连的路由器转发给真正客户端。
NAT模式原理
NAT模式
- 到达 lvs 后,通过目的 IP 和目的 port 查找是否为 IPVS 服务。若是 IPVS 服务,则会选择一个 RS 作为后端服务器,将数据包目的 IP 修改为 RIP,并以 RIP 为目的 IP 查找路由信息,确定下一跳和出口信息,将数据包转发至 output 上。
- 修改后的数据包经过 postrouting 和链路层处理后,到达 RS 服务器,此时的数据包源 IP 是 CIP,目的 IP 是 RIP。
- 到达 RS 服务器的数据包经过链路层和网络层检查后,被送往用户空间 nginx 程序。nginx 程序处理完毕,发送响应数据包,由于 RS 上默认网关配置为 lvs 设备 IP,所以 nginx 服务器会将数据包转发至下一跳,也就是 lvs 服务器。此时数据包源 IP 是 RIP,目的 IP 是 CIP。
- lvs 服务器收到 RS 响应数据包后,根据路由查找,发现目的 IP 不是本机 IP,且 lvs 服务器开启了转发模式,所以将数据包转发给 forward 链,此时数据包未作修改。
- lvs 收到响应数据包后,根据目的 IP 和目的 port 查找服务和连接表,将源 IP 改为 VIP,通过路由查找,确定下一跳和出口信息,将数据包发送至网关,经过复杂的网络到达用户客户端,最终完成了一次请求和响应的交互。
Tunnel模式原理
Tunnel模式
- 到达 lvs 后,通过目的 ip 和目的 port 查找是否为 IPVS 服务。若是 IPVS 服务,则会选择一个 rs 作为后端服务器,以 rip 为目的 ip 查找路由信息,确定下一跳、dev 等信息,然后 IP 头部前边额外增加了一个 IP 头(以 dip 为源,rip 为目的 ip),将数据包转发至 output 上。
- 数据包根据路由信息经最终经过 lvs 网卡,发送至路由器网关,通过网络到达后端服务器。
- 后端服务器收到数据包后,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
网友评论