配置 Egress Gateway

概述

Egress Gateway,也称为 VPC Egress Gateway,为 overlay 网络中的 Pod 提供稳定的出站地址。 它会先将选定的工作负载路由到专用网关 Pod,然后流量再离开集群。

在以下场景中使用 Egress Gateway:

  • 为特定工作负载提供稳定的源 IP 地址
  • 以工作负载级别进行出站控制,而不是子网级别控制
  • 通过水平扩展获得更高吞吐量
  • 更快地处理出站流量故障切换

主要能力:

  • 通过 ECMP 实现 Active-Active 高可用,并支持水平吞吐扩展
  • 通过 BFD 实现快速故障切换,通常可在 1 秒内完成
  • 支持 IPv4、IPv6 和双栈环境
  • 通过 NamespaceSelector 和 PodSelector 实现细粒度流量匹配
  • 通过 node selector 和 toleration 实现灵活调度

当前限制:

  • 多副本部署需要多个 egress IP
  • 不保留源 NAT 映射记录

Egress Gateway 与 Centralized Gateway 的对比

将 Egress Gateway 与 Centralized Gateway 进行对比,以选择最适合你场景的网关模型。 有关 centralized 模式的详细信息,请参阅 配置 Centralized Gateway

维度Egress GatewayCentralized Gateway
粒度通过 selectorspolicies(Namespace/Pod/Subnet/IPBlock)进行细粒度控制。在子网级别应用(gatewayType: centralized)。
出站地址来源使用带有外部子网 IP 的专用网关 Pod。使用指定的网关节点;在 natOutgoing: true 时,出站流量使用节点 IP。
数据路径流量先路由到 VPC Egress Gateway Pod,然后 SNAT 到外部网络。流量路由到指定节点(ovn0),再由主机路由/NAT 规则转发。
HA 和故障切换Active-Active ECMP;支持 BFD 快速故障切换(亚秒级)。支持 ECMP 和主备模式;故障切换通常比基于 BFD 的 Egress Gateway 更慢。
调度控制支持为网关工作负载配置节点调度控制(nodeSelectortolerations)。通过 gatewayNodegatewayNodeSelectors 选择网关节点。
典型使用场景租户级或工作负载级出站隔离、细粒度策略控制、更高性能和更快的故障切换。更简单的子网级固定源出站、审计、IP 白名单和防火墙源 IP 管理。

选择建议:

  • 当你需要工作负载级策略控制、可扩展吞吐量和快速故障切换时,选择 Egress Gateway
  • 当子网级固定出站和简单运维已足够时,选择 Centralized Gateway

Egress Gateway 的工作原理

Egress Gateway 以一个或多个 Pod 的形式运行。每个 Pod 使用两个网络接口:

  • 一个接口连接集群内的 overlay 网络。
  • 另一个接口连接外部 underlay 网络。

来自所选 Pod 的流量会先转发到网关 Pod,然后通过 underlay 接口发送到外部网络。

每个 Egress Gateway 实例都会在 OVN 路由表中注册其地址。 当 overlay 网络中的 Pod 访问外部网络时,OVN 会使用源地址哈希在多个网关实例之间分发流量。 这提供了负载均衡,并允许随着实例数量增加而水平扩展吞吐量。

OVN 可以使用 BFD 探测多个网关实例。 如果某个实例失败,OVN 会将对应路由标记为不可用,并快速将流量重定向到健康的实例。

开始之前

在开始之前,请确保满足以下前提条件:

  • 集群中已经安装 Multus CNI Plugin MUST
  • 已完成外部 underlay 网络、VLAN 和 bridge network 的规划并可用。
  • 你已确定哪些工作负载应使用该网关,以及它们是否需要 SNAT。

要安装 Multus CNI Plugin,请参阅 部署 Multus CNI Plugin

配置流程

按以下顺序配置 Egress Gateway:

  1. 准备外部网络附加,包括子网和 Network Attachment Definition。
  2. 创建 VPC Egress Gateway 资源,并指定外部子网和策略。
  3. 验证资源状态、路由和流量转发。
  4. 可选地扩展副本并启用基于 BFD 的快速故障切换。

步骤 1:准备外部网络附加

Egress Gateway 使用多个接口同时连接内部网络和外部网络。 在创建网关之前,请准备以下资源:

  • 一个外部子网
  • 该子网对应的 Network Attachment Definition(NAD)
NOTE

NetworkAttachmentDefinition 名称 MUST NOT 包含点号(.)。 每个 NetworkAttachmentDefinition 只能用于一个子网。不要在多个子网之间重复使用同一个 NetworkAttachmentDefinition。

以下示例使用 Kube-OVN underlay 子网作为外部网络。

NOTE

此示例假设用于 underlay 网络的 bridge network 和 VLAN 资源 external-vlan 已经创建。

apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: underlay-ext
  namespace: default
spec:
  config: |-
    {
      "cniVersion": "0.3.0",
      "type": "kube-ovn",
      "server_socket": "/run/openvswitch/kube-ovn-daemon.sock",
      "provider": "underlay-ext.default.ovn"
    }
---
apiVersion: kubeovn.io/v1
kind: Subnet
metadata:
  name: underlay-ext
spec:
  protocol: IPv4
  provider: underlay-ext.default.ovn
  cidrBlock: 172.17.0.0/16
  gateway: 172.17.0.1
  vlan: external-vlan
  excludeIps:
    - 172.17.0.11..172.17.0.20
  1. secondary network 使用的 Kube-OVN CNI plugin。
  2. CNI plugin 使用的 Kube-OVN daemon socket。
  3. 形式为 <network attachment definition name>.<namespace>.ovn 的 provider 名称。
  4. 子网使用的 provider。此值 MUST 与 NetworkAttachmentDefinition 中的 provider 保持一致。
  5. 外部 underlay 网络的 CIDR。
  6. 外部 underlay 网络的 gateway。
  7. underlay 子网使用的 VLAN 资源。
  8. 从自动分配中排除的 IP 范围。有关详细信息,请参阅 使用 Kube-OVN Underlay 网络的子网自定义资源(CR)示例
TIP

在使用 underlay 子网之前,请确保物理网络、VLAN 和 bridge network 已正确准备。 有关环境规划的详细信息,请参阅 准备 Kube-OVN Underlay 物理网络

步骤 2:创建 VPC Egress Gateway

创建 VPC Egress Gateway 资源,并定义哪些工作负载应使用它。

apiVersion: kubeovn.io/v1
kind: VpcEgressGateway
metadata:
  name: gateway1
  namespace: default
spec:
  replicas: 1
  internalSubnet: ovn-default
  externalSubnet: underlay-ext
  externalIPs:
    - 172.17.0.11
    - 172.17.0.12
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 200m
      memory: 256Mi
      ephemeral-storage: 2Gi
  nodeSelector:
    - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
            - node1
            - node2
  tolerations:
    - key: node-role.kubernetes.io/control-plane
      operator: Exists
      effect: NoSchedule
  selectors:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: ns1
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: ns2
      podSelector:
        matchLabels:
          app: myapp
  policies:
    - snat: true
      subnets:
        - subnet1
    - snat: false
      ipBlocks:
        - 10.18.0.0/16
  1. 创建 VPC Egress Gateway 实例的 namespace。
  2. VPC Egress Gateway 实例数量。
  3. 连接内部网络的 internal subnet。该子网 MUST 是同一 VPC 中的 overlay 子网,并且具有足够的可用 IP 供网关实例使用。 如果未指定,网关 Pod 将使用 VPC 的默认 internal subnet。
  4. 连接外部网络的 external subnet。
  5. 网关 Pod 在 underlay 网络上使用的 external IP。每个网关实例都会从该列表中分配一个 IP。 这些 IP MUST 位于外部子网的 CIDR 内,并且应包含在子网的 excludeIps 范围中。 建议预留 .spec.replicas + 1 个 IP,以便在边缘情况下网关 Pod 仍能获取到 IP。
  6. 每个 VPC Egress Gateway 实例的资源 requests 和 limits。 如果未指定,将应用 VPC Egress Gateway controller 中定义的默认资源 requests 和 limits。
  7. 用于调度 VPC Egress Gateway 实例的 node selector。
  8. 用于调度 VPC Egress Gateway 实例的 toleration。
  9. 用于选择通过 VPC Egress Gateway 访问外部网络的 Pod 的 Namespace selector 和 Pod selector。
  10. VPC Egress Gateway 的策略,包括要应用的 SNAT 和 subnets/ipBlocks。
  11. 是否为该策略启用 SNAT。
  12. 该策略适用的子网。
  13. 该策略适用的 IP block。

此示例在 default namespace 中创建一个名为 gateway1 的 VPC Egress Gateway。 匹配这些 selector 和 policy 的流量会通过外部子网 underlay-ext 转发。 在此示例中,包括:

  • ns1 namespace 中的 Pod
  • 带有标签 app: myappns2 namespace 中的 Pod
  • subnet1 子网相关的流量
  • 与 CIDR 10.18.0.0/16 相关的流量
NOTE

匹配 .spec.selectors 的 Pod 始终会被网关执行 SNAT。

步骤 3:验证网关

创建网关后,确认它已准备就绪并按预期转发流量。

1. 检查资源状态

先检查基础资源状态:

$ kubectl get veg gateway1
NAME       VPC           REPLICAS   BFD ENABLED   EXTERNAL SUBNET   PHASE       READY   AGE
gateway1   ovn-cluster   1          false         underlay-ext      Completed   true    13s

然后检查详细的网关信息:

kubectl get veg gateway1 -o wide
NAME       VPC           REPLICAS   BFD ENABLED   EXTERNAL SUBNET   PHASE       READY   INTERNAL IPS     EXTERNAL IPS      WORKING NODES   AGE
gateway1   ovn-cluster   1          false         underlay-ext      Completed   true    ["10.16.0.12"]   ["172.17.0.11"]   ["node1"]       82s

最后,验证网关工作负载是否正在运行:

$ kubectl get deployment -n default -l ovn.kubernetes.io/vpc-egress-gateway=gateway1
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
gateway1   1/1     1            1           4m40s

$ kubectl get pod -n default -l ovn.kubernetes.io/vpc-egress-gateway=gateway1 -o wide
NAME                       READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
gateway1-b9f8b4448-76lhm   1/1     Running   0          4m48s   10.16.0.12   node1   <none>           <none>

2. 检查网关 Pod 内部的网络

检查网关 Pod 内的 IP 地址、路由条目和 iptables 规则:

$ kubectl exec -n default gateway1-b9f8b4448-76lhm -c gateway -- ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: net1@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 62:d8:71:90:7b:86 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.11/16 brd 172.17.255.255 scope global net1
       valid_lft forever preferred_lft forever
    inet6 fe80::60d8:71ff:fe90:7b86/64 scope link
       valid_lft forever preferred_lft forever
17: eth0@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP group default
    link/ether 36:7c:6b:c7:82:6b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.16.0.12/16 brd 10.16.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::347c:6bff:fec7:826b/64 scope link
       valid_lft forever preferred_lft forever

$ kubectl exec -n default gateway1-b9f8b4448-76lhm -c gateway -- ip rule show
0:      from all lookup local
1001:   from all iif eth0 lookup default
1002:   from all iif net1 lookup 1000
1003:   from 10.16.0.12 iif lo lookup 1000
1004:   from 172.17.0.11 iif lo lookup default
32766:  from all lookup main
32767:  from all lookup default

$ kubectl exec -n default gateway1-b9f8b4448-76lhm -c gateway -- ip route show
default via 172.17.0.1 dev net1
10.16.0.0/16 dev eth0 proto kernel scope link src 10.16.0.12
10.17.0.0/16 via 10.16.0.1 dev eth0
10.18.0.0/16 via 10.16.0.1 dev eth0
172.17.0.0/16 dev net1 proto kernel scope link src 172.17.0.11

$ kubectl exec -n default gateway1-b9f8b4448-76lhm -c gateway -- ip route show table 1000
default via 10.16.0.1 dev eth0

$ kubectl exec -n default gateway1-b9f8b4448-76lhm -c gateway -- iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N VEG-MASQUERADE
-A PREROUTING -i eth0 -j MARK --set-xmark 0x4000/0x4000
-A POSTROUTING -d 10.18.0.0/16 -j RETURN
-A POSTROUTING -s 10.18.0.0/16 -j RETURN
-A POSTROUTING -j VEG-MASQUERADE
-A VEG-MASQUERADE -j MARK --set-xmark 0x0/0xffffffff
-A VEG-MASQUERADE -j MASQUERADE --random-fully

3. 确认流量转发

在网关 Pod 中抓包,以确认流量已通过网关转发:

$ kubectl exec -n default gateway1-b9f8b4448-76lhm -c gateway -- tcpdump -i any -nnve icmp and host 172.17.0.1
tcpdump: data link type LINUX_SLL2
tcpdump: listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
06:50:58.936528 eth0  In  ifindex 17 92:26:b8:9e:f2:1c ethertype IPv4 (0x0800), length 104: (tos 0x0, ttl 63, id 30481, offset 0, flags [DF], proto ICMP (1), length 84)
    10.17.0.9 > 172.17.0.1: ICMP echo request, id 37989, seq 0, length 64
06:50:58.936574 net1  Out ifindex 2 62:d8:71:90:7b:86 ethertype IPv4 (0x0800), length 104: (tos 0x0, ttl 62, id 30481, offset 0, flags [DF], proto ICMP (1), length 84)
    172.17.0.11 > 172.17.0.1: ICMP echo request, id 39449, seq 0, length 64
06:50:58.936613 net1  In  ifindex 2 02:42:39:79:7f:08 ethertype IPv4 (0x0800), length 104: (tos 0x0, ttl 64, id 26701, offset 0, flags [none], proto ICMP (1), length 84)
    172.17.0.1 > 172.17.0.11: ICMP echo reply, id 39449, seq 0, length 64
06:50:58.936621 eth0  Out ifindex 17 36:7c:6b:c7:82:6b ethertype IPv4 (0x0800), length 104: (tos 0x0, ttl 63, id 26701, offset 0, flags [none], proto ICMP (1), length 84)
    172.17.0.1 > 10.17.0.9: ICMP echo reply, id 37989, seq 0, length 64

4. 确认 OVN 路由策略

会为所选流量自动创建 OVN Logical Router policies:

$ kubectl ko nbctl lr-policy-list ovn-cluster
Routing Policies
     31000                            ip4.dst == 10.16.0.0/16   allow
     31000                            ip4.dst == 10.17.0.0/16   allow
     31000                           ip4.dst == 100.64.0.0/16   allow
     30000                              ip4.dst == 172.18.0.2  reroute  100.64.0.4
     30000                              ip4.dst == 172.18.0.3  reroute  100.64.0.3
     30000                              ip4.dst == 172.18.0.4  reroute  100.64.0.2
     29100                  ip4.src == $VEG.8ca38ae7da18.ipv4  reroute  10.16.0.12
     29100                   ip4.src == $VEG.8ca38ae7da18_ip4  reroute  10.16.0.12
     29000 ip4.src == $ovn.default.kube.ovn.control.plane_ip4  reroute  100.64.0.3
     29000       ip4.src == $ovn.default.kube.ovn.worker2_ip4  reroute  100.64.0.2
     29000        ip4.src == $ovn.default.kube.ovn.worker_ip4  reroute  100.64.0.4
     29000     ip4.src == $subnet1.kube.ovn.control.plane_ip4  reroute  100.64.0.3
     29000           ip4.src == $subnet1.kube.ovn.worker2_ip4  reroute  100.64.0.2
     29000            ip4.src == $subnet1.kube.ovn.worker_ip4  reroute  100.64.0.4
  1. VPC Egress Gateway 用于转发与 .spec.policies 匹配流量的 Logical Router Policy。
  2. VPC Egress Gateway 用于转发与 .spec.selectors 匹配流量的 Logical Router Policy。

可选:启用多副本负载均衡

NOTE

在扩展副本之前,请确保在外部子网中准备了足够的外部 IP,并将它们指定到 .spec.externalIPs 中。

要启用 ECMP 负载均衡并水平扩展吞吐量,请增加 .spec.replicas

$ kubectl scale veg -n default gateway1 --replicas=2
vpcegressgateway.kubeovn.io/gateway1 scaled

$ kubectl get veg -n default gateway1
NAME       VPC           REPLICAS   BFD ENABLED   EXTERNAL SUBNET   PHASE       READY   AGE
gateway1   ovn-cluster   2          false         underlay-ext      Completed   true    39m

$ kubectl get pod -n default -l ovn.kubernetes.io/vpc-egress-gateway=gateway1 -o wide
NAME                       READY   STATUS    RESTARTS   AGE   IP           NODE    NOMINATED NODE   READINESS GATES
gateway1-b9f8b4448-76lhm   1/1     Running   0          40m   10.16.0.12   node1   <none>           <none>
gateway1-b9f8b4448-zd4dl   1/1     Running   0          64s   10.16.0.13   node2   <none>           <none>

$ kubectl ko nbctl lr-policy-list ovn-cluster
Routing Policies
     31000                            ip4.dst == 10.16.0.0/16    allow
     31000                            ip4.dst == 10.17.0.0/16    allow
     31000                           ip4.dst == 100.64.0.0/16    allow
     30000                              ip4.dst == 172.18.0.2  reroute  100.64.0.4
     30000                              ip4.dst == 172.18.0.3  reroute  100.64.0.3
     30000                              ip4.dst == 172.18.0.4  reroute  100.64.0.2
     29100                  ip4.src == $VEG.8ca38ae7da18.ipv4  reroute  10.16.0.12, 10.16.0.13
     29100                   ip4.src == $VEG.8ca38ae7da18_ip4  reroute  10.16.0.12, 10.16.0.13
     29000 ip4.src == $ovn.default.kube.ovn.control.plane_ip4  reroute  100.64.0.3
     29000       ip4.src == $ovn.default.kube.ovn.worker2_ip4  reroute  100.64.0.2
     29000        ip4.src == $ovn.default.kube.ovn.worker_ip4  reroute  100.64.0.4
     29000     ip4.src == $subnet1.kube.ovn.control.plane_ip4  reroute  100.64.0.3
     29000           ip4.src == $subnet1.kube.ovn.worker2_ip4  reroute  100.64.0.2
     29000            ip4.src == $subnet1.kube.ovn.worker_ip4  reroute  100.64.0.4

可选:配置带宽限制

要限制所选 namespace 或工作负载的带宽,请设置 .spec.bandwidth.ingress.spec.bandwidth.egress。 每个字段都接受以下格式之一:

  • 非负整数或数字字符串,按 Mbps 解释。例如,2000"2000" 都表示 2000 Mbps。
  • 带有 MMiGGi 后缀的 Kubernetes quantity 字符串,按 bit/s 解释。带有后缀时支持小数值。该值会向上取整到最接近的整数 Mbps。例如,1Gi 会变为 1074 Mbps。

将某个字段省略或设置为 0,即可使该方向不受限。限制适用于每个网关实例。

NOTE

如果 .spec.replicas 大于 1,每个副本都会获得所配置的限制。 Quantity 字符串需要支持它们的 VPC Egress Gateway CRD 和 controller 版本。在滚动升级期间,请继续使用整数 Mbps 值,直到 Kube-OVN 升级完成。

以下示例将所选 namespace 的 ingress 带宽限制为 2 Gbps,egress 带宽限制为 4 Gbps:

apiVersion: kubeovn.io/v1
kind: VpcEgressGateway
metadata:
  name: gateway-bandwidth
  namespace: default
spec:
  replicas: 1
  internalSubnet: ovn-default
  externalSubnet: underlay-ext
  externalIPs:
    - 172.17.0.21
  bandwidth:
    ingress: 2G
    egress: 4G
  selectors:
    - namespaceSelector:
        matchExpressions:
          - key: kubernetes.io/metadata.name
            operator: In
            values:
              - ecommerce
              - ecommerce-test

在此示例中,方向是相对于所选 namespace 或工作负载而言的:ingress 限制从外部网络到它们的流量,egress 限制从它们到外部网络的流量。

可选:启用基于 BFD 的高可用

基于 BFD 的故障切换依赖于 VPC BFD LRP。 请按以下顺序启用。

1. 在 VPC 上启用 BFD Port

首先,在 VPC 上启用 BFD Port:

apiVersion: kubeovn.io/v1
kind: Vpc
metadata:
  name: ovn-cluster
spec:
  bfdPort:
    enabled: true
    ip: 10.255.255.255
    nodeSelector:
      matchLabels:
        kubernetes.io/os: linux
  1. 是否启用 BFD Port。
  2. BFD Port 的 IP 地址,MUST 是一个有效 IP 地址,且不得与任何其他 IP/Subnet 冲突。
  3. 用于选择以 Active-Backup 模式运行 BFD Port 的节点的 node selector。
TIP

默认情况下存在 Vpc 资源 ovn-cluster。你可以直接编辑它以启用 BFD Port。

启用 BFD Port 后,会在 OVN Logical Router 上自动创建一个专用的 BFD LRP:

$ kubectl ko nbctl show ovn-cluster
router 0c1d1e8f-4c86-4d96-88b2-c4171c7ff824 (ovn-cluster)
    port bfd@ovn-cluster
        mac: "8e:51:4b:16:3c:90"
        networks: ["10.255.255.255"]
    port ovn-cluster-join
        mac: "d2:21:17:71:77:70"
        networks: ["100.64.0.1/16"]
    port ovn-cluster-ovn-default
        mac: "d6:a3:f5:31:cd:89"
        networks: ["10.16.0.1/16"]
    port ovn-cluster-subnet1
        mac: "4a:09:aa:96:bb:f5"
        networks: ["10.17.0.1/16"]
  1. 在 OVN Logical Router 上创建的 BFD Port。

2. 在 VPC Egress Gateway 上启用 BFD

然后通过将 .spec.bfd.enabled 设置为 true 来在 VPC Egress Gateway 上启用 BFD:

apiVersion: kubeovn.io/v1
kind: VpcEgressGateway
metadata:
  name: gateway2
  namespace: default
spec:
  vpc: ovn-cluster
  replicas: 2
  internalSubnet: ovn-default
  externalSubnet: underlay-ext
  externalIPs:
    - 172.17.0.11
    - 172.17.0.12
    - 172.17.0.13
  bfd:
    enabled: true
    minRX: 100
    minTX: 100
    multiplier: 5
  policies:
    - snat: true
      ipBlocks:
        - 10.18.0.0/16
  1. Egress Gateway 所属的 VPC。
  2. Egress Gateway 实例连接到的 internal subnet。
  3. Egress Gateway 实例连接到的 external subnet。
  4. 分配给 Egress Gateway 实例的 external IP。
  5. 是否为 Egress Gateway 启用 BFD。
  6. BFD 的最小接收间隔,单位为毫秒。
  7. BFD 的最小发送间隔,单位为毫秒。
  8. BFD 的 multiplier,用于确定在判定故障前允许丢失的报文数。

此示例创建一个名为 gateway2 的 VPC Egress Gateway,包含两个副本并启用 BFD。 如果某个实例失败,BFD session 会断开,OVN 会将该路由标记为不可用,并将流量重定向到健康的实例。

故障切换检测时间取决于 BFD 设置。 使用以下公式:break time = (multiplier + 1) * max(minRX, minTX)。 在此示例配置下,故障切换检测大约为 500-600 ms。

在网络质量较差或链路抖动频繁的环境中,100 ms 的 BFD 间隔可能过于敏感。 你可以将 .spec.bfd.minRX.spec.bfd.minTX 增加到 500-1000 ms,以减少误判故障和频繁切换。 提高这些值也会增加故障切换检测时间,因此请根据稳定性和故障检测延迟之间的需求平衡进行调整。

NOTE

在故障切换期间,现有连接可能会中断并需要重新建立。新的连接仍然可以正常建立。

3. 验证 BFD 状态

检查 VPC Egress Gateway 状态:

$ kubectl get veg -n default gateway2 -o wide
NAME       VPC           REPLICAS   BFD ENABLED   EXTERNAL SUBNET   PHASE       READY   INTERNAL IPS                  EXTERNAL IPS                    WORKING NODES       AGE
gateway2   ovn-cluster   2          true          underlay-ext      Completed   true    ["10.16.0.12","10.16.0.13"]   ["172.17.0.11","172.17.0.12"]   ["node1","node2"]   58s

$ kubectl get pod -n default -l ovn.kubernetes.io/vpc-egress-gateway=gateway2 -o wide
NAME                       READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
gateway2-fcc6b8b87-8lgvx   1/1     Running   0          2m18s   10.16.0.13   node2   <none>           <none>
gateway2-fcc6b8b87-wmww6   1/1     Running   0          2m18s   10.16.0.12   node1   <none>           <none>

$ kubectl ko nbctl lr-policy-list ovn-cluster
Routing Policies
     31000                            ip4.dst == 10.16.0.0/16    allow
     31000                            ip4.dst == 10.17.0.0/16    allow
     31000                           ip4.dst == 100.64.0.0/16    allow
     30000                              ip4.dst == 172.18.0.2  reroute  100.64.0.4
     30000                              ip4.dst == 172.18.0.3  reroute  100.64.0.3
     30000                              ip4.dst == 172.18.0.4  reroute  100.64.0.2
     29100                  ip4.src == $VEG.8ca38ae7da18.ipv4  reroute  10.16.0.12, 10.16.0.13  bfd
     29100                   ip4.src == $VEG.8ca38ae7da18_ip4  reroute  10.16.0.12, 10.16.0.13  bfd
     29090                  ip4.src == $VEG.8ca38ae7da18.ipv4     drop
     29090                   ip4.src == $VEG.8ca38ae7da18_ip4     drop
     29000 ip4.src == $ovn.default.kube.ovn.control.plane_ip4  reroute  100.64.0.3
     29000       ip4.src == $ovn.default.kube.ovn.worker2_ip4  reroute  100.64.0.2
     29000        ip4.src == $ovn.default.kube.ovn.worker_ip4  reroute  100.64.0.4
     29000     ip4.src == $subnet1.kube.ovn.control.plane_ip4  reroute  100.64.0.3
     29000           ip4.src == $subnet1.kube.ovn.worker2_ip4  reroute  100.64.0.2
     29000            ip4.src == $subnet1.kube.ovn.worker_ip4  reroute  100.64.0.4

$ kubectl ko nbctl list bfd
_uuid               : 223ede10-9169-4c7d-9524-a546e24bfab5
detect_mult         : 5
dst_ip              : "10.16.0.12"
external_ids        : {af="4", vendor=kube-ovn, vpc-egress-gateway="default/gateway2"}
logical_port        : "bfd@ovn-cluster"
min_rx              : 100
min_tx              : 100
options             : {}
status              : up

_uuid               : b050c75e-2462-470b-b89c-7bd38889b758
detect_mult         : 5
dst_ip              : "10.16.0.13"
external_ids        : {af="4", vendor=kube-ovn, vpc-egress-gateway="default/gateway2"}
logical_port        : "bfd@ovn-cluster"
min_rx              : 100
min_tx              : 100
options             : {}
status              : up

然后检查 BFD sessions:

$ kubectl exec -n default gateway2-fcc6b8b87-8lgvx -c bfdd -- bfdd-control status
There are 1 sessions:
Session 1
 id=1 local=10.16.0.13 (p) remote=10.255.255.255 state=Up

$ kubectl exec -n default gateway2-fcc6b8b87-wmww6 -c bfdd -- bfdd-control status
There are 1 sessions:
Session 1
 id=1 local=10.16.0.12 (p) remote=10.255.255.255 state=Up
NOTE

如果所有网关实例都处于下线状态,由 VPC Egress Gateway 处理的出站流量将被丢弃。

可能中断流量的操作

以下操作可能会短暂中断出站流量,因为它们会删除或重建网关实例:

  1. 更改副本数量
  2. 更改配置,例如 internal 或 external IP、node selector 或 BFD 设置
  3. 如果未指定 .spec.image,则升级或降级 Kube-OVN
  4. 手动删除 Egress Gateway Pod

其他资源