SLB健康检查过程介绍
负载均衡采用集群部署。LVS集群或Tengine集群内的相关节点服务器同时承载了数据转发和健康检查职责。
LVS集群内不同服务器分别独立、并行地根据负载均衡策略进行数据转发和健康检查操作。如果某一台LVS节点服务器对后端某一台ECS健康检查失败,则该LVS节点服务器将不会再将新的客户端请求分发给相应的异常ECS。LVS集群内所有服务器同步进行该操作。
负载均衡健康检查使用的地址段是100.64.0.0/10,后端服务器务必不能屏蔽该地址段。您无需在ECS安全组中额外针对该地址段配置放行策略(ECS安全组检测到流量来自阿里云SLB会自动方向,不会应用安全在规则) ,但如有配置 iptables 等安全策略,请务必放行(100.64.0.0/10 是阿里云保留地址,其他用户无法分配到该网段内,不会存在安全风险)。
HTTP/HTTPS监听健康检查机制
针对七层(HTTP或HTTPS协议)监听,健康检查通过HTTP HEAD探测来获取状态信息,如下图所示。
对于HTTPS监听,证书在负载均衡系统中进行管理。负载均衡与后端 ECS之间的数据交互(包括健康检查数据和业务交互数据),不再通过HTTPS 进行传输,以提高系统性能。
七层监听的检查机制
Tengine节点服务器根据监听的健康检查配置,向后端ECS的内网IP+【健康检查端口】+【检查路径】发送HTTP HEAD请求(包含设置的【域名】)。
后端ECS收到请求后,根据相应服务的运行情况,返回HTTP状态码。
如果在【响应超时时间】之内,Tengine节点服务器没有收到后端ECS返回的信息,则认为服务无响应,判定健康检查失败。
如果在【响应超时时间】之内,Tengine节点服务器成功接收到后端ECS返回的信息,则将该返回信息与配置的状态码进行比对。如果匹配则判定健康检查成功,反之则判定健康检查失败。
TCP监听健康检查机制
针对四层TCP监听,为了提高健康检查效率,健康检查通过定制的TCP探测来获取状态信息,如下图所示。
UDP监听健康检查
针对四层UDP监听,健康检查通过UDP报文探测来获取状态信息,如下图所示。
UDP监听的检查机制
LVS节点服务器根据监听的健康检查配置,向后端ECS的内网IP+【健康检查端口】发送UDP报文。
如果后端ECS相应端口未正常监听,则系统会返回类似返回 port XX unreachable的ICMP报错信息;反之不做任何处理。
如果在【响应超时时间】之内,LVS节点服务器收到了后端ECS返回的上述错误信息,则认为服务异常,判定健康检查失败。
如果在【响应超时时间】之内,LVS节点服务器没有收到后端ECS返回的任何信息,则认为服务正常,判定健康检查成功。
实验环境搭建
-
创建一个共享型的SLB实例,然后开始配置监听。
-
点击添加监听
-
选择默认服务器组,我这只是测试没有创建自己的服务器组,选择我刚创建的ECS,这里我为了测试只有一台ECS,在实际的使用中,SLB后端最少需要监听两台ECS,不然SLB的使用就完全没有意义了。
-
选择后端监听端口为80
-
四层监听是默认开启健康检查的且无法关闭
注意: SLB监听的ECS安全组是不会拦截SLB的连接访问,所以如果遇到问题,不需要排查安全组的问题,只需要直接排查网络和ECS内部配置。 -
ECS实例安装 nginx 软件,centos 可以通过下面的命令快速安装和启动
yum install nginx service nginx start
-
安装完成后测试访问SLB和ECS的80端口是正常的
-
安装FTP服务器来下载抓包文件,创建了一个账号ftptest 用于FTP的下载,需要授权FTP 对指定路径的文件夹的下载权限。
yum install -y vsftpd
-
在服务器侧用tcpdump 的命令进行抓包,抓取 SLB 健康检查的网络包,然后通过 wireshark 分析抓包文件,来验证一下SLB 是否是上面描述的方式进行探测
tcpdump tcp -i eth0 -w ./target.cap
验证健康检查方式
四层TCP监听
首先我这里模仿的是四层TCP监听,抓包文件分析如下,可以看出来四层的监听如上面介绍,三次握手后SLB 侧 RST连接:
七层HTTP监听
下面我将验证 七层HTTP的监听 是否如上面介绍的原理,首先删除之前四层的监听,配置七层的监听,健康检查状态正常。
通过后端的抓包验证一下是否正确,这里可以看到确实是通过head的方式进行健康检查,正常的健康检查交互过程如下:
有时候会发生客户Nginx配置禁用了HEAD方法或者配置了特殊返回不正常的HTTP code,导致SLB健康检查失败,现象是SLB健康检查失败,但是直接访问后端ECS是没有问题的,客户会怀疑SLB的健康检查有问题,遇到这种问题最好是在服务器端抓一个包,看一下服务器是否接收到SLB的健康检查, 是否返回了正确的状态,当然也可以通过SLB的健康检查日志来看一下服务器的返回健康检查是否正确。下面是NGINX配置文件修改,然后重启NGINX。
然后我们发现过一会SLB的健康检查会失败
通过服务器的抓包文件我们可以看到下面现象,符合前面介绍的七层HTTP健康检查的方式,我这里返回的是405而不是设定的200,所以SLB健康检查失败。
如果后端ECS实例的服务关闭HEAD方法,会导致健康检查失败。建议在本地用HEAD方法访问ECS公网IP地址进行测试:
curl -v -0 -I -H "Host:" -X HEAD http://IP:port
直接访问服务器是可以看HEAD方法也是返回失败的,也可以验证是健康检查失败的原因是由于服务器HEAD的方法处理不正确的原因。
四层UDP监听
创建一个新的 UDP 监听TFTP服务,TFTP是基于UDP协议的,创建好的监听状态是正常的。
抓包命令替换为UDP协议, 服务器抓包看到SLB是不断通过UDP报文探测,服务器不反馈ICMP unreachable,SLB 即认为ECS监听状态正常。
tcpdump udp -i eth0 -w ./target.cap
总结:
负载均衡通过健康检查来判断后端服务器(ECS实例)的业务可用性。健康检查机制提高了前端业务整体可用性,避免了后端ECS异常对总体服务的影响。开启健康检查功能后,当后端某台ECS健康检查出现异常时,负载均衡会自动将新的请求分发到其它健康检查正常的ECS上;而当该ECS恢复正常运行时,负载均衡会将其自动恢复到负载均衡服务中。如果您的业务对负载敏感性高,高频率的健康检查探测可能会对正常业务访问造成影响。您可以结合业务情况,通过降低健康检查频率、增大健康检查间隔、七层检查修改为四层检查等方式,来降低对业务的影响。但为了保障业务的持续可用,不建议关闭健康检查。
参考:
https://help.aliyun.com/knowledge_detail/60152.html
https://help.aliyun.com/document_detail/98226.html
https://help.aliyun.com/document_detail/85959.html
抓包文件:
https://github.com/Dushibing/SLBPacketcapture