当前位置: 首页 > news >正文

kubernetes负载均衡---MetalLB

https://github.com/metallb/metallb

参考 : https://mp.weixin.qq.com/s/MBOWfcTjFMmgJFWw-FIk0Q

自建的Kubernetes集群,默认情况下是不支持负载均衡的。当需要提供服务的外部访问时,可使用 Ingress、NodePort等方式。他们都存在一些问题 ,如Ingress不支持TCP协议,而NodePort则是使用随机端口
MetalLB 提供基于网络设备的负载均衡功能来解决这些问题

部署要求

MetalLB部署需要以下环境才能运行:

运行Kubernetes 1.13.0或更高版本的群集,尚不具有网络负载平衡功能;
一些用于MetalLB分配的IPv4地址;
如果使用BGP模式,需要准备一台或多台支持BGP的路由器;
如果使用layer 2模式时,集群节点间必须允许7946端口的访问 ,用户代理之间的通信;

集群的网络类型需要支持MetalLB,详见下表

网络类型兼容性
AntreaYes
CalicoMostly
CanalYes
CiliumYes
FlannelYes
Kube-ovnYes
Kube-routerMostly
Weave NetMostly

工作原理

Metallb包含两个组件,Controller和Speaker,Controller为Deployment部署方式,而Speaker则采用Daemonset方式部署到集群内部各个Node节点。

具体的工作原理如下图所示,Controller负责监听Service变化,当Service配置为LoadBalancer模式时,从IP池分配给到相应的IP地址并对该IP的生命周期进行管理。Speaker则会依据选择的协议进行相应的广播或应答,实现IP地址的通信响应。当业务流量通过TCP/UDP协议到达指定的Node时,由Node上面运行的Kube-Proxy组件对流量进行处理,并分发到对应服务的Pod上面。

在这里插入图片描述

MetalLB支持两种模式,一种是Layer2模式,一种是BGP模式

Layer2模式

在2层模式下,Metallb会在Node节点中选出一台作为Leader,与服务IP相关的所有流量都会流向该节点。在该节点上, kube-proxy将接收到的流量传播到对应服务的Pod。当leader节点出现故障时,会由另一个节点接管。从这个角度来看,2层模式更像是高可用,而不是负载均衡,因为同时只能在一个节点负责接收数据

在二层模式中会存在以下两种局限性:单节点瓶颈和故障转移慢的情况

由于Layer 2 模式会使用单个选举出来的Leader来接收服务IP的所有流量,这就意味着服务的入口带宽被限制为单个节点的带宽,单节点的流量处理能力将成为整个集群的接收外部流量的瓶颈。

在故障转移方面,目前的机制是MetalLB通过发送2层数据包来通知各个节点,并重新选举Leader,这通常能在几秒内完成。但如果是计划外的事故导致的,此时在有故障的客户端刷新其缓存条目之前,将无法访问服务IP

BGP模式

BGP模式是真正的负载均衡,该模式需要路由器支持BGP协议 ,群集中的每个节点会与网络路由器建议基于BGP的对等会话,并使用该会话来通告负载均衡的IP。MetalLB发布的路由彼此等效,这意味着路由器将使用所有的目标节点,并在它们之间进行负载平衡。数据包到达节点后,kube-proxy负责流量路由的最后一跳,将数据包发送到对应服务的Pod。

负载平衡的方式取决于您特定的路由器型号和配置,常见的有基于数据包哈希对每个连接进行均衡,这意味着单个TCP或UDP会话的所有数据包都将定向到群集中的单个计算机。

BGP模式也存在着自身的局限性,该模式通过对数据包头中的某些字段进行哈希处理,并将该哈希值用作后端数组的索引,将给定的数据包分配给特定的下一跳。但路由器中使用的哈希通常不稳定,因此只要后端节点数量发生变化时,现有连接就会被随机地重新哈希,这意味着大多数现有连接将被转发到另一后端,而该后端并不清楚原有的连接状态。为了减少这种麻烦,建议使用更加稳定的BGP算法,如:ECMP散列算法。

安装

k8s版本:我这里是k8s1.29.3
Metallb版本:v0.13.4

启用kube-proxy的ARP模式

如果集群是使用IPVS模式下kube-proxy,则从kubernetes v.1.14.2开始,必须启用ARP模式。

修改kube-proxy配置文件
kubectl edit configmap -n kube-system kube-proxy

...
#设置strictARP值为true
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:strictARP: true

重启kube-proxy

kubectl -n kube-system rollout restart daemonset kube-proxy

安装MetalLB相关组件

下载部署yaml文件

wget https://raw.githubusercontent.com/metallb/metallb/v0.13.4/config/manifests/metallb-native.yaml

下载镜像

docker pull quay.io/metallb/controller:v0.13.4
docker pull quay.io/metallb/speaker:v0.13.4

打tag为自己的镜像

registry.cn-beijing.aliyuncs.com/wuxingge123/metallb-controller:v0.13.4
registry.cn-beijing.aliyuncs.com/wuxingge123/metallb-speaker:v0.13.4

配置模式

Layer2模式配置

创建IPAddressPool,并指定用于分配的IP池。

vim IPAddressPool.yaml

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: ip-poolnamespace: metallb-system
spec:addresses:- 10.0.0.101-10.0.0.150

创建广播声明,此处未指定IP池,则默认会使用所有IP池地址

vim L2Advertisement.yaml

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:name: l2advernamespace: metallb-system

BGP模式配置

对于具有一个BGP路由器和一个IP地址范围的基本配置,您需要4条信息:

MetalLB应该连接的路由器IP地址,
路由器的AS号,
MetalLB应该使用的AS号,
以CIDR前缀表示的IP地址范围。

示例:现在分配给MetalLB的AS编号为64500和192.168.10.0/24的IP地址池,并将其连接到AS编号为64501的地址为10.0.0.1的路由器,则配置如下所示

创建BGPPeer

apiVersion: metallb.io/v1beta2
kind: BGPPeer
metadata:name: samplenamespace: metallb-system
spec:myASN: 64500peerASN: 64501peerAddress: 10.0.0.1

配置IP地址池

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: first-poolnamespace: metallb-system
spec:addresses:- 192.168.10.0/24

创建广播声明

apiVersion: metallb.io/v1beta1
kind: BGPAdvertisement
metadata:name: bgpadvernamespace: metallb-system

功能验证

本实例使用Layer2配置来测试

vim myapp.yaml

apiVersion: v1
kind: Service
metadata:name: myapp-svc
spec:selector:app: myappports:- protocol: TCPport: 80targetPort: 80type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp-deploymentlabels:app: myapp
spec:replicas: 2selector:matchLabels:app: myapptemplate:metadata:labels:app: myappspec:containers:- name: nginximage: nginx:1.19.4ports:- containerPort: 80

查看创建的SVC状态,已获取到IP

kubectl get service
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP      10.96.0.1        <none>        443/TCP        66d
myapp-svc    LoadBalancer   10.110.204.123   10.0.0.101    80:32339/TCP   38m

访问
http://10.0.0.101/

相关文章:

  • STM32项目分享:智能家居语音系统
  • python基于flask写后端接口、python接收请求、python作为服务端提供接口、python接收json数据或数组
  • JVM学习-JVM运行时参数
  • 24.6.2(动态开点线段树)
  • 股票数据集1-纳斯达克NASDAQ 100简介
  • 【java11】java11新特性之嵌套类
  • 打造无障碍网络体验:Edge 浏览器代理服务器设置指南
  • 【Unity实战篇 】 | Unity实现UGUI颜色渐变,支持透明渐变
  • 星舰第四次发射:历史性的一步
  • 入坑必看的几个嵌入式方向热点问题
  • Memory测试工具-stressapptest详解
  • 国内科技企业和机构发力AI研发,50余篇论文入选顶会ICML2024
  • 计数排序(排序终篇)
  • 人工智能在肿瘤预后预测中的最新研究进展|顶刊精析·24-06-07
  • 单节点离线部署TiDB 6.1用于测试
  • 5、React组件事件详解
  • Apache的80端口被占用以及访问时报错403
  • gf框架之分页模块(五) - 自定义分页
  • IDEA常用插件整理
  • JAVA SE 6 GC调优笔记
  • Javascript弹出层-初探
  • JavaWeb(学习笔记二)
  • mongo索引构建
  • vue的全局变量和全局拦截请求器
  • Webpack 4 学习01(基础配置)
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 一些关于Rust在2019年的思考
  • 因为阿里,他们成了“杭漂”
  • 正则表达式
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • # linux 中使用 visudo 命令,怎么保存退出?
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #pragam once 和 #ifndef 预编译头
  • #图像处理
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (附源码)计算机毕业设计ssm电影分享网站
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (转) ns2/nam与nam实现相关的文件
  • .NET Core Web APi类库如何内嵌运行?
  • .Net Web项目创建比较不错的参考文章
  • .NET/C# 利用 Walterlv.WeakEvents 高性能地中转一个自定义的弱事件(可让任意 CLR 事件成为弱事件)
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .php结尾的域名,【php】php正则截取url中域名后的内容
  • /etc/shadow字段详解
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • @data注解_SpringBoot 使用WebSocket打造在线聊天室(基于注解)