CLB简介

传统的LVS负载均衡是一种集群(Cluster)技术,采用IP负载均衡技术和基于内容请求分发技术。LVS有三种工作模式DR模式、NAT模式及TUNNEL模式,三种模式分别都有各自的局限性。这样就催生了CLB概念。套用官网介绍:负载均衡(Cloud Load Balancer)是对多台云服务器进行流量分发的服务。负载均衡可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。

CLB基本概念

这里首先需要了解下腾讯云相关的一些概念,有助于后续了解CLB业务。

基本属性

LB实例

腾讯云提供的一种网络负载均衡服务(CLB),可以结合 CVM 虚拟机为用户提供基于 TCP/UDP/HTTP/HTTPS协议类型的负载均衡服务。

后端服务器

接受负载均衡分发请求的一组云服务器实例,负载均衡服务将访问请求按照用户设定的规则/权重转发到这一组后端 CVM 上进行应用处理。

虚拟地址VIP

腾讯云负载均衡分配给每个负载均衡实例的虚拟地址。客户端可以通过vip+port进行4层负载分发。也可以按照vip+vport+url进行7层负载分发。

监听器

目前存在两种监听器。传统公网固定IP类型的监听器包括监听端口,后端服务器端口、负载均衡策略、健康检查阀值配置和轮训方式等,每个监听器对应后端的一个应用服务。新版的应用型监听器只有监听端口属性(https还有证书信息)。但是监听器下又可以创建域名和规则,规则中可以设置健康检查阀值、负载均衡策略、转发路径等信息。同时监听器维度存在几个概念需要了解下,主要如下:

vport:提供给客户端访问的端口

pport:LB后端服务器需要启动的端口

轮询方式:目前只有权重轮询/ip_hash/最小连接数三种轮询方式

会话保持:保证同一客户端多次请求在一定的时间内落地到后端同一台服务器上

snat:lb是否支持后端服务器可以看到客户端的真实ip,否则RS看到是vip(snat不支持获取客户端ip)

健康检查:针对lb后端服务器端口存活状态进行检测,及时剔除异常端口的机器,保证服务稳定正常

证书

公网LB支持https协议监听器,创建监听器过程中需要上传服务器和客户端证书。

负载均衡类型

内网与公网之分

内网lb主要提供给同appid下的子机之间进行负载均衡请求,lb绑定的子机必须是appid下的子机,客户端请求子机也必须是appid下的子机。

公网lb开发商可以将自己的服务搭建在lb绑定的后端服务器上,然后提供给自己的用户使用进行访问。公网lb对绑定后端子机有一个要求:子机必须要有流量。

基础网络与私有网络之分

基础网络包含vpc0和实体网络子机,这里要求lb绑定的后端服务器必须是基础网络子机。当基础网络与vpc互通之后,基础网络子机也可以访问私有网络的LB服务。

私有网络即所有的vpc>0子机,这里同时要求lb绑定的后端服务器必须是私有网络子机。

物理网络与VPC网络之分

物理网络:这种网络架构是腾讯云最早使用的框架,有非常大的局限性,如下描述:A受物理网络路由限制,子机不能跨机架迁移;B子机ip固定,用户不可自定义;C用户的子机IP无规律,不能划分网段,不方便管理。

VPC网络:为了解决实体网络的限制,应运而生出来了私有网络。VPC网络可以让虚拟机保持IP、MAC不变进行跨机架迁移。用户自定义网络,选择IP地址范围、管理子网、路由表和网关。支持IPSec VPN、SSLVPN、专线接入,满足VPC网络与客户本地数据中心部署混合云需求。

综上所述,所以目前公网LB同样也区分基础网络与私有网络类型。但是底层负载能力实现原理基本保持一致。

七层与四层之分

目前腾讯云内网LB只支持4层负载,不支持7层负载。公网LB同时支持7层和4层负载。下面介绍关于7层与4层的区别见下图。

BIND实现负载均衡 负载均衡clb_nginx

4层LB主要是通过报文中的目的地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。负载能力实现主要基于数据包的传输层信息(ip+port)进行负载转发。

7层LB也成为“内容交换”,主要通过报文中真正有意义的应用层内容(证书,cookies,http头部信息),会在负载均衡设备上进行证书校验,三次握手等操作,再加上负载均衡设备设置的服务器选择方式,决定最终的内服务器。负载能力实现主要基于应数据包应用层信息(domain+port+url等)进行负载转发。

CLB业务架构

首先看下图,简单可以看到公网LB的实现主要是由TGW(tencent gateway)实现。TGW集群承载腾讯流量入口,有着强大的负载均衡能力,当然也有其他重要能力(例如:ip漂移,容灾等)。

BIND实现负载均衡 负载均衡clb_BIND实现负载均衡_02

CLB业务场景

传统场景

大多数用户使用传统的LB主要具有三种使用场景:流量分发;横向扩展;业务分离。腾讯云目前提供两种类型的LB:经典型和应用型。

腾讯云目前提供的经典型LB(公网有日租)基本可以满足大部分用户的使用场景,但是有一定的局限性。 主要局限性表现如下:

  • 每个LB分配一个VIP
  • 分配一个域名(带有腾讯云后缀的域名)
  • LB下可以创建多个监听器(vport-->pport映射)
  • 子机绑定在LB维度

这样就存在多个问题:域名含有腾讯云后缀,用户不可自定义;每个LB-vip对应一个域名,对vip造成大量浪费;7层访问只能细化到域名维度,不能在url维度进行细化。这样就应运而生了应用型LB。

BIND实现负载均衡 负载均衡clb_负载均衡_03

高级场景

针对比较高端的用户使用场景比较复杂,腾讯云推出应用型LB可以在单个LB上实现业务分离,真正基于应用层内容进行负载均衡。如下图所示。这种类型的LB就完全弥补了传统LB的缺陷。主要优点整理如下:

  • 每个LB分配一个VIP
  • 不会分配固有域名,LB下可以创建多个监听器
  • 每个监听器下可以创建多个域名
  • 每个域名下可以创建多个规则
  • 子机绑定在规则维度,并且可以绑定一台子机上的多个端口

这样做的好处比较多:真正发挥http七层转发的优势,CLB开始了解业务;有利于IP收敛,整个网站对外可以只使用一个公网IP;节省二级域名,减少DNS解析次数,有效提高用户访问速度;自定义转发规则,会话保持和健康检查的颗粒度可以细致到转发组级别。

BIND实现负载均衡 负载均衡clb_负载均衡_04

CLB实现

隧道技术区分

公网LB流程中TGW(STGW)中ld集群上需要区分vpc网络和物理网络。vpc网络采用gre隧道封装技术实现TGW和虚拟机之间进行通讯,物理网络采用IP隧道封装技术实现TGW和虚拟机之间进行通讯。7层和4层负载均衡实现分别是在不同的ld集群上进行,当然实现技术也是不一致的。如果不清楚gre和ip隧道区别,请看下图。

BIND实现负载均衡 负载均衡clb_nginx_05

BIND实现负载均衡 负载均衡clb_BIND实现负载均衡_06

根据小编本人理解,gre技术主要应用场景在于该数据包的目的地址不是gre里面封装的ip信息,但是数据包到达目的端之后需要gre的封装信息进行进一步操作(qcloud目前当数据包到达母机之后,母机根据gre信息决定下一步路由);IP隧道主要应用场景在于该数据包的目的地址就是即将要封装的ip信息,可以理解为将新的ip把原来的数据包进行再一次封装,这样数据包才能根据封装的目的ip进行路由。

4层LB

VPC网络

先对4层VPC网络负载均衡整体的架构做简单介绍。用户在qcloud控制台或者调用api操作之后,操作流最终会下发到TGW提供的oss组件模块,该oss模块主要负责提供接口(比分配vip,创建监听器,创建域名和规则等)供qcloud调用,ld上存在组件将接口请求中的相关规则下发到集群内每个ld设备内核中,ld上负载均衡转发功能主要由相关内核模块实现。

数据包入方向

  • 当用户访问vip的时候,首先数据流会到ld中,ld根据下发规则找到vm对应的hostip,然后对数据包进行dnat和sant,将目的ip和源ip分别改为hostip和tsvip。
  • ld上存在gre设备对数据包进行gre封装,将(vpcid,vmip)带入数据包,这样数据包就会将带有gre头的数据包发送给子机所在的母机。
  • vpc母机上存在gre设备对数据包进行解封装,根据vpcid和vmip即可将请求发送给相应虚拟网桥下的对应子机。

数据包出方向

  • 首先在经过虚拟网桥之后gre设备需要对数据包进行gre封装,此时的目的ip为tsvip,源ip为hostip
  • 数据包向tsvip发送回到ld上,在ld上进行去掉gre部分,进行dnat和snat,将源ip和目的ip转换为vip和客户端ip。
  • 则数据包可以正常返回给客户端。这样既可完成一次负载均衡数据交互。

BIND实现负载均衡 负载均衡clb_负载均衡_07

物理网络

整体流程上和vpc基本一样,只是在TGW和cvm之间通讯时通过ip隧道的方式进行的,TGW的ld集群中存在内核模块对数据包进行ip隧道封装和解封装(如下图)。

BIND实现负载均衡 负载均衡clb_腾讯云_08

七层LB

7层LB目前使用的底层架构是STGW(TGW的升级版),这里简单说一下STGW的强大之处。

  • 多协议适配及卸载(支持SSL3~TLS1.2, SPDY3.1, HTTP2, Websocket,对业务透明,减少业务协议适配压力)
  • 内容路由(根据url,header等字段深度匹配,精确、正则、前缀匹配)
  • 负载均衡策略(加权轮询,ip_hash,最小连接数,一致性hash)

7层针对CLB来讲主要是提供http和https服务,https有三大功能:身份认证---防冒充;数据加密---防窃听;数据一致性---防篡改,防抵赖。目前STGW针对https性能做了很大提升,目前已经具有以下特点。

  • 并行支持协议多
  • https计算性能强
  • https防攻击能力强
  • https访问速度快
  • 统一的证书管理及证书远程加载服务

VPC网络

其实和四层的区别主要是中间多了一层l7-ld,如下图所示为vpc公网LB数据流程图,这一层主要是做nginx反向代理和7层负载功能的。本应该ld和实体网络vm之间是可以通过普通的ip包进行数据交互的,但是vpc子机的话,存在私有网络和自定义ip,ld就没法和vm之间进行直接通讯了,目的ip为vpc子机的话,数据包是没法路由的。为了解决上面的问题,TGW在l7-ld上安装了内核模块,该内核用来模拟TGW封装gre包,然后将gre后的数据包和vpc子机进行交互就没有任何问题了。qcloud为腾讯云业务层,oss模块接收到请求之后将规则下发到l7-nginx的配置文件中,l7-nginx通过反向代理功能和nginx本身负载均衡功能会进行domain+port+url维度的负载转发。

BIND实现负载均衡 负载均衡clb_BIND实现负载均衡_09

l7-nginx

l7-nginx提供的反向代理和负载均衡能力,这个是7层负载均衡的核心功能。上面谈到l7-agent会下发业务侧的规则到l7-nginx上,其实就是下发一个nginx的配置文件到l7-nginx上,如下图所示。可以看到这个配置文件里面域名就是用户在控制台配置的域名(www.arlis.com),还有vip、vport信息、子机,权重等信息都存在这个配置文件中。

BIND实现负载均衡 负载均衡clb_BIND实现负载均衡_10

  • 用户访问www.arlis.com:2356/data/test
  • server模块中 server_name用来指定ip或者域名,当用户访问这个域名的时候 server_name将请求匹配给location中/data/test/路径下proxy_pass;这里location会根据不同的路径进行转发给相应的proxy_pass,实现了基于路径转发的能力
  • proxy_pass接下来就交给相应的upstream模块处理了

upstream模块

Upstream为nginx负载均衡的主要模块。它提供了一个简单的方法实现在轮训和客户端ip之间的后端服务器负载均衡,并且可以对后端服务器进行健康检查。upstream并不处理请求,而是通过请求后端服务器得到用户的请求内容。在转发给后端时,默认是轮询,也可以是ip_hash。

nginx健康检查

当Nginx在检测到后端服务器故障后,nginx依然会把请求转向该服务器,当nginx发 现timeout或者refused后,会把改请求会分发到upstream的其它节点,直到获得正常数据后,nginx才会把数据返回给用户,上面配置文件中max_fails和fail_timeout字段就是和健康检查相关的。

物理网络

7层物理网络负载均衡实现方式和vpc网络唯一的不同就是数据包封装技术不同,因为物理网络不需要进行gre封装,直接IP隧道即可实现和子机通讯(如下图)。其他就没有必要再详细说了,和vpc基本保持一致。

BIND实现负载均衡 负载均衡clb_腾讯云_11

请求重定向

目前腾讯云应用型LB支持请求重定向,域名端口 + 规则维度进行重定向。给用户直接的感受就是当你使用url-a在浏览器上进行访问时,请求会被自动重定向到url-b。这里底层的实现也是基于nginx的rewrite操作进行处理。当用户设置了重定向操作之后,会在nginx下发如下配置

BIND实现负载均衡 负载均衡clb_BIND实现负载均衡_12

会话保持实现

Cookie植入

在Cookie插入模式下,CLB将负责插入cookie,后端服务器无需作出任何修改。当客户进行第一次请求时,客户HTTP请求(不带cookie)进入CLB, CLB根据负载平衡算法策略选择后端一台服务器,并将请求发送至该服务器,后端服务器进行HTTP回复(不带cookie)被发回CLB,然后CLB插入cookie,将HTTP回复(带cookie)返回到客户端。当客户请求再次发生时,客户HTTP请求(带有上次CLB插入的cookie)进入CLB,然后CLB读出cookie里的会话保持数值,将HTTP请求(带有与上面同样的cookie)发到指定的服务器,然后后端服务器进行请求回复,由于服务器并不写入cookie,HTTP回复将不带有cookie,恢复流量再次经过进入CLB时,CLB再次写入更新后的会话保持cookie。

实践一下看看,可以看到第一次访问时返回给客户端的cookies值

BIND实现负载均衡 负载均衡clb_nginx_13

BIND实现负载均衡 负载均衡clb_nginx_14

Cookie重写

表示负载均衡系统会根据用户自定义cookie名称来分配和管理对客户端进行的cookie植入操作,便于用户识别和区分自定义的cookie名称,从而有选择的针对后端应用服务器上的不同应用设定会话保持规则,用户在进行配置时需要指定相应的cookie名称。目前腾讯云不支持这种类型(阿里云支持)。

服务器如何分辨请求类型

由于CLB代理了HTTPS的SSL加解密,在后端CVM看来,所有7层请求,都是http请求,客户不便于分辨是http,还是https来源。CLB目前已全局生效,在http header中植入X-Client-Proto:

  • X-Client-Proto: http (client请求为http请求)
  • X-Client-Proto: https (client请求为https请求)

后端nginx/apache可根据该信息判断来源。

服务器如何获取来访者真实IP

针对 7 层(HTTP协议)服务,负载均衡通过 Http Header:X-Real-IP获取来访者真实 IP,该功能已经默认开启,无需配置,也不能修改。针对 4层(TCP协议)服务可以直接获取,无需额外配置。

健康检查请求类型

目前默认是GET方式进行请求,后续会改为默认使用HEAD,可选GET的请求方式。修改后的健康检查使用HTTP/1.1协议 增加了host字段(host字段可配置)。HEAD和GET请求方式的区别如下: HEAD: 只请求页面的首部 GET: 请求指定的页面信息,并返回实体主体。

其中,默认使用HEAD方法请求的话,服务器返回的只是响应标题,可以有效降低后端开销,提高请求效率。但在某些业务场景下依然需要选取GET方式请求,例如在较为苛刻的健康检查时,需要通过判断body中某些字段来获取版本号等,此时HEAD请求返回的数据不足,需要通过GET来实现。

CLB 默认HTTP1.1

HTTP1.0:浏览器接收到头部信息后,接受完Content-Length中定义的长度字节后开始解析页面,但如果服务端有部分数据延迟发送吗,则会出现浏览器白屏,造成比较糟糕的用户体验。HTTP/1.1中引入了Chunked transfer-coding来解决上面这个问题,发送方将消息分割成若干个任意大小的数据块,每个数据块在发送时都会附上块的长度,最后用一个零长度的块作为消息结束的标志。这种方法允许发送方只缓冲消息的一个片段,避免缓冲整个消息带来的过载。该功能,主流的浏览器,以及apache、nginx等web服务器是默认支持的,无需配置。

session同步

实现web集群后,肯定会首先考虑session同步问题,因为通过负载均衡后,同一个IP访问同一个页面会被分配到不同的服务器上,如果session不同步的话,一个登录用户,一会是登录状态,一会又不是登录状态。腾讯云目前实现了集群内session连接定期同步。这样在别的服务器接管故障机器的包时,能够正确找到session,保证提供正常服务。不同集群之间进行session同步,目前腾讯云尚不支持。

利用cookie同步session :session是文件的形势存放在服务器端的,cookie是文件的形势存在客户端的,怎么实现同步呢?方法很简单,就是把用户访问页面产生的session放到cookie里面,就是以cookie为中转站。你访问web服务器A,产生了session把它放到cookie里面了,你访问被分配到web服务器B,这个时候,web服务器B先判断服务器有没有这个session,如果没有,在去看看客户端的cookie里面有没有这个session,如果也没有,说明session真的不存,如果cookie里面有,就把cookie里面的sessoin同步到web服务器B,这样就可以实现session的同步了。

集群容灾

集群容灾,简单来说就是一个集群中一台服务器倒掉不会影响整个集群的服务能力。CLB采用ospf动态路由协议来实现集群的容灾,若一台机器倒掉,ospf协议可以保证在10s以内把机器从集群中剔除。CLB一个集群放在两个接入交换机下,并且保证跨机架的容灾,这样保证在即便有单边的交换机出故障或者单边机架掉电时,本集群的服务不受影响。

抗DDoS攻击

腾讯云有非常厉害的大禹系统来保护业务,但是大禹系统的宙斯盾的检测时长是10s,那么在大禹系统生效之前,可能客户的RS已经被压垮。为了解决这10s内的问题,我们开发了synproxy的功能。目前腾讯云这边的具体实现是:CLB在接收到客户端的三步握手请求时,代理三步握手,在数据包到来之前,不会打扰到RS,一旦第一个包到来,CLB将其缓存,此时再和RS进行三步握手,握手成功之后,将缓存的数据包发送给RS,之后的流程就透传数据包了。这样保证DDos攻击不会到达RS,而是由CLB来承担压力。CLB本身承载能力比较强,又是集群模式,同时又具备资源隔离的能力,所以一般情况下,很难在10s以内把CLB机器压垮。

结束语

本文主要讲述了腾讯云CLB的基本概念,业务架构以及公网LB技术实现。