32.10. 使用 MetalLB 管理对称路由
作为集群管理员,您可以通过从 MetalLB、NMState 和 OVN-Kubernetes 实现功能来有效地管理带有多个主机接口的 MetalLB 负载均衡器服务后面的 pod 的流量。通过结合此上下文中的这些功能,您可以提供对称路由、流量隔离,并支持具有不同网络上的客户端及重叠 CIDR 地址。
要实现此功能,了解如何使用 MetalLB 实施虚拟路由和转发(VRF)实例,并配置出口服务。
使用带有 MetalLB 和出口服务的 VRF 实例配置对称流量只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围。
32.10.1. 使用 MetalLB 管理对称路由的挑战
当您将 MetalLB 与多个主机接口搭配使用时,MetalLB 通过主机上的所有可用接口公开并宣布服务。这可能会造成与网络隔离、非对称返回流量和重叠 CIDR 地址相关的挑战。
确保返回流量达到正确的客户端的一个选项是使用静态路由。但是,使用这个解决方案,MetalLB 无法隔离服务,然后通过不同的接口声明每个服务。另外,静态路由需要手动配置,并在添加远程站点时需要维护。
在实现 MetalLB 服务时,对称路由的进一步挑战是外部系统预期应用程序的源和目标 IP 地址相同的情况。OpenShift Container Platform 的默认行为是将主机网络接口的 IP 地址分配为来自 pod 的流量的源 IP 地址。这在多个主机接口中存在问题。
您可以通过实施组合来自 MetalLB、NMState 和 OVN-Kubernetes 的功能的配置来解决这些挑战。
32.10.2. 使用带有 MetalLB 的 VRF 管理对称路由概述
您可以使用 NMState 在主机上配置 VRF 实例、将 VRF 实例与 MetalLB BGPPeer
资源关联,以及为出口流量配置出口服务来克服实施对称路由的挑战。
图 32.2. 使用带有 MetalLB 的 VRF 管理对称路由的网络概述
配置过程涉及三个阶段:
1.定义 VRF 和路由规则
-
配置
NodeNetworkConfigurationPolicy
自定义资源 (CR),将 VRF 实例与网络接口关联。 - 使用 VRF 路由表直接入口和出口流量。
2.将 VRF 链接到 MetalLB BGPPeer
-
配置 MetalLB
BGPPeer
资源,以使用网络接口上的 VRF 实例。 -
通过将
BGPPeer
资源与 VRF 实例关联,指定的网络接口成为 BGP 会话的主接口,MetalLB 通过这个接口公告服务。
3.配置出口服务
- 配置出口服务,为出口流量选择与 VRF 实例关联的网络。
- 可选:将出口服务配置为使用 MetalLB 负载均衡器服务的 IP 地址作为出口流量的源 IP。
32.10.3. 使用带有 MetalLB 的 VRF 配置对称路由
您可以为需要同一入口和出口网络路径的 MetalLB 服务后面的应用程序配置对称网络路由。
这个示例将 VRF 路由表与 MetalLB 和出口服务相关联,以便为 LoadBalancer
服务后面的 pod 启用对称路由。
-
如果您在
EgressService
CR 中使用sourceIPBy: "LoadBalancerIP"
设置,您必须在BGPAdvertisement
自定义资源 (CR) 中指定负载均衡器节点。 -
在使用带有
gatewayConfig.routingViaHost
规格设置为true
的 OVN-Kubernetes 的集群中,您可以使用sourceIPBy: "Network"
设置。另外,如果您使用sourceIPBy: "Network"
设置,您必须在使用网络 VRF 实例配置的节点上调度应用程序工作负载。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。 - 安装 Kubernetes NMState Operator。
- 安装 MetalLB Operator。
流程
创建一个
NodeNetworkConfigurationPolicy
CR 来定义 VRF 实例:创建一个文件,如
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
字段必须与Cluster Network
CIDR 和Service Network
CIDR 匹配。您可以运行以下命令来查看这些 CIDR 地址规格的值:oc describe network.config/cluster
。 - 10
- 计算路由时使用的 Linux 内核的主路由表的 ID 为
254
。
运行以下命令来应用策略:
$ oc apply -f node-network-vrf.yaml
创建
BGPPeer
自定义资源 (CR):创建一个文件,如
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 peer 关联的 VRF 实例。MetalLB 可以公告服务并根据 VRF 中的路由信息做出路由决策。
运行以下命令,应用 BGP peer 的配置:
$ oc apply -f frr-via-vrf.yaml
创建一个
IPAddressPool
CR:创建一个文件,如
first-pool.yaml
,其内容类似以下示例:apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: first-pool namespace: metallb-system spec: addresses: - 192.169.10.0/32
运行以下命令,为 IP 地址池应用配置:
$ oc apply -f first-pool.yaml
创建
BGPAdvertisement
CR:创建一个文件,如
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
运行以下命令,应用 BGP 公告的配置:
$ oc apply -f first-adv.yaml
创建一个
EgressService
CR:创建一个文件,如
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
- 指定出口服务的名称。
EgressService
资源的名称必须与您要修改的负载均衡器服务的名称匹配。 - 2
- 指定出口服务的命名空间。
EgressService
的命名空间必须与您要修改的负载均衡器服务的命名空间匹配。egress 服务是命名空间范围的。 - 3
- 这个示例将
LoadBalancer
服务入口 IP 地址分配为出口流量的源 IP 地址。 - 4
- 如果为
sourceIPBy
规格指定LoadBalancer
,则单一节点处理LoadBalancer
服务流量。在本例中,只有标签vrf: "true"
的节点才能处理服务流量。如果没有指定节点,OVN-Kubernetes 会选择一个 worker 节点来处理服务流量。当选择节点时,OVN-Kubernetes 以以下格式标记节点:egress-service.k8s.ovn.org/<svc_namespace>-<svc_name>: ""
。 - 5
- 指定出口流量的路由表。
运行以下命令,为出口服务应用配置:
$ oc apply -f egress-service.yaml
验证
运行以下命令,验证您可以访问 MetalLB 服务后运行的 pod 的应用程序端点:
$ curl <external_ip_address>:<port_number> 1
- 1
- 更新外部 IP 地址和端口号,以适合您的应用程序端点。
-
可选:如果您将
LoadBalancer
服务入口 IP 地址指定为出口流量的源 IP 地址,请使用tcpdump
等工具分析外部客户端接收的数据包,以此验证此配置。