0x00 前言
分享几个关于NLB的有趣问题。
0x01 架构概述
- 我有一个internal的NLB(跨两个AZ),监听33端口
- NLB后端有1个EC2实例(实例B),监听22端口
- 我还有一个EC2实例作为客户端(实例A)
0x02 相关问题
2.1 实例B不能正常访问NLB,但是实例A可以
这个最开始我还觉得奇怪,手动测试了一下,确实是这样:
实例B(10.0.0.64是实例B的IP,10.0.1.170是NLB的IP):
[ec2-user@ip-10-0-0-64 ~]$ nc -vz 10.0.1.170 33 Ncat: Version 7.50 ( https://nmap.org/ncat ) Ncat: Connection timed out. [ec2-user@ip-10-0-0-64 ~]$ nc -vz 10.0.0.64 22 Ncat: Version 7.50 ( https://nmap.org/ncat ) Ncat: Connected to 10.0.0.64:22. Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds. [ec2-user@ip-10-0-0-64 ~]$ |
实例A访问NLB和实例B都是可以正常访问的:
[2019-11-01 11:53.25] ~ [Administrator.EC2AMAZ-OKAR8BT] ➤ nc -vz 10.0.1.170 33 Connection to 10.0.1.170 33 port [tcp/*] succeeded! [2019-11-01 11:53.27] ~ [Administrator.EC2AMAZ-OKAR8BT] ➤ nc -vz 10.0.0.64 22 Connection to 10.0.0.64 22 port [tcp/ssh] succeeded! |
请教了一下大佬,这种现象其实是正常的,NLB做的流量转发会把目的IP地址转过去,如果我src IP与dst的IP相等的话,那自然会被丢弃掉,这也就造成了,如果我在后端实例上访问NLB的端口会出现time out的现象。
此外,NLB的官方文档也有对此部分的说明,可以参考:Troubleshoot Your Network Load Balancer中“Connections time out for requests from a target to its load balancer”部分。
上面我是通过实例ID注册的,那我如果通过IP注册(这也是文档中提到的解决方法之一)的话,就不会有这个问题了。效果如下:
[root@ip-10-0-0-64 about-aws-nlb-interesting-qa]# nc -vz 10.0.1.170 44 Ncat: Version 7.50 ( https://nmap.org/ncat ) Ncat: Connected to 10.0.1.170:44. Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds. |
2.2 NLB如果不开通“Cross-Zone Load Balancing”功能,流量是不会跨AZ转发至后端EC2实例的
这个场景比如说,我有一个NLB跨了两个AZ(cn-north-1a,cn-north-1b),然后我后端仅有1台EC2实例(在cn-north-1b中)。如果我访问cn-north-1a的NLB IP,则会出现访问超时的现象,而访问cn-north-1b则不会有这个问题。这是因为我如果没开“Cross-Zone Load Balancing”功能的话,流量是不会跨AZ转发的。
开通“Cross-Zone Load Balancing”功能的方法也很简单,console上点一下:
![](https://img-blog.csdnimg.cn/img_convert/3e8aac5c989b7e76b793c5938b662bb1.png)
完事现在支持跨AZ负载均衡就没啥问题了,当然如果不考虑高可用NLB只有一个AZ的话也没有这个问题了。
(以上内容目前仅测试了internal NLB)
0x03 NLB超时问题
连接空闲超时
对于客户端通过 Network Load Balancer 发出的每个 TCP 请求,都将跟踪该连接的状态。如果客户端或目标通过连接发送数据的间隔超过空闲超时期限,则连接将关闭。如果客户端或目标在空闲超时期限后发送数据,则会收到一个 TCP RST 数据包,以指示连接不再有效。
对于 TCP 流,Elastic Load Balancing 将空闲超时值设为 350 秒。您不能修改此值。客户端或目标可以使用 TCP keepalive 数据包重置空闲超时值。为维护 TLS 连接而发送的 Keepalive 数据包不能包含数据或负载。
虽然 UDP 无连接,但是负载均衡器将基于源和目标 IP 地址和端口保持 UDP 流状态,从而确保属于同一个流中的数据包始终发送到相同的目标。空闲超时期限后,负载均衡器会考虑将传入的 UDP 数据包作为新流,并路由到新的目标。Elastic Load Balancing 将 UDP 流的空闲超时值设置为 120 秒。
EC2 实例必须在 30 秒内响应新请求,才能建立退回路径。