diff --git a/assets/balancer-edge-proxy.svg b/assets/balancer-edge-proxy.svg index 3c786ef3..13755bbf 100644 --- a/assets/balancer-edge-proxy.svg +++ b/assets/balancer-edge-proxy.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/balancer-sdk.svg b/assets/balancer-sdk.svg index da06e28c..10a69cff 100644 --- a/assets/balancer-sdk.svg +++ b/assets/balancer-sdk.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/balancer-sidecar.svg b/assets/balancer-sidecar.svg index c3a5fa07..615a2e75 100644 --- a/assets/balancer-sidecar.svg +++ b/assets/balancer-sidecar.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/balancer.svg b/assets/balancer.svg index d7905795..05418b21 100644 --- a/assets/balancer.svg +++ b/assets/balancer.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/balancer4-NAT.svg b/assets/balancer4-NAT.svg index b076cfe1..0990973e 100644 --- a/assets/balancer4-NAT.svg +++ b/assets/balancer4-NAT.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/balancer4-dsr.svg b/assets/balancer4-dsr.svg index 1f2b94af..10134332 100644 --- a/assets/balancer4-dsr.svg +++ b/assets/balancer4-dsr.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/balancer4-tunnel.svg b/assets/balancer4-tunnel.svg index 416f84c3..4a8c86f1 100644 --- a/assets/balancer4-tunnel.svg +++ b/assets/balancer4-tunnel.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/balancer4.svg b/assets/balancer4.svg index e47511eb..a3888610 100644 --- a/assets/balancer4.svg +++ b/assets/balancer4.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/balancer7.svg b/assets/balancer7.svg index a6f217ce..c83fae0f 100644 --- a/assets/balancer7.svg +++ b/assets/balancer7.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/l4-connection-v2.svg b/assets/l4-connection-v2.svg index 4f92acb0..ccaddf09 100644 --- a/assets/l4-connection-v2.svg +++ b/assets/l4-connection-v2.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/balance/balance-topology.md b/balance/balance-topology.md index e154c8d4..1473a523 100644 --- a/balance/balance-topology.md +++ b/balance/balance-topology.md @@ -6,9 +6,9 @@ 下面介绍的每种拓扑都适用于四层和七层负载均衡器。 ::: -第一种类型为中间代理型拓扑,如图 4-2 所示。这应该是大家最熟悉负载均衡部署模式,负载均衡器位于客户端和后端服务器之间,将客户端的请求转发至多个后端服务器。 +第一种类型为中间代理型拓扑,如图 4-2 所示。 -部分明显具有中间代理拓扑特征的负载均衡产品有: +中间代理型拓扑应该是大家最熟悉负载均衡部署模式,负载均衡器位于客户端和后端服务器之间,将客户端的请求转发至多个后端服务器。明显具有中间代理拓扑特征的负载均衡产品有: - 硬件设备:Cisco、Juniper、F5 Networks 等公司的产品。 - 云软件解决方案:阿里云的 SLB(Server Load Balancer),AWS 的 ELB(Elastic Load Balancer)、Azure 的 Load Balancer 和 Google Cloud 的 Cloud Load Balancing 等。 @@ -23,10 +23,9 @@ 图 4-2 中间代理型负载均衡拓扑 ::: - 第二种边缘代理型拓扑实际上是中间代理型拓扑变种。 -一个具体的边缘代理示例是本书第二章 2.7 节中提到的动态请求“加速”技术。Akamai 的服务部署在全球多个数据中心,用户的请求被路由至距离最近的 Akamai 边缘节点。边缘节点接收请求后,进行安全检查(如 DDoS 防护),根据缓存策略决定是否返回缓存内容,或将请求继续转发至源服务器。 +一个具体的边缘代理示例是本书第二章 2.7 节中提到的动态请求“加速”技术。Akamai 的服务部署在全球多个数据中心,用户的请求被路由至距离最近的 Akamai 边缘节点。边缘节点接收请求后,执行安全检查(如 DDoS 防护),根据缓存策略决定是否返回缓存内容(CDN 技术),或将请求继续转发至源服务器(请求加速技术)。 总结边缘代理型拓扑的优缺点: - 优点是,将负载均衡逻辑(还有缓存、安全策略等)集中在网络边缘,能够显著减少延迟,提高网站的响应速度,增强安全性(预防 DDos); diff --git a/balance/balance4.md b/balance/balance4.md index 39249512..a9eb3d1e 100644 --- a/balance/balance4.md +++ b/balance/balance4.md @@ -1,27 +1,32 @@ # 4.4 四层负载均衡技术 -软件层面实现的四层负载均衡器典型代表是 LVS(Linux Virtual Server)。 +软件层面四层负载均衡器的典型代表是 LVS(Linux Virtual Server,Linux 虚拟服务器)。 -从 Linux 内核 2.4 版本起,LVS 已经是 Linux 内核网络栈的一部分,它基于本书第三章介绍的 Netfilter 的钩子捕获数据包并进行相应修改,在内核网络栈层面实现请求的转发。 +从 Linux 内核 2.4 版本起,LVS 被集成进 Linux 内核,它基于本书第三章介绍的 Netfilter 的钩子捕获数据包并进行相应修改,在内核网络栈层面,将这些请求按照负载均衡算法转发至“后端服务器”。 -根据数据包的修改方式,LVS 提供三种工作模式:直接路由(DR,Direct Routing)、隧道(Tunnel)和网络地址转换(NAT,Network Address Translation)。 +:::tip +LVS 称 Linux 虚拟服务器,相应的,实际执行请求的称真实服务器(real server)。为了简化表述,本节统一称“后端服务器”。 +::: + +根据数据包的修改方式,LVS 有了三种工作模式:直接路由(DR,Direct Routing)、隧道(Tunnel)和网络地址转换(NAT,Network Address Translation)。 ## 4.4.1 直接路由模式 -LVS 的 DR 模式,实际上是一种链路层负载均衡技术。 +LVS 的直接路由模式,实际上是一种链路层负载均衡技术。 + +链路层负载均衡的原理是,负载均衡器(LVS)接收请求后,修改数据帧的目标 MAC 地址,将原本发给负载均衡器的数据帧重新定向,经过二层交换机转发至某个“后端服务器”。 -链路层负载均衡的原理是,负载均衡器在接收到请求后,修改数据帧的目标 MAC 地址,将原本发给负载均衡器的数据帧重新定向,经过二层交换机转发至某个真实服务器(Real Server),使得该真实服务器接收到原本并非直接发给它的数据帧。 -真实服务器的网卡接收数据帧后,因为 IP 层的目的 IP 并非本机,所以内核中的网络协议栈实际上无法处理该数据包。为了解决这个问题,需要将虚拟 IP(VIP,详细介绍将在下一节中提供)配置到本地回环接口(lo)上。这样,请求到达真实服务器后,内核的网络协议栈就能识别并正常接收该数据包。 +后端服务器解包数据帧,会发现 IP 层的目的 IP 并非本机,所以 Linux 内核网络协议栈无法继续处理该数据包。为了解决这个问题,后端服务器需要将虚拟 IP(VIP,Virtual IP)配置到本地回环接口(lo)上。这样,Linux 内核网络协议栈就能识别并正常处理该数据包。 -如某个虚拟 IP(VIP)为 1.1.1.1,通过以下命令将该 IP 绑定到真实服务器的 lo 接口: +如某个 VIP 为 1.1.1.1,通过以下命令将该 IP 绑定到后端服务器的 lo 接口: ```bash // 这里 /32 表示单个 IP 地址,也即仅将 VIP 绑定到 lo 接口,不与其他 IP 地址共享子网。 $ ip addr add 1.1.1.1/32 dev lo ``` -为了避免真实服务器对 VIP 抢答 ARP 请求,从而导致网络问题,还必须禁用真实服务器对 VIP 的 ARP 应答。命令如下所示: +为了避免后端服务器对 VIP 抢答 ARP 请求,从而导致网络问题,还必须禁用后端服务器对 VIP 的 ARP 应答。命令如下所示: ```bash $ echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore @@ -32,26 +37,28 @@ $ echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore $ echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce ``` -经过上述配置后,真实服务器在本地回环接口(lo)上检测到目标 IP 为 VIP(配置的 1.1.1.1)的数据包时,将其识别为自己的地址并处理请求。处理完成后,真实服务器通过其外部接口(如 eth0)发送响应数据时,会保持原始请求中的目的 IP 地址,即 VIP(1.1.1.1),作为响应数据包的源 IP。 +经过上述配置后,后端服务器当在本地回环接口(lo)上检测到目标 IP 为 VIP(配置的 1.1.1.1)的数据包时,将其识别为自己的地址并处理请求。处理完成后,后端服务器通过其外部接口(如 eth0)发送响应数据时,会保持原始请求中的目的 IP 地址,即 VIP(1.1.1.1),作为响应数据包的源 IP。 -在 DR 模式中,请求经过负载均衡器后,真实服务器的响应无需再通过负载均衡器原路返回。整个工作模式中,请求、转发和响应形成了一个“三角关系”,DR 模式也被形象地称为“三角传输模式”,如图 4-7 所示。 +直接路由模式中,请求经过负载均衡器后,后端服务器的响应无需通过负载均衡器原路返回。整个工作模式中,请求、转发和响应形成了一个“三角关系”,因此直接路由模式也被形象地称为“三角传输模式”,如图 4-7 所示。 :::center ![](../assets/balancer4-dsr.svg)
- 图 4-7 DR 的三角传输模式 + 图 4-7 直接路由模式的三角传输示例 ::: -DR 模式的主要优势在于它特别适合于响应流量远大于请求流量的场景。如典型的 HTTP 请求/响应模式,假设请求流量仅占 10%,响应流量占 90%。通过三角传输模式,负载均衡器只需处理 1/10 的总流量,这样不仅极大节省了带宽成本,还提高了负载均衡器的可靠性(流量越低越好)。 +直接路由模式的主要优势在于它特别适合于响应流量远大于请求流量的场景。如典型的 HTTP 请求/响应模式,假设请求流量仅占 10%,响应流量占 90%。通过三角传输模式,负载均衡器只需处理 1/10 的总流量,这样不仅极大节省了带宽成本,还提高了负载均衡器的可靠性(流量越低越好)。 -DR 模式的缺陷也非常明显:首先,由于响应流量直接返回给客户端,中间的负载均衡器无法监控完整的 TCP 连接状态,从而影响防火墙策略的应用(负载均衡器只能看到 TCP 连接的 SYN 包,而无法看到 ACK 包);其次,负载均衡器与真实服务器之间通过链路层通信,它们必须位于同一子网内,对网络架构有一定的要求。 +当然,直接路由模式缺陷也非常明显: +- 首先,由于响应流量直接返回给客户端,中间的负载均衡器就无法监控完整的 TCP 连接状态,影响防火墙策略(负载均衡器只能看到 TCP 连接的 SYN 包,而无法看到 ACK 包); +- 其次,负载均衡器与后端服务器之间通过链路层通信,它们必须位于同一子网内,对网络架构有一定的要求。 ## 4.4.2 隧道模式 -数据链路层负载均衡通过改写 MAC 地址实现数据包转发。到了网络层,我们也可以采用类似修改 IP 数据包的方式重定向数据包路由。LVS 的 Tunnel 和 NAT 模式都属于网络层负载均衡,它们的主要区别在于对 IP 数据包的处理方式。 +直接路由模式通过改写数据链路层的 MAC 地址实现请求转发。到了网络层,我们也可以采用类似的方式修改网络层的 IP 数据包,实现请求的转发。LVS 的 隧道(Tunnel)和网络地址转换(NAT)模式都属于网络层负载均衡,它们的主要区别在于对 IP 数据包的修改方式。 -在 Tunnel 模式中,LVS 会创建一个新的 IP 数据包,并将原始 IP 数据包整体放入新数据包的负载部分(Payload)中。随后,这个新数据包通过三层交换机发送出去。当真实服务器收到数据包时,通过相应的拆包机制去除负载均衡器自动添加的额外头部,从而解析出负载部分的原始 IP 数据包,并进行正常处理。 +隧道模式中,LVS 会创建一个新的 IP 数据包,并将原始 IP 数据包整体放入新数据包的负载部分(Payload)中。随后,这个新数据包通过三层交换机发送出去。当后端服务器收到数据包时,通过相应的拆包机制去除负载均衡器添加的额外头部,解析出原始 IP 数据包。 -上述的操作称之为”封包“,举一个具体例子供你参考。假设客户端(IP 203.0.113.5)向 VIP (1.1.1.1) 发送的数据包如下: +举一个具体例子,假设客户端(IP 203.0.113.5)向 VIP (1.1.1.1) 发送的数据包如下: ```go { Source IP: 203.0.113.5, @@ -60,7 +67,7 @@ DR 模式的缺陷也非常明显:首先,由于响应流量直接返回给 } ``` -负载均衡器接收到数据包后,根据调度算法选择出一台真实服务器(172.12.1.3),然后对数据包执行封装处理。 +负载均衡器接收到数据包后,根据调度算法选择出一台后端服务器(172.12.1.3),然后对数据包执行封装处理。 ```go { @@ -74,31 +81,33 @@ DR 模式的缺陷也非常明显:首先,由于响应流量直接返回给 } ``` -上述将一个 IP 数据包封装在另一个 IP 数据包内,并配合相应的解包机制,属于典型的 IP 隧道技术。Linux 中的 IPIP 隧道就是字面意思上的“IP in IP”。由于 IP 隧道工作在网络层,解除了直接路由模式的网络限制,因此 LVS Tunnel(隧道)模式可以跨越子网。 +上述将一个 IP 数据包封装在另一个 IP 数据包内,并配合相应的解包机制,属于典型的 IP 隧道技术。Linux 中的 IPIP 隧道就是字面意思上的“IP in IP”。由于隧道模式工作在网络层,解除了直接路由模式的网络限制,因此 LVS 隧道模式可以跨越子网。 -由于源数据包的所有信息均未被修改,IP 隧道模式依然保留了三角传输模式的特征(当然,仍需处理 lo 回环地址)。Tunnel 模式的请求到响应的整个过程如图 4-9 所示。 +由于源数据包的所有信息均未被修改,隧道模式依然保留了三角传输模式的特征(当然,仍需处理 lo 回环地址)。隧道模式的请求到响应的整个过程如图 4-9 所示。 :::center ![](../assets/balancer4-tunnel.svg)
-图 4-9 Tunnel 模式 +图 4-9 隧道模式的工作原理 ::: -Tunnel 模式相当于 DR 模式的升级(支持了跨网)。由于需要对数据包进行封装/解封,真实服务器必须支持特定的隧道技术(如 IPIP、GRE)。其次,**只要是三角模式(LVS 的 DR 模式或者 Tunnel 模式)必须保证真实服务器的 lo 接口与负载均衡服务器有相同的虚拟 IP 地址**。回复客户端的数据包,必须使用 VIP 作为数据包的源地址,这样客户端收到之后才能正常处理。 +隧道(Tunnel)模式相当于直接路由模式的升级(支持了跨网): +- 由于需要对数据包进行封装/解封,后端服务器必须支持某些隧道技术(如 IPIP、GRE); +- 其次,**只要是三角模式(LVS 的直接路由模式或者隧道模式)必须保证后端服务器的的 lo 接口与负载均衡服务器有相同的虚拟 IP 地址**。因为回复客户端的数据包,必须使用 VIP 作为数据包的源地址,这样客户端收到之后才能正常处理。 ## 4.4.3 网络地址转换模式 -另一种对 IP 数据包的修改方式是更改其头部中的目标地址,将其替换为真实服务器的地址。IP 数据包的目的地址修改后,将被三层交换机转发到真实服务器的网络接口上。 +另一种对 IP 数据包的修改方式是**直接修改原始 IP 数据包的目标地址,将其替换为后端服务器的地址**。 这段解释可能不够直观,但相信大多数读者都曾操作过类似的配置。如在家中设置路由器时,你希望外部设备可以访问家中某台运行服务器的电脑。假设家中的电脑 IP 是 192.168.1.100,并在端口 8080 上运行一个 Web 服务。你可以在路由器中设置端口转发(NAT),将外部访问路由器的 80 端口的请求转发到该电脑的 192.168.1.100:8080。这样,当外部设备通过路由器的公共 IP 访问 80 端口时,实际上就会连接到局域网内的服务器。 -**四层负载均衡器对 IP 数据包的改写与路由器中的“端口转发”原理相同**。因此,这种负载均衡方式被称为 NAT 模式,其请求和响应的流程如图 4-10 所示。 +**四层负载均衡器对 IP 数据包的改写与路由器中的“端口转发”原理相同**。因此,这种负载均衡方式被称为网络地址转换(NAT)模式,其请求和响应的流程如图 4-10 所示。 :::center ![](../assets/balancer4-NAT.svg)
-图 4-10 NAT 模式负载均衡 +图 4-10 网络地址转换(NAT)模式 ::: -举例一个具体的例子。假设客户端(203.0.113.5:37118)请求负载均衡器(1.1.1.1:80),四层负载均衡器根据调度算法挑选了某个后端服务器(10.0.0.2:8080)处理请求。 +举例一个具体的例子,假设客户端(203.0.113.5:37118)请求负载均衡器(1.1.1.1:80),四层负载均衡器根据调度算法挑选了某个后端服务器(10.0.0.2:8080)处理请求。 此时,四层负载均衡器处理请求和响应的逻辑如下: - 当客户端请求到达负载均衡器时,负载均衡器执行 NAT 操作: @@ -110,7 +119,7 @@ Tunnel 模式相当于 DR 模式的升级(支持了跨网)。由于需要对 最终,客户端请求/接收的都是负载均衡器的 IP 和端口,并不知道实际的后端服务器信息。 -从上述可见,NAT 模式下,负载均衡器代表整个服务集群接收和响应请求,当流量压力较大时,系统的瓶颈就很容易体现在负载均衡器上。 +从上述可见,网络地址转换模式下,负载均衡器代表整个服务集群接收和响应请求。因此,当流量压力较大时,系统的瓶颈就很容易体现在负载均衡器上。 ## 4.4.4 主备容错模式