地址分配
在云环境中,创建 Service.type=LoadBalancer 类型,云商将负责创建负载均衡。在自建集群中,我们可以通过 MetalLB 来实现.
预先定义地址池,然后 MetalLB 将从该地址池中选择地址进行分配;
地址池范围取决于环境:既可以使用运营商分配的公网地址,也可以在内网中使用私有地址,或同时使用;
地址通告
当通过 MetalLB 分配地址后,需要让网络感知到该地址的存在;
ARP for IPv4 | NDP for IPv6
在该模式(二层模式)中,Service 的地址被分配到某台主机,然后使用标准的地址发现协议,使其能否被访问。站在网络的角度,简单说,就是通告地址的主机具有多个地址;
ARP for IPv4, NDP for IPv6
主要的特性特征:
部署简单,具有普适性(适合多数环境),无针对网络硬件的特殊要求(相对于 BGP 模式);
针对某个服务,所有的流量都被发往某个节点,然后被 kube-proxy 进行负载均衡;
并未实现真正的负载均衡,但是依旧实现故障切换(节点故障,地址将被重新分配到其他节点);
主要的两个缺点:
1)单节点的带宽瓶颈:鉴于所有流量都转发到同一个节点;
2)故障转义时间较长:ARP/NDP 的工作模式,使得转移需要时间;
官方将其与 keepalived 的对比,但这并非我们关注的内容,所以这里不再深入了解相关内容;
BGP mode
在 BGP mode 中,MetalLB 与 Router 建立会话,并就行地址路由通告。通过 BGP 模式,能够实现跨节点的负载均衡,并能否借助 BGP 选路策略实现更精细的路由控制;
借助 BGP 模式,对路由进行通告,除了下一跳不同,所有路由互为等价路由,即每个节点都能接收流量,最后通过 kube-proxy 转发到对应的 Pod 实例;
其基于 packet hash 进行每连接的负载均衡:同个 TCP/UDP 连接,将被转发到同个节点;不同 TCP/UDP 连接,将负载均衡到不同节点;
—- 避免数据包的重新排序问题,保证性能;
—- 保证报文被转发到同个 Pod 实例(将同个连接的流量散布到不同的节点,每个节点将负载均衡到不同的 Pod 示例,将导致连接重置)
针对 packet hash 算法,具体取决于路由器的实现,3-tuple,5-tuple,参与哈希的元组越多,负载均衡的模型的结果越接近理想值;
针对 BGP 模式的缺点:
1)后端节点下线,出现连接被重置的现象(因为重新哈希而导致流量转发到新的 Pod(其未建立 TCP 连接);
2)同样,当增加节点时,也会导致连接出现连接重置(同样是因为流量可以被转发到未建立连接的 Pod 实例);
3)官方针对这些问题提供缓解方案,但是在我们的场景中不会频繁的出现类似变更,所以日后有需要在深入研究;