1、为什么要用metallb

K8S裸机集群只能使用 NodePort 或者 externalIPs service 来对面暴露服务,然而这两种方式和 LoadBalancer service 相比都有很大的缺点。

NodePort 使用的端口范围是 30000-32767。当需要暴露的服务到达一定数量时,无法提供暴露。并且没有负债均衡的策略。端口也可能冲突

externalIPs 需要为每个服务分配外部 IP 地址。这在 IP 地址资源有限的情况下会成为一个瓶颈。并且没有负载均衡的策略

对于这些问题lb可以解决

2、metallb原理

MetalLB 有 Layer2 模式和Layer3 BGP 模式

不管是Layer2模式还是BGP模式,两者都不使用Linux的网络栈(这里指的是不直接使用,而是通过metallb的抽象层对linux网络栈进行操作,在metallb层面并看不出来使用了),也就是说我们没办法使用诸如ip命令之类的操作准确的查看VIP所在的节点和相应的路由,相对应的是在每个节点上面都能看到一个kube-ipvs0网卡接口上面的IP。同时,两种模式都只是负责把VIP的请求引到对应的节点上面,之后的请求怎么到达pod,按什么规则轮询等都是由kube-proxy实现的。

在 Kubernetes 集群中,kube-proxy是负责实现服务发现和负载均衡的重要组件。当使用IPVS模式的kube-proxy时,它会在节点上创建kube-ipvs0网卡作为虚拟服务器,用于接收和分发到达服务的流量。

IPVS 配置模块:MetalLB 抽象层创建了专门用于与 Linux 内核 IPVS 模块交互的模块。通过调用 Linux 系统的ipvsadm命令或直接使用libipvs库等方式,实现对 IPVS 规则的动态配置和管理。

虚拟网卡管理模块:为了在节点上实现网络流量的接收和转发,MetalLB 开发了虚拟网卡管理模块。这个模块利用 Linux 内核的网络设备管理接口,如netlink套接字等,在节点上创建和配置kube-ipvs0等虚拟网卡,设置其 IP 地址、MAC 地址等属性,并进行路由规则的配置。

所以即使K8S使用的不是ipvs模块,metallb也会创建ipvs0网卡

2.1 L2 L3优势劣势

2 层模式的主要优点是它的通用性:它可以在任何 以太网网络,不需要特殊硬件,甚至不需要花哨的路由器。

L2模式,只需要一段跟K8s管理网相同网段的地址即可。

Metallb在这种模式下,会从k8s节点中选一个Leader节点,在这个节点上面响应LB地址段的ARP请求,从而使上层路由把发往LB的流量都发到Leader节点。

缺点也很明显,所有对LB的请求都会发往Leader节点。如果当前Service下面的Pod分布在不同节点,那么这个流量还会从Leader发往相应的节点。

L3模式

优点:bgp的优点

缺点就是需要上层路由器支持BGP。配置复杂。

因为BGP单session的限制,如果Calico也是使用的BGP模式,就会有冲突从而导致metallb无法正常工作。解决BGP 模式下 Calico 与 MetalLB 如何结合-腾讯云开发者社区-腾讯云

ECMP的故障转移(failover)并不是特别地优雅,这个问题的严重程度取决于使用的ECMP算法;当集群的节点出现变动导致BGP连接出现变动,所有的连接都会进行重新哈希(使用三元组或五元组哈希),这对一些服务来说可能会有影响;

k8s系列06-负载均衡器之MatelLB - 简书

2.2 网络变化

由于L3模式的BGP要依赖于frr,所以需要安装quagga,

Quagga提供了一个叫做vtysh特有的命令行工具,用于配置网络方面的

Zebra:一个核心守护进程用于内核接口和静态路由. 打开端口2601

BGPd:一个BGP守护进程. 打开端口2605

启动bgp 打开端口179

抽象层的存在:MetalLB 在使用 Linux 网络栈时,并不是直接让用户通过传统的ip命令等方式去操作和查看网络配置。它在 Linux 网络栈之上构建了自己的抽象层,对用户隐藏了底层的复杂细节。例如,在 MetalLB 中,VIP(虚拟 IP)的管理和分配是由 MetalLB 自身的组件(controller)和逻辑来完成的,用户不需要手动使用ip addr add等命令去配置 VIP。

隐藏底层复杂性

网络配置细节:Linux 网络栈的原生配置方式较为复杂,涉及众多命令和参数。例如,手动配置 IP 地址、路由规则、虚拟 IP 等需要熟悉ip命令、route命令以及相关的网络配置文件等。MetalLB 的抽象层将这些复杂的配置过程封装起来,用户无需直接操作这些底层命令和文件来配置 MetalLB 相关的网络资源。

内核模块交互:与 Linux 内核中的各种网络相关模块如 IPVS、Netfilter 等的交互也被抽象层隐藏。这些内核模块的工作原理和调用方式对于普通用户和开发者来说较为晦涩难懂。MetalLB 的抽象层在内部完成与这些内核模块的交互和协调工作,使得用户无需深入了解内核模块的具体细节就能使用 MetalLB 实现负载均衡和服务暴露等功能。

实现动态管理

自动 IP 分配与管理:抽象层实现了 VIP 的自动分配和动态管理。在 MetalLB 中,用户只需定义 IP 地址池,MetalLB 会根据服务的需求自动从地址池中分配 VIP,并在服务发生变化或节点状态改变时自动调整 VIP 的分配和绑定。这与传统的手动使用 Linux 网络栈配置 IP 地址相比,大大简化了 IP 管理的复杂性,且避免了因手动配置错误导致的网络问题。

流量动态调度:根据集群中服务和节点的实时状态,MetalLB 的抽象层能够动态调整流量的调度策略。例如,当某个节点的负载过高或出现故障时,抽象层可以自动将流量从该节点转移到其他健康的节点,而无需用户手动干预。这种动态调度能力是通过在抽象层中实时监控集群状态并根据预设的策略进行调整实现的。

由于metallb抽象层的原因,所以我们不需要操作linux网络协议栈,只需要给metallb的抽象层相对应的参数,抽象层会通过自己的封装,完成交互。

metallb 配置bgp后,会把bgp路由所拥有的负载通过ipvs的方式提供给linux路由表,Linux 路由表会新增与 MetalLB 配置相关的 VIP 路由条目,还会因为 BGP 学习到外部网络路由信息而增加对应路由,Linux 路由表会出现用于 BGP 下一跳转发等特殊用途的路由

3、metallb架构

Controller 组件

核心职责 - 资源管理与分配

MetalLB 的 Controller 负责管理整个负载均衡系统中的资源分配。它主要针对 IP 地址池进行管理,从用户配置的IPAddressPool资源中挑选合适的虚拟 IP(VIP)并分配给新创建的LoadBalancer类型的 Kubernetes 服务。例如,当一个开发人员在集群中部署了一个需要外部访问的微服务,并将服务类型设置为LoadBalancer时,Controller 会根据预先定义的 IP 地址范围(如192.168.1.10 - 192.168.1.20),从中选择一个未被使用的 VIP(假设为192.168.1.12)分配给这个服务。

同时,Controller 还会维护 VIP 与服务之间的映射关系,记录哪些 VIP 分配给了哪些服务,以便后续进行流量调度和管理。

决策与调度功能

Controller 会根据集群中各个节点的状态信息来做出决策。它会考虑节点的资源可用性(如 CPU、内存、网络带宽等)、节点的负载情况(当前正在处理的流量负载)以及网络拓扑等因素,选择合适的节点来承载 VIP 的流量。例如,在一个具有多个节点的集群中,如果某个节点的网络带宽利用率较低,Controller 可能会优先将新的 VIP 流量调度到该节点。

与 Kubernetes API Server 交互

这是 Controller 的关键功能之一。它持续监控 Kubernetes API Server 上的资源变化,重点关注LoadBalancer类型服务的创建、更新和删除事件。当有新的LoadBalancer服务创建时,Controller 会及时获取服务的详细信息,如服务的端口、后端 Pod 的选择器等,然后进行 VIP 分配和相关的配置操作。同样,当服务被更新或删除时,Controller 也会相应地更新或释放 VIP 资源。

实现高可用的策略 - Leader Election

在多 Controller 副本部署的情况下,Controller 通过 Kubernetes 的 Leader Election 机制来选举一个 leader。多个 Controller 副本会竞争获取一个资源锁(如 ConfigMap 或 Lease),只有成功获取资源锁的副本成为 leader,拥有完整的控制权和决策权。领导者 Controller 会定期发送心跳信号和进行续租操作来维持其领导地位,一旦出现故障,其他副本会重新竞争成为新的 leader,确保系统的高可用性。

Speaker 组件

节点本地操作执行

Speaker 以 DaemonSet 的形式部署在 Kubernetes 集群的每个节点上,其主要职责是在本地节点执行网络相关的操作。在 Layer2 模式下,Speaker 会发送 ARP(Address Resolution Protocol)或 NDP(Neighbor Discovery Protocol)广播,宣告 VIP 的 MAC 地址。例如,当 Controller 分配了一个 VIP(如192.168.1.12)给某个服务后,Speaker 会在本地节点广播这个 VIP 对应的 MAC 地址,使得外部网络设备能够通过这个 MAC 地址将流量发送到集群内的相应节点。

在 BGP 模式下,Speaker 会与外部的 BGP 路由器建立连接,将 VIP 的路由信息通告出去。这使得外部网络能够正确地将流量路由到集群内拥有 VIP 的节点。例如,Speaker 会与数据中心的 BGP 路由器交换路由信息,告知路由器如何将特定 VIP 的流量转发到集群内部。

配置传播与同步

Speaker 负责将 Controller 分配的 VIP 及相关负载均衡配置信息传播到所在节点。它会与节点上的网络组件(如 kube - proxy 等)进行交互,确保每个节点都能正确地配置路由和 IPVS(IP Virtual Server)规则。这样,当外部流量到达节点时,能够根据这些配置正确地导向后端的服务 Pod。例如,Speaker 会将 VIP 与后端 Pod 的映射关系以及负载均衡策略(如轮询、加权轮询等)传递给节点上的 IPVS 模块,使 IPVS 能够按照策略将流量转发到正确的 Pod。

节点状态反馈

Speaker 实时收集所在节点的网络状态和负载信息,并将这些信息反馈给 Controller。这些信息包括节点的网络连接情况、流量负载情况等。Controller 根据这些反馈信息可以动态调整负载均衡策略。例如,如果 Speaker 反馈某个节点的网络流量出现拥塞,Controller 可以调整流量分配,将新的流量导向负载较低的节点,以优化整个集群的负载均衡效果。

4、安装metallb

MetalLB的早期版本采用 configmap 配置,但是从版本 v0.13.0 开始,只能通过 CRs 进行配置。在 quay.io/metallb/configmaptocrs 提供了一个将旧有的 configmap 转换到 CRs 的工具镜像。

MetalLB 有 Layer2 模式和Layer3 BGP 模式

在安装MetalLB之前,需要检查:

Kubernetes 1.13.0 或更高版本,并且还没有部署网络负载均衡功能

Kubernetes网络插件MetalLB兼容性列表

保留部分IPv4地址给MetalLB处理

当使用BGP操作模式,需要有一些能够处理BGP通讯的路由器

当使用L2操作模式(两层交换机模式),Kubernetes节点必须允许端口 7946 流量(TCP和UDP,也可以配置其他端口)

apiVersion: metallb.io/v1beta1

kind: IPAddressPool

metadata:

name: ippool

namespace: metallb-system

spec:

addresses:

  • 192.168.10.240-192.168.10.250 #为宿主机地址

kubectl apply -f ippool.yaml

注意:我们可以看出 MetalLB 的二层模式是非常简单的(另一种 BGP 模式需要路由器支持),只要保证 IP 地址池与集群是同一个网段即可。

MetalLB 响应 ARP 请求 IPv4 服务和 NDP 请求 IPv6 的。

第 2 层模式的主要优点是它的通用性:它可以在任何 以太网网络,不需要特殊硬件,甚至不需要花哨的路由器。

L2模式,只需要一段跟K8s管理网相同网段的地址即可。

Metallb在这种模式下,会从k8s节点中选一个Leader节点,在这个节点上面响应LB地址段的ARP请求,从而使上层路由把发往LB的流量都发到Leader节点。

缺点也很明显,所有对LB的请求都会发往Leader节点。如果当前Service下面的Pod分布在不同节点,那么这个流量还会从Leader发往相应的节点。

如果使用 IPVS 模式的 kube-proxy ,从 Kubernetes v1.14.2 开始,必须激活严格的 ARP 模式。注意,如果使用 kube-router 作为 service-proxy 则不需要这个步骤,因为已经默认激活了 strict ARP

通过编辑当前集群的 kube-proxy 配置实现:

通过编辑 kube-proxy 配置激活 strict ARP:kubectl edit configmap -n kube-system kube-proxy

创建 L2Advertisement,并关联 IPAdressPool

cat <<EOF > L2Advertisement.yaml apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: example namespace: metallb-system spec: ipAddressPools: - first-pool #上一步创建的 ip 地址池,通过名字进行关联 EOF kubectl apply -f L2Advertisement.yaml

apiVersion: metallb.io/v1beta1

kind: L2Advertisement

metadata:

name: example

namespace: metallb-system

使用Manifest方式安装MetalLB

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml

FRR模式

MetalLB 实现了 FRR 模式,该模式使用 FRR 容器作为处理 BGP 会话的后端。 它提供了本机 BGP 实现所不具备的功能,例如将 BGP 会话与 BFD 会话配对,以及公布 IPV6 地址。

尽管与本机 BGP 实施相比,FRR 模式的实战测试较少,但 FRR 模式目前被那些需要 BFD 或 IPV6 的用户使用,并且它是随 OpenShift 分发的 MetalLB 版本中唯一受支持的方法。 长期计划是使其成为 MetalLB 中唯一可用的 BGP 实现。

需要路由器支持接收Metallb的BGP广播,从而把请求分布到正确的节点上。

缺点就是需要上层路由器支持BGP。而且因为BGP单session的限制,如果Calico也是使用的BGP模式,就会有冲突从而导致metallb无法正常工作。

更多推荐