type
status
date
slug
summary
tags
category
icon
password
MetalLB部署
什么是 MetalLB
Repo:https://github.com/metallb/metallb
MetalLB 是一个用于裸机 Kubernetes 集群的负载均衡器实现,使用标准路由协议。k8s 并没有为裸机集群实现负载均衡器,因此我们只有在以下
IaaS 平台(AliCloud, AWS, Azure)上才能使用 LoadBalancer 类型的 service因此裸机集群只能使用
NodePort 或者 externalIPs service 来对面暴露服务,然而这两种方式和 LoadBalancer service 相比都有很大的缺点而 MetalLB 的出现就是为了解决这个问题
必要条件
MetalLB 要求如下:
- 一个 Kubernetes 集群, Kubernetes 版本 1.13.0+, 没有网络负载均衡器功能;
- 可以与 MetalLB 共存的集群网络配置;
- 一些供 MetalLB 分发的 IPv4 地址;
- 当使用 BGP 操作模式时,您将需要一台或多台能够发布 BGP 的路由器;
- 使用 L2 操作模式时,节点之间必须允许 7946 端口(
TCP和UDP,可配置其他端口)上的流量,这是 hashicorp/memberlist 的要求。
主要架构实现
在公有云的 Kubernetes 集群中, 你申请一个负载均衡器, 云平台会给你分配一个 IP 地址. 在裸金属集群中, MetalLB 来做地址分配.MetalLB 不能凭空造 IP, 所以你需要提供供它使用的 IP 地址池. 在 Service 的创建和删除过程中, MetalLB 会对 Service 分配和回收 IP, 这些都是你配置的地址池中的 IP.
如何获取 MetalLB 的 IP 地址池取决于您的环境。如果您在托管设施中运行裸机集群,您的托管服务提供商可能会提供 IP 地址供出租。在这种情况下,将租用例如 /26 的 IP 空间(64 个地址),并将该范围提供给
MetalLB 以用于集群服务。
工作模式
MetalLB 是裸机 Kubernetes 集群的负载均衡器实现,使用标准路由协议,主要用于暴露 K8s 集群的服务到集群外部访问,
MetalLB 可以让我们在 K8s 集群中创建服务类型为 LoadBalancer 的服务,并且无需依赖云厂商提供的LoadBalancer。它具有两个共同提供此服务的工作负载:
地址分配(address allocation)和外部公告(external announcement),对应在 K8s 中部署的 controller 和 speaker。- *address allocation:**地址分配这个功能比较好理解,首先我们需要给 MetalLB 分配一个 IP 段,接着它会根据K8s 的 Service 中的相关配置来给 LoadBalancer 的服务分配 IP,LoadBalancer 的 IP 可以手动指定,也可以让 MetalLB 自动分配。地址分配主要就是由作为 Deployment 部署的 controller 来实现,它负责监听集群中的 Service 状态并且分配 IP。
- *external announcement:**外部公告的主要功能就是要把服务类型为 LoadBalancer 的服务的 EXTERNAL-IP 公布到网络中去,确保客户端能够正常访问到这个 IP。MetalLB 对此的实现方式主要有三种:ARP/NDP 和 BGP,其中ARP/NDP 分别对应 IPv4/IPv6 协议的 Layer2 模式,BGP 路由协议则是对应 BGP 模式。外部公告主要通过由 DaemonSet 部署的 speaker 来实现,它负责在网络中发布 ARP/NDP 报文或者是和 BGP 路由器建立连接并发布BGP 报文。
不管是 Layer2 模式还是 BGP 模式,两者都不使用 Linux 的网络栈,也就是说我们没办法使用诸如 ip 命令之类的操作准确的查看 VIP 所在的节点和相应的路由,相对应的是在每个节点上面都能看到一个
kube-ipvs0 网卡接口上面的IP。同时,两种模式都只是负责把 VIP 的请求引到对应的节点上面,之后的请求怎么到达 pod,按什么规则轮询等都是由kube-proxy 实现的。Layer 2 中的 Speaker 工作负载是 DaemonSet 类型,在每台节点上都调度一个 Pod。首先,几个 Pod 会先进行选举,选举出 Leader,Leader 获取所有 LoadBalancer 类型的 Service,将已分配的 IP 地址绑定到当前主机的网卡上。也就是说,所有 LoadBalancer 类型的 Service 的 IP 同一时间都是绑定在同一台节点的网卡上。
部署验证
部署 Layer2 模式需要把 K8s 集群中的 ipvs 配置打开 strictARP,开启之后 K8s 集群中的 kube-proxy 会停止响应 kube-ipvs0 网卡之外的其他网卡的 arp 请求,而由 MetalLB 接手处理。我们只需要在 K8s 集群中编辑kube-proxy 配置即可:
使用 Layer2 模式,直接使用下面的命令一键安装即可部署验证到这里就部署成功了。对于 2 层模式的配置使用是最简单的,因为不需要什么特定的协议配置,只需要 IP 地址即可。L2模式不需要将 IP 与你的工作节点的网络接口绑定,它的工作方式是直接响应你本地网络上的 ARP 请求,把机器的 MAC地址给客户端
配置管理
要 Layer2 模式进行配置,需要创建一个 IPAddressPool 资源对象,用来指定用于分配的 IP 池,这部分一定要在 DHCP 服务器上做 IP 资源的保留,以防止IP被再次分配,造成异常
vim ip-pool.yaml[!CAUTION]注意:我们可以看出 MetalLB 的二层模式是非常简单的(另一种 BGP 模式需要路由器支持),只要保证 IP 地址池与集群是同一个网段即可。
然后需要创建一个广播声明,可以关联上面的 IP 池对象,这样会使用关联的 IP 池地址。为了通告来自 IPAddressPool 的 IP,L2Advertisement 实例必须关联到 IPAddressPool
vim advertise.yaml直接创建上面的两个资源对象验证测试
vim nginx-demo.yaml总结
我们可以看出 MetalLB 的二层模式是非常简单的(另一种 BGP 模式需要路由器支持),只要保证 IP 地址池与集群是同一个网段即可。当然缺点也很明显:
- 所有的流量都会在同一个节点上,该节点的容易成为流量的瓶颈,当 VIP 所在节点宕机之后,需要较长时间进行故障转移(一般在 10s),这主要是因为 MetalLB 使用了memberlist 来进行选主;
- 当 VIP 所在节点宕机之后重新选主的时间要比传统的 keepalived 使用的
vrrp 协议要更长,难以定位 VIP 所在节点;
- MetalLB 并没有提供一个简单直观的方式让我们查看到底哪一个节点是 VIP 所属节点,基本只能通过抓包或者查看 pod 日志来确定,当集群规模变大的时候这会变得非常的麻烦;
- 所以有条件的可以考虑使用 BGP 模式。
- 作者:NotionNext
- 链接:https://tangly1024.com/article/f093520f-f6cb-4811-bb01-3fe2178e3e4f
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。





