metallb 一致性实现和故障切换

问题的引出

事情是这样的项目上有个客户提到,我们容器平台提供的load balancer service是由metallb l2 mode去实现的,客户那边使用vip都来自于同一个ippool,后来发现vip老是飘到同一个节点上,导致这个节点的负载很高。之前我以为metallb的vip是随机飘到后端节点,直到这个问题出现,才去研究了下metallb的一致性和故障切换。

metallb l2 mode

metallb 的l2 mode实现原理很简单,由speaker发起arp声明vip对应的某个节点的mac。那么刚才的那个问题很明显就是vip所对应的mac,全固定到某个节点上了,所以流量全都经过这个节点,那么metallb是怎么去选vip对应的节点的呢?

metallb一致性实现memberlist

metallb的speaker部署在每个节点上,那么他们之间肯定会有一个协商,协商出当前memberlist集群中的节点成员,这个一致性的实现,就是通过memberlist这个库,github.com/hashicorp/m... ,这个库是参考一致性协议gossip去实现的。gossip和raft的目的一样,都是为了实现分布式数据的一致性,但是gossip比raft理解和实现起来简单很多(但我感觉问题也挺多的,gossip协议内容后面再说),总之先知道 metallb 调用了一个三方库 memberlist 去实现一致性。

memberlist 部分源码

看了下 metallb 调用 memberlist 部分的源码也比较简单,基本就是在 create 初始化 和 join 两步实现。

初始化 create

每个speaker在初始化的时候会 create memberlist,会创建一个NodeEvent的channel,那么一旦 memberlist 中有节点退出或者加入,就会通知到 memberlist

还有点注意的是mconfig,这里包含了 memberlist 协议的配置参数。

join 加入memberlist

调用了sl.ml.Join(joinIPs),其中joinIPs,就是所有 metallb speaker 的Pod IP

决定哪个speaker声明的源码

每当新的节点加入和退出,就会触发到 ServiceHandler 里面的 c.SetBalancer 重新去设定 vip 后端的节点。这个SetBalancer最终会调用到 ShouldAnnounce 这个函数上来,这个就是决定哪个speaker去声明arp,最关键是这一步,metallb speaker把memberlist中的成员重新排序,然后取第一个节点去声明arp.

但我想了下,不借助其他组件,确实没啥好办法让metallb的speaker共同协商出一个类似leader的角色来发arp声明,如果metallb 的一致性协议使用的是 raft 就不会有这种问题,raft 协议本身会有leader,选取leader作为声明arp的node即可。

这个问题workaround

我觉得最好的方法如果集群比较大lb service需求比较多的情况下,选型的时候别用metallb l2模式,本身该模式就不支持负载均衡只是个高可用。

如果已经部署了的话,可以申请多个ippool, 每个ippool绑定节点不一样,那vip也不会都飘到同一个节点上。

相关推荐
brzhang11 分钟前
别再梭哈 Curosr 了!这 AI 神器直接把需求、架构、任务一条龙全干了!
前端·后端·架构
安妮的心动录26 分钟前
安妮的2025 Q2 Review
后端·程序员
程序员爱钓鱼26 分钟前
Go语言数组排序(冒泡排序法)—— 用最直观的方式掌握排序算法
后端·google·go
Victor3561 小时前
MySQL(140)如何解决外键约束冲突?
后端
Victor3561 小时前
MySQL(139)如何处理MySQL字符编码问题?
后端
007php0073 小时前
服务器上PHP环境安装与更新版本和扩展(安装PHP、Nginx、Redis、Swoole和OPcache)
运维·服务器·后端·nginx·golang·测试用例·php
武子康5 小时前
Java-72 深入浅出 RPC Dubbo 上手 生产者模块详解
java·spring boot·分布式·后端·rpc·dubbo·nio
椰椰椰耶7 小时前
【Spring】拦截器详解
java·后端·spring
brzhang8 小时前
我操,终于有人把 AI 大佬们 PUA 程序员的套路给讲明白了!
前端·后端·架构