×

作为集群管理员,您可以通过实施 MetalLB、NMState 和 OVN-Kubernetes 的功能,有效地管理位于具有多个主机接口的 MetalLB 负载均衡器服务后面的 Pod 的流量。在此环境中组合这些功能,您可以提供对称路由、流量隔离,并支持具有重叠 CIDR 地址的不同网络上的客户端。

要实现此功能,请了解如何使用 MetalLB 实现虚拟路由和转发 (VRF) 实例,以及如何配置出站服务。

使用 MetalLB 和出站服务配置基于 VRF 实例的对称流量仅是技术预览功能。技术预览功能不受 Red Hat 生产服务级别协议 (SLA) 的支持,并且可能功能不完整。Red Hat 不建议在生产环境中使用它们。这些功能提供对即将推出的产品功能的抢先访问,使客户能够在开发过程中测试功能并提供反馈。

有关 Red Hat 技术预览功能的支持范围的更多信息,请参阅 技术预览功能支持范围

使用 MetalLB 管理对称路由的挑战

当您将 MetalLB 与多个主机接口一起使用时,MetalLB 会通过主机上的所有可用接口公开和宣布服务。这可能会带来与网络隔离、非对称返回流量和重叠 CIDR 地址相关的挑战。

确保返回流量到达正确的客户端的一种方法是使用静态路由。但是,使用此解决方案,MetalLB 无法隔离服务,然后通过不同的接口宣布每个服务。此外,静态路由需要手动配置,如果添加远程站点,则需要维护。

在实施 MetalLB 服务时,对称路由的另一个挑战是外部系统期望应用程序的源 IP 地址和目标 IP 地址相同的情况。OpenShift Container Platform 的默认行为是为源自 Pod 的流量分配主机网络接口的 IP 地址作为源 IP 地址。对于多个主机接口,这存在问题。

您可以通过实施结合 MetalLB、NMState 和 OVN-Kubernetes 功能的配置来克服这些挑战。

使用 MetalLB 和 VRF 管理对称路由的概述

您可以通过使用 NMState 在主机上配置 VRF 实例,将 VRF 实例与 MetalLB BGPPeer 资源关联,并为 OVN-Kubernetes 的出站流量配置出站服务来克服实施对称路由的挑战。

Network overview of managing symmetric routing by using VRFs with MetalLB
图 1. 使用 MetalLB 和 VRF 管理对称路由的网络概述

配置过程涉及三个阶段

1. 定义 VRF 和路由规则
  • 配置 NodeNetworkConfigurationPolicy 自定义资源 (CR) 以将 VRF 实例与网络接口关联。

  • 使用 VRF 路由表来引导入站和出站流量。

2. 将 VRF 链接到 MetalLB BGPPeer
  • 配置 MetalLB BGPPeer 资源以使用网络接口上的 VRF 实例。

  • 通过将 BGPPeer 资源与 VRF 实例关联,指定的网络接口将成为 BGP 会话的主要接口,MetalLB 将通过此接口通告服务。

3. 配置出站服务
  • 配置出站服务以选择与 VRF 实例关联的网络用于出站流量。

  • 可选:配置出站服务以使用 MetalLB 负载均衡器服务的 IP 地址作为出站流量的源 IP。

使用 MetalLB 和 VRF 配置对称路由

您可以为位于需要相同入站和出站网络路径的 MetalLB 服务后面的应用程序配置对称网络路由。

此示例将 VRF 路由表与 MetalLB 和 egress 服务关联,以便为 `LoadBalancer` 服务后方的 Pod 启用对称路由,用于处理入站和出站流量。

  • 如果在 `EgressService` CR 中使用 `sourceIPBy: "LoadBalancerIP"` 设置,则必须在 `BGPAdvertisement` 自定义资源 (CR) 中指定负载均衡器节点。

  • 仅当使用配置了 `gatewayConfig.routingViaHost` 规范设置为 `true` 的 OVN-Kubernetes 的集群时,才能使用 `sourceIPBy: "Network"` 设置。此外,如果使用 `sourceIPBy: "Network"` 设置,则必须在配置了网络 VRF 实例的节点上调度应用程序工作负载。

先决条件
  • 安装 OpenShift 命令行界面 (oc)。

  • 以具有 `cluster-admin` 权限的用户身份登录。

  • 安装 Kubernetes NMState 运算符。

  • 安装 MetalLB 运算符。

步骤
  1. 创建 `NodeNetworkConfigurationPolicy` CR 以定义 VRF 实例

    1. 创建一个文件,例如 `node-network-vrf.yaml`,内容如下例所示

      apiVersion: nmstate.io/v1
      kind: NodeNetworkConfigurationPolicy
      metadata:
        name: vrfpolicy (1)
      spec:
        nodeSelector:
          vrf: "true" (2)
        maxUnavailable: 3
        desiredState:
          interfaces:
          - name: ens4vrf (3)
            type: vrf (4)
            state: up
            vrf:
              port:
              - ens4 (5)
              route-table-id: 2 (6)
          - name: ens4 (7)
            type: ethernet
            state: up
            ipv4:
              address:
              - ip: 192.168.130.130
                prefix-length: 24
              dhcp: false
              enabled: true
          routes: (8)
            config:
            - destination: 0.0.0.0/0
              metric: 150
              next-hop-address: 192.168.130.1
              next-hop-interface: ens4
              table-id: 2
          route-rules: (9)
            config:
            - ip-to: 172.30.0.0/16
              priority: 998
              route-table: 254 (10)
            - ip-to: 10.132.0.0/14
              priority: 998
              route-table: 254
      1 策略的名称。
      2 此示例将策略应用于所有具有标签 `vrf:true` 的节点。
      3 接口的名称。
      4 接口的类型。此示例创建一个 VRF 实例。
      5 VRF 附加到的节点接口。
      6 VRF 的路由表 ID 名称。
      7 与 VRF 关联的接口的 IPv4 地址。
      8 定义网络路由的配置。`next-hop-address` 字段定义路由的下一跳的 IP 地址。`next-hop-interface` 字段定义路由的出站接口。在此示例中,VRF 路由表为 `2`,它引用您在 `EgressService` CR 中定义的 ID。
      9 定义额外的路由规则。`ip-to` 字段必须与 `集群网络` CIDR 和 `服务网络` CIDR 匹配。您可以通过运行以下命令查看这些 CIDR 地址规范的值:oc describe network.config/cluster
      10 Linux 内核在计算路由时使用的主路由表 ID 为 `254`。
    2. 运行以下命令应用策略

      $ oc apply -f node-network-vrf.yaml
  2. 创建 `BGPPeer` 自定义资源 (CR)

    1. 创建一个文件,例如 `frr-via-vrf.yaml`,内容如下例所示

      apiVersion: metallb.io/v1beta2
      kind: BGPPeer
      metadata:
        name: frrviavrf
        namespace: metallb-system
      spec:
        myASN: 100
        peerASN: 200
        peerAddress: 192.168.130.1
        vrf: ens4vrf (1)
      1 指定要与 BGP 对等体关联的 VRF 实例。MetalLB 可以根据 VRF 中的路由信息来通告服务并做出路由决策。
    2. 运行以下命令应用 BGP 对等体的配置

      $ oc apply -f frr-via-vrf.yaml
  3. 创建 `IPAddressPool` CR

    1. 创建一个文件,例如 `first-pool.yaml`,内容如下例所示

      apiVersion: metallb.io/v1beta1
      kind: IPAddressPool
      metadata:
        name: first-pool
        namespace: metallb-system
      spec:
        addresses:
        - 192.169.10.0/32
    2. 运行以下命令应用 IP 地址池的配置

      $ oc apply -f first-pool.yaml
  4. 创建 `BGPAdvertisement` CR

    1. 创建一个文件,例如 `first-adv.yaml`,内容如下例所示

      apiVersion: metallb.io/v1beta1
      kind: BGPAdvertisement
      metadata:
        name: first-adv
        namespace: metallb-system
      spec:
        ipAddressPools:
          - first-pool
        peers:
          - frrviavrf (1)
        nodeSelectors:
          - matchLabels:
              egress-service.k8s.ovn.org/test-server1: "" (2)
      1 在此示例中,MetalLB 将 `first-pool` IP 地址池中的 IP 地址范围通告给 `frrviavrf` BGP 对等体。
      2 在此示例中,`EgressService` CR 将出站流量的源 IP 地址配置为使用负载均衡器服务的 IP 地址。因此,您必须指定负载均衡器节点,以便返回流量使用与 Pod 发起的流量相同的返回路径。
    2. 运行以下命令应用 BGP 通告的配置

      $ oc apply -f first-adv.yaml
  5. 创建 `EgressService` CR

    1. 创建一个文件,例如 `egress-service.yaml`,内容如下例所示

      apiVersion: k8s.ovn.org/v1
      kind: EgressService
      metadata:
        name: server1 (1)
        namespace: test (2)
      spec:
        sourceIPBy: "LoadBalancerIP" (3)
        nodeSelector:
          matchLabels:
            vrf: "true" (4)
        network: "2" (5)
      1 指定 egress 服务的名称。`EgressService` 资源的名称必须与要修改的负载均衡器服务的名称匹配。
      2 指定 egress 服务的命名空间。`EgressService` 的命名空间必须与要修改的负载均衡器服务的命名空间匹配。egress 服务是命名空间范围的。
      3 此示例将 `LoadBalancer` 服务入口 IP 地址分配为出站流量的源 IP 地址。
      4 如果为 `sourceIPBy` 规范指定 `LoadBalancer`,则单个节点将处理 `LoadBalancer` 服务流量。在此示例中,只有具有标签 `vrf: "true"` 的节点才能处理服务流量。如果不指定节点,OVN-Kubernetes 将选择一个工作节点来处理服务流量。选择节点后,OVN-Kubernetes 将以以下格式标记该节点:`egress-service.k8s.ovn.org/-: ""`。
      5 指定出站流量的路由表。
    2. 运行以下命令应用 egress 服务的配置

      $ oc apply -f egress-service.yaml
验证
  1. 通过运行以下命令验证您可以访问在 MetalLB 服务后运行的 Pod 的应用程序端点

    $ curl <external_ip_address>:<port_number> (1)
    1 更新外部 IP 地址和端口号以适应您的应用程序端点。
  2. 可选:如果您将 `LoadBalancer` 服务入口 IP 地址分配为出站流量的源 IP 地址,请使用诸如 `tcpdump` 之类的工具分析外部客户端接收到的数据包来验证此配置。