Kubernetes之Service LoadBalancer调度Metallb解决方案

 

简介

  Kubernetes Service服务的LoadBalancer调度通常需要云厂商的laaS平台(AWS、Azure、阿里云)提供负载均衡的服务。而如果只是企业内部使用Kubernetes,并且也需要负载均衡服务,那么MetalLB是一个不错的选择。MetalLB是裸机Kubernetes集群的负载均衡器实现,使用标准路由协议。

  官网地址:https://metallb.io

MetalLB IP地址分配机制

Layer 2模式

  这是MetalLB默认的工作模式,在这种模式下,MetalLB使用ARP协议来响应分配给Service的IP地址的请求。这意味着 MetalLB 会配置集群中的某个节点来回应针对该 IP 的 ARP 请求。实际上,这意味着任意时刻只有一个节点会响应来自客户端的请求,但这种响应是动态的,如果当前响应节点失败,另一个节点可以接管。它的局限性就是因为ARP广播通常局限于同一个二层网络(即同一个VLAN或广播域)内,那么意味着访问Kubernetes服务的客户端和Kubernetes集群要在同一个网段下面,不同网段的客户端是收不到MetalLB的ARP宣告。

BGP 模式

  在此模式下,MetalLB可以与支持BGP的路由器通信,宣告由Kubernetes服务使用的IP地址范围。这允许外部路由器知道如何到达这些 IP 地址,并根据路由信息将流量转发到正确的节点。这种方式更加灵活和冗余,因为它不依赖于单一节点来处理特定 IP 的流量。并且在公司不同网段的客户端也可以访问Kubernetes集群中的服务。同时它的局限性就是公司的网络设备要支持BGP协议,MetalLB BGP模式要跟公司内部的路由器做IBGP对接,进行路由信息同步,对硬件网络设备要求较高。

MetalLB服务安装

官网地址:https://metallb.io/installation/

1、kube-proxy启用ARP模式

# see what changes would be made, returns nonzero returncode if different
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl diff -f - -n kube-system
上下两种方式任选其一
# actually apply the changes, returns nonzero returncode on errors only
kubectl get configmap kube-proxy -n kube-system -o yaml | \
sed -e "s/strictARP: false/strictARP: true/" | \
kubectl apply -f - -n kube-system

2、安装MetalLB服务

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

 3、定义分配给负载均衡服务的ip池

官网地址:https://metallb.io/configuration/     

vim ip-pool.yaml   注意:ip地址池里的地址一定要是未被使用的ip地址,否则会导致ip地址冲突。并且要跟kubernetes集群同网段,否则ARP报文不会被宣告。同时不但支持ip地址范围,也支持CIDR。

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

4、使用Layer 2宣告服务IP池

官网地址:https://metallb.io/configuration/#layer-2-configuration
vim l2-advertisement.yaml

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: my-l2-advertisement
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool

部署Kubernetes资源服务测试

1、deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginxdemo
  labels:
    app: nginx
    version: 0.1.0
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
      version: 0.1.0
  template:
    metadata:
      labels:
        app: nginx
        version: 0.1.0
    spec:
      containers:
      - name: nginxdemo
        image: nginx
        ports:
        - containerPort: 80
          name: http

2、service

apiVersion: v1
kind: Service
metadata:
  name: nginxdemo
  labels:
    app: nginx
    version: 0.1.0
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app: nginx
    version: 0.1.0

 

3、测试

3.1、要先改造一下启动的两个Nginx pod

kubectl exec -it nginxdemo-77bc78c8c4-jmvdq -- /bin/bash
echo "<h1>Nginx Test Server 1</h1>" > /usr/share/nginx/html/index.html

kubectl exec -it nginxdemo-77bc78c8c4-tkjvs -- /bin/bash
echo "<h1>Nginx Test Server 2</h1>" > /usr/share/nginx/html/index.html

3.2、先在集群内部做测试

# 启用一个临时pod服务
kubectl run -it --rm debug --image=busybox -- sh

 3.3、在客户端主机上用LoadBalancer IP访问

 后记

查看MetalLB日志

kubectl logs -l app=metallb,component=speaker -n metallb-system
... ...
{"caller":"main.go:420","event":"serviceAnnounced","ips":["192.168.90.200"],"level":"info","msg":"service has IP, announcing","pool":"first-pool","protocol":"layer2","ts":"2025-05-28T06:56:12Z"}
... ...
# 表明IP已经被成功分配。

用arping工具来检测是否有节点响应了LoadBalancer IP的ARP请求

 画红框的mac地址实际上是,Kubernetes 其中一个node节点物理机网卡的mac。

表明由stw-node1这个节点来向局域网发送ARP广播宣告192.168.90.200,同时也响应针对192.168.90.200的ARP请求。

 

posted @ 2025-05-28 16:10  潇湘神剑  阅读(66)  评论(0)    收藏  举报