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也不会都飘到同一个节点上。

相关推荐
我叫黑大帅29 分钟前
Go 语言并发编程的 “工具箱”
后端·面试·go
用户8356290780511 小时前
Python 实现 PowerPoint 形状动画设置
后端·python
用户908324602731 小时前
Spring Boot 缓存架构:一行配置切换 Caffeine 与 Redis,透明支持多租户隔离
后端
tyung2 小时前
zhenyi-base 开源 | Go 高性能基础库:TCP 77万 QPS,无锁队列 16ns/op
后端·go
子兮曰2 小时前
Humanizer-zh 实战:把 AI 初稿改成“能发布”的技术文章
前端·javascript·后端
桦说编程2 小时前
你的函数什么颜色?—— 深入理解异步编程的本质问题(上)
后端·性能优化·编程语言
百度地图汽车版2 小时前
【AI地图 Tech说】第九期:让智能体拥有记忆——打造千人千面的小度想想
前端·后端
臣妾没空3 小时前
Elpis 全栈框架:从构建到发布的完整实践总结
前端·后端
喷火龙8号3 小时前
单 Token 认证方案的进阶优化:透明刷新机制
后端·架构
孟沐3 小时前
Java异常处理知识点整理(大白话版)
后端