• 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-pool
      namespace: 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: l2adver
      namespace: 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: sample
      namespace: metallb-system
    spec:
      myASN: 64500
      peerASN: 64501
      peerAddress: 10.0.0.1
    

    配置IP地址池

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

    创建广播声明

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

    功能验证

    本实例使用Layer2配置来测试

    vim myapp.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: myapp-svc
    spec:
      selector:
        app: myapp
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
      type: LoadBalancer
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp-deployment
      labels:
        app: myapp
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: myapp
      template:
        metadata:
          labels:
            app: myapp
        spec:
          containers:
          - name: nginx
            image: nginx:1.19.4
            ports:
            - 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/

  • 相关阅读:
    唐老师讲电赛
    【RTOS训练营】设备子系统、晚课学员提问
    自制肥鲨HDO2电源延长线,支持3S~6S动力电池
    大学生网页制作期末作业——html+css+javascript+jquery旅游官网6页 html大学生网站开发实践作业 web网页设计实例作业
    ❤️新版Linux零基础快速入门到精通——第一部分❤️
    数据绑定之数据类型转换
    深度学习项目:男女性别识别【附完整源码】
    六、软考-系统架构设计师笔记-软件工程基础知识
    leetcode 416. Partition Equal Subset Sum 分割等和子集(中等)
    Anaconda如何创建一个环境
  • 原文地址:https://blog.csdn.net/wuxingge/article/details/139430747