Kube-OVN Underlay + MetalLB LoadBalancer 服务配置

Overview

本方案解决了 MetalLB L2 模式与 Kube-OVN Underlay 网络的集成问题。它允许用户使用 Underlay 子网 IP 作为 MetalLB LoadBalancer 服务的 VIP,流量直接转发到后端业务 Pod。

Prerequisites

环境要求

  • ACP 版本:>= 4.2.2
  • IP 支持:仅支持 IPv4(当前不支持 IPv6)

流量流程

流量示意图


配置步骤

1. 配置带 VLAN 子接口的 ProviderNetwork

重要:必须使用 VLAN 子接口。

配置 Kube-OVN Underlay 网络自动创建 VLAN 子接口:

apiVersion: kubeovn.io/v1
kind: ProviderNetwork
metadata:
  name: provider
spec:
  defaultInterface: underlay0.341
  autoCreateVlanSubinterfaces: true  # 如果只有父接口(underlay0),则自动创建 VLAN 子接口(如 underlay0.341)

---
apiVersion: kubeovn.io/v1
kind: Vlan
metadata:
  name: ovn-vlan
spec:
  id: 0    # 使用 0 是因为 autoCreateVlanSubinterfaces 会创建 VLAN 子接口(underlay0.341)来处理 VLAN 标签,Kube-OVN 本身不直接处理
  provider: provider
status:
  subnets:
  - ovn-default

⚠️ 警告:单独修改 ProviderNetworkVlan 资源时,Underlay 网络连通性会中断。只有两个资源都配置完成且同步后,网络连通性才会恢复。请在维护窗口期间进行配置变更以减少服务中断。

2. 配置 Kube-OVN Controller 参数

为 LoadBalancer 功能配置 Kube-OVN controller 参数:

通过 Web 控制台操作:

  1. 进入 管理员 > Marketplace > 集群插件,搜索 ovn,找到 Alauda Container Platform Networking for Kube-OVN
  2. 在插件行点击操作菜单(竖直 ⋮),选择 更新 打开配置对话框
  3. 配置以下参数:
    • Skip CT for Dst LPort IPs
    • Enable OVN LB Local

3. 配置 Underlay 子网的外部地址功能

编辑 Underlay 子网,预留一段 IP 范围用于 LoadBalancer 使用:

重要:外部地址池 IP 必须在 Underlay 子网内。

修改 Underlay 子网参数 spec.enableExternalLBAddress: true

apiVersion: kubeovn.io/v1
kind: Subnet
metadata:
  name: underlay-subnet
spec:
  enableExternalLBAddress: true       # 表示该子网有用于 LB 服务 VIP 的 IP 范围
  excludeIps:
  - 10.180.208.200..10.180.208.220    # 预留 IP 范围作为外部地址池

4. 创建 MetalLB 外部地址池

# underlay-ippool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: acp-underlay-pool
  namespace: metallb-system
spec:
  addresses:
    - 10.180.208.200-10.180.208.220  # Underlay 子网 IP 范围
  avoidBuggyIPs: true
  autoAssign: true
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: acp-underlay-pool
  namespace: metallb-system
spec:
  ipAddressPools:
    - acp-underlay-pool
  nodeSelectors: []

部署地址池:

kubectl apply -f underlay-ippool.yaml

5. 创建示例应用及 LoadBalancer 服务

# application-with-loadbalancer.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-app
  labels:
    app: backend
spec:
  replicas: 3
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
        - name: backend
          image: nginx:1.25
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: backend-lb-service
  # 若使用指定 IPPool:添加注解 `metallb.io/address-pool: acp-underlay-pool`
  # 若使用固定 IP:设置 `spec.loadBalancerIP: 10.180.208.201`
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local  # **重要**:保留源 IP,启用直通 Pod 路由
  selector:
    app: backend
  ports:
    - port: 80
      targetPort: 80

部署应用:

kubectl apply -f application-with-loadbalancer.yaml

6. 验证配置

# 查看服务状态
kubectl get svc backend-lb-service -o wide

# 测试外部访问
curl http://10.180.208.200

7. 迁移现有服务

对于使用旧地址池(仅节点子网)的现有服务,可以迁移到新的 Underlay 地址池:

# 为现有服务添加注解以迁移
kubectl annotate service <existing-service-name> metallb.io/address-pool=acp-underlay-pool --overwrite

# 验证服务已分配新的 Underlay 地址池 IP
kubectl get svc <existing-service-name> -o wide

对于新服务,直接添加注解:

apiVersion: v1
kind: Service
metadata:
  name: backend-lb-service
  annotations:
    metallb.io/address-pool: acp-underlay-pool  # 使用 Underlay 地址池
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  selector:
    app: backend
  ports:
    - port: 80
      targetPort: 80
# 查看服务状态
kubectl get svc backend-lb-service -o wide

# 测试外部访问
curl http://10.180.208.200