侧边栏壁纸
  • 累计撰写 6 篇文章
  • 累计创建 4 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Metallb

uuliyu
2023-08-30 / 0 评论 / 0 点赞 / 66 阅读 / 6361 字

本文摘自 西岸Alex 的博客 【Kubernetes的负载均衡方案:MetalLB

一、工作原理

Metallb包含两个组件,

- Controller,Controller为Deployment部署方式

- Speaker,Speaker则采用Daemonset方式部署到集群内部各个Node节点。

原理说明:

- Controller负责监听Service变化,当Service配置为LoadBalancer模式时,从IP池分配给到相应的IP地址并对该IP的生命周期进行管理。

- Speaker则会依据选择的协议进行相应的广播或应答,实现IP地址的通信响应。当业务流量通过TCP/UDP协议到达指定的Node时,由Node上面运行的Kube-Proxy组件对流量进行处理,并分发到对应服务的Pod上面。

![metalLB示意图](https://ask.qcloudimg.com/http-save/yehe-4290200/26efdaabfb3a9dd95e289c60a9c75d49.png)

二、 模式

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散列算法。

三、部署

3.1 启用kube-proxy的ARP模式

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

$ kubectl edit configmap -n kube-system kube-proxy 

#设置strictARP值为true

apiVersion: kubeproxy.config.k8s.io/v1alpha1

kind: KubeProxyConfiguration

mode: "ipvs"

ipvs:

  strictARP: true

3.2 安装MetalLB相关组件

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

3.3 配置模式

Layer2模式配置

apiVersion: metallb.io/v1beta1

kind: IPAddressPool

metadata:

  name: ip-pool

  namespace: metallb-system

spec:

  addresses:

  - 192.168.10.210-192.168.10.215   #分配给LB的IP池

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

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配置来测试。

4.1 创建示例yaml文件并执行,包括svc与deployment。

apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
spec:
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer    #类型选择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

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

![获取ip](https://ask.qcloudimg.com/http-save/yehe-4290200/c0afb9a9f7925f77aedb7a1e49f2ea07.png)

4.3 通过外部浏览器访问

![访问](https://ask.qcloudimg.com/http-save/yehe-4290200/11112762797f0bcbee3a18c51d585453.png)

其他

# Print the supported API Resources

kubectl api-resources

# Print the supported API Resources with more information

kubectl api-resources -o wide

# Print the supported API Resources sorted by a column

kubectl api-resources --sort-by=name

# Print the supported namespaced resources

kubectl api-resources --namespaced=true

# Print the supported non-namespaced resources

kubectl api-resources --namespaced=false

# Print the supported API Resources with specific APIGroup

kubectl api-resources --api-group=extensions

参考文档

[metalLB offical web](https://metallb.universe.tf/)

[metalLB github](https://github.com/metallb/metallb)

[k8s中iptables与ipvs详解——2023.05](http://wed.xjx100.cn/news/240339.html)

0

评论区