Chapter 1. BGP routing


1.1. About BGP routing

To integrate BGP with MetalLB and FRR-K8s in Red Hat OpenShift Service on AWS, you can review how FRR-K8s resources model cluster routing. Migrate FRRConfiguration custom resources from metallb-system to openshift-frr-k8s when admins or third parties created them outside the MetalLB Operator.

Important

If you are using the MetalLB Operator and there are existing FRRConfiguration CRs in the metallb-system namespace created by cluster administrators or third-party cluster components other than the MetalLB Operator, you must ensure that they are copied to the openshift-frr-k8s namespace or that those third-party cluster components use the new namespace. For more information, see "Migrating FRR-K8s resources".

1.1.1. About Border Gateway Protocol (BGP) routing

To enable external routing for your cluster, configure Border Gateway Protocol (BGP) using FRRouting (FRR) and the FRR-K8s daemon. You can define routing behavior with the FRRConfiguration custom resource (CR) and ensure compatibility with the MetalLB Operator by using the required namespace and migration approach.

Red Hat OpenShift Service on AWS supports BGP routing through FRR, a free, open source internet routing protocol suite for Linux, UNIX, and similar operating systems. FRR-K8s is a Kubernetes-based daemon set that exposes a subset of the FRR API in a Kubernetes-compliant manner. As a cluster administrator, you can use the FRRConfiguration custom resource to access FRR services.

The following diagram shows a multi-tenancy environment where two namespaces exist on an Red Hat OpenShift Service on AWS node. When the OVN-Kubernetes gateway router sends traffic from a namespace to an external source, the traffic passes through the default virtual routing and forwarding (VRF) instance. BGP advertisement occurs when the FRR or OVN-Kubernetes router establishes a BGP session with the router of the cloud provider. This session ensures the router of the cloud provider knows that the node is the next-hop IP address for reaching the pod or service networks.

Figure 1.1. BGP advertisement without a VPN

Image of BGP advertisement without a VPN

The following diagram shows multiple VRF BGP instances that use VRF lite. This architecture supports only local gateway mode. VRF lite provides network virtualization by using UDNs to isolate pod traffic without incurring the heavy encapsulation typical of Multi-Protocol Label Switching (MPLS) or Ethernet Virtual Private Network (EVPN) protocols. Separate L3 links get mapped to specific VRFs, so independent BGP peering sessions route traffic to the next-hop router. Further, you can deploy this L3 mechanism to multi-cloud deployments to allow specific namespaces to exist over the network.

Figure 1.2. Multiple VRF BGP instances that use VRF lite

Image of multiple VRF BGP instances that use VRF lite

1.1.1.1. Supported platforms

BGP routing is supported on the following infrastructure types:

  • Bare metal

BGP routing requires that you have properly configured BGP for your network provider. Outages or misconfigurations of your network provider might cause disruptions to your cluster network.

The MetalLB Operator is installed as an add-on to the cluster. Deployment of the MetalLB Operator automatically enables FRR-K8s as an additional routing capability provider and uses the FRR-K8s daemon installed by this feature.

Before upgrading to 4.18, any existing FRRConfiguration in the metallb-system namespace not managed by the MetalLB operator (added by a cluster administrator or any other component) needs to be copied to the openshift-frr-k8s namespace manually, creating the namespace if necessary.

Important

If you are using the MetalLB Operator and there are existing FRRConfiguration CRs in the metallb-system namespace created by cluster administrators or third-party cluster components other than MetalLB Operator, you must:

  • Ensure that these existing FRRConfiguration CRs are copied to the openshift-frr-k8s namespace.
  • Ensure that the third-party cluster components use the new namespace for the FRRConfiguration CRs that they create.

1.1.1.3. Cluster Network Operator configuration

The Cluster Network Operator API exposes the following API field to configure BGP routing:

  • spec.additionalRoutingCapabilities: Enables deployment of the FRR-K8s daemon for the cluster, which can be used independently of route advertisements. When enabled, the FRR-K8s daemon is deployed on all nodes.

1.1.1.4. BGP routing custom resources

The following custom resources are used to configure BGP routing:

FRRConfiguration
This custom resource defines the FRR configuration for the BGP routing. This CR is namespaced.

1.1.2. Configure the FRRConfiguration CR

To customize routing behavior beyond standard MetalLB capabilities, configure the FRRConfiguration custom resource (CR).

The following reference examples demonstrate how to define specific FRRouting (FRR) parameters to enable advanced services, such as receiving routes:

The routers parameter

You can use the routers parameter to configure multiple routers, one for each Virtual Routing and Forwarding (VRF) resource. For each router, you must define the Autonomous System Number (ASN).

You can also define a list of Border Gateway Protocol (BGP) neighbors to connect to, as in the following example:

Example FRRConfiguration CR

apiVersion: frrk8s.metallb.io/v1beta1
kind: FRRConfiguration
metadata:
  name: test
  namespace: frr-k8s-system
spec:
  bgp:
    routers:
    - asn: 64512
      neighbors:
      - address: 172.30.0.3
        asn: 4200000000
        ebgpMultiHop: true
        port: 180
      - address: 172.18.0.6
        asn: 4200000000
        port: 179
# ...

The toAdvertise parameter

By default, FRR-K8s does not advertise the prefixes configured as part of a router configuration. To advertise the prefixes, you use the toAdvertise parameter.

You can advertise a subset of the prefixes, as in the following example:

Example FRRConfiguration CR

apiVersion: frrk8s.metallb.io/v1beta1
kind: FRRConfiguration
metadata:
  name: test
  namespace: frr-k8s-system
spec:
  bgp:
    routers:
    - asn: 64512
      neighbors:
      - address: 172.30.0.3
        asn: 4200000000
        ebgpMultiHop: true
        port: 180
        toAdvertise:
          allowed:
            prefixes:
            - 192.168.2.0/24
      prefixes:
        - 192.168.2.0/24
        - 192.169.2.0/24
# ...

  • allowed.prefixes: Advertises a subset of prefixes.

The following example shows you how to advertise all of the prefixes:

Example FRRConfiguration CR

apiVersion: frrk8s.metallb.io/v1beta1
kind: FRRConfiguration
metadata:
  name: test
  namespace: frr-k8s-system
spec:
  bgp:
    routers:
    - asn: 64512
      neighbors:
      - address: 172.30.0.3
        asn: 4200000000
        ebgpMultiHop: true
        port: 180
        toAdvertise:
          allowed:
            mode: all
      prefixes:
        - 192.168.2.0/24
        - 192.169.2.0/24
# ...

  • allowed.mode: Advertises all prefixes.
The toReceive parameter

By default, FRR-K8s does not process any prefixes advertised by a neighbor. You can use the toReceive parameter to process such addresses.

You can configure for a subset of the prefixes, as in this example:

Example FRRConfiguration CR

apiVersion: frrk8s.metallb.io/v1beta1
kind: FRRConfiguration
metadata:
  name: test
  namespace: frr-k8s-system
spec:
  bgp:
    routers:
    - asn: 64512
      neighbors:
      - address: 172.18.0.5
          asn: 64512
          port: 179
          toReceive:
            allowed:
              prefixes:
              - prefix: 192.168.1.0/24
              - prefix: 192.169.2.0/24
                ge: 25
                le: 28
# ...

  • prefixes: The prefix is applied if the prefix length is less than or equal to the le prefix length and greater than or equal to the ge prefix length.

The following example configures FRR to handle all the prefixes announced:

Example FRRConfiguration CR

apiVersion: frrk8s.metallb.io/v1beta1
kind: FRRConfiguration
metadata:
  name: test
  namespace: frr-k8s-system
spec:
  bgp:
    routers:
    - asn: 64512
      neighbors:
      - address: 172.18.0.5
          asn: 64512
          port: 179
          toReceive:
            allowed:
              mode: all
# ...

The bgp parameter

You can use the bgp parameter to define various BFD profiles and associate them with a neighbor. In the following example, BFD backs up the BGP session and FRR can detect link failures:

Example FRRConfiguration CR

apiVersion: frrk8s.metallb.io/v1beta1
kind: FRRConfiguration
metadata:
  name: test
  namespace: frr-k8s-system
spec:
  bgp:
    routers:
    - asn: 64512
      neighbors:
      - address: 172.30.0.3
        asn: 64512
        port: 180
        bfdProfile: defaultprofile
    bfdProfiles:
      - name: defaultprofile
# ...

The nodeSelector parameter

By default, FRR-K8s applies the configuration to all nodes where the daemon is running. You can use the nodeSelector parameter to specify the nodes to which you want to apply the configuration. For example:

Example FRRConfiguration CR

apiVersion: frrk8s.metallb.io/v1beta1
kind: FRRConfiguration
metadata:
  name: test
  namespace: frr-k8s-system
spec:
  bgp:
    routers:
    - asn: 64512
  nodeSelector:
    labelSelector:
    foo: "bar"
# ...

The interface parameter

You can use the interface parameter to configure unnumbered BGP peering by using the following example configuration:

Example FRRConfiguration CR

apiVersion: frrk8s.metallb.io/v1beta1
kind: FRRConfiguration
metadata:
  name: test
  namespace: frr-k8s-system
spec:
  bgp:
    bfdProfiles:
    - echoMode: false
      name: simple
      passiveMode: false
    routers:
    - asn: 64512
      neighbors:
      - asn: 64512
        bfdProfile: simple
        disableMP: false
        interface: net10
        port: 179
        toAdvertise:
          allowed:
            mode: filtered
            prefixes:
            - 5.5.5.5/32
        toReceive:
          allowed:
            mode: filtered
      prefixes:
      - 5.5.5.5/32
# ...

  • neighbors.interface: Activates unnumbered BGP peering.
Note

To use the interface parameter, you must establish a point-to-point, layer 2 connection between the two BGP peers. You can use unnumbered BGP peering with IPv4, IPv6, or dual-stack, but you must enable IPv6 RAs (Router Advertisements). Each interface is limited to one BGP connection.

If you use this parameter, you cannot specify a value in the spec.bgp.routers.neighbors.address parameter.

The parameters for the FRRConfiguration custom resource are described in the following table:

Table 1.1. MetalLB FRRConfiguration custom resource
ParameterTypeDescription

spec.bgp.routers

array

Specifies the routers that FRR is to configure (one per VRF).

spec.bgp.routers.asn

integer

The Autonomous System Number (ASN) to use for the local end of the session.

spec.bgp.routers.id

string

Specifies the ID of the bgp router.

spec.bgp.routers.vrf

string

Specifies the host VRF used to establish sessions from this router.

spec.bgp.routers.neighbors

array

Specifies the neighbors to establish BGP sessions with.

spec.bgp.routers.neighbors.asn

integer

Specifies the ASN to use for the remote end of the session. If you use this parameter, you cannot specify a value in the spec.bgp.routers.neighbors.dynamicASN parameter.

spec.bgp.routers.neighbors.dynamicASN

string

Detects the ASN to use for the remote end of the session without explicitly setting it. Specify internal for a neighbor with the same ASN, or external for a neighbor with a different ASN. If you use this parameter, you cannot specify a value in the spec.bgp.routers.neighbors.asn parameter.

spec.bgp.routers.neighbors.address

string

Specifies the IP address to establish the session with. If you use this parameter, you cannot specify a value in the spec.bgp.routers.neighbors.interface parameter.

spec.bgp.routers.neighbors.interface

string

Specifies the interface name to use when establishing a session. Use this parameter to configure unnumbered BGP peering. There must be a point-to-point, layer 2 connection between the two BGP peers. You can use unnumbered BGP peering with IPv4, IPv6, or dual-stack, but you must enable IPv6 RAs (Router Advertisements). Each interface is limited to one BGP connection.

spec.bgp.routers.neighbors.port

integer

Specifies the port to dial when establishing the session. Defaults to 179.

spec.bgp.routers.neighbors.password

string

Specifies the password to use for establishing the BGP session. Password and PasswordSecret are mutually exclusive.

spec.bgp.routers.neighbors.passwordSecret

string

Specifies the name of the authentication secret for the neighbor. The secret must be of type "kubernetes.io/basic-auth", and in the same namespace as the FRR-K8s daemon. The key "password" stores the password in the secret. Password and PasswordSecret are mutually exclusive.

spec.bgp.routers.neighbors.holdTime

duration

Specifies the requested BGP hold time, per RFC4271. Defaults to 180s.

spec.bgp.routers.neighbors.keepaliveTime

duration

Specifies the requested BGP keepalive time, per RFC4271. Defaults to 60s.

spec.bgp.routers.neighbors.connectTime

duration

Specifies how long BGP waits between connection attempts to a neighbor.

spec.bgp.routers.neighbors.ebgpMultiHop

boolean

Indicates if the BGPPeer is a multi-hop away.

spec.bgp.routers.neighbors.bfdProfile

string

Specifies the name of the BFD Profile to use for the BFD session associated with the BGP session. If not set, the BFD session is not set up.

spec.bgp.routers.neighbors.toAdvertise.allowed

array

Represents the list of prefixes to advertise to a neighbor, and the associated properties.

spec.bgp.routers.neighbors.toAdvertise.allowed.prefixes

string array

Specifies the list of prefixes to advertise to a neighbor. This list must match the prefixes that you define in the router.

spec.bgp.routers.neighbors.toAdvertise.allowed.mode

string

Specifies the mode to use when handling the prefixes. You can set to filtered to allow only the prefixes in the prefixes list. You can set to all to allow all the prefixes configured on the router.

spec.bgp.routers.neighbors.toAdvertise.withLocalPref

array

Specifies the prefixes associated with an advertised local preference. You must specify the prefixes associated with a local preference in the prefixes allowed to be advertised.

spec.bgp.routers.neighbors.toAdvertise.withLocalPref.prefixes

string array

Specifies the prefixes associated with the local preference.

spec.bgp.routers.neighbors.toAdvertise.withLocalPref.localPref

integer

Specifies the local preference associated with the prefixes.

spec.bgp.routers.neighbors.toAdvertise.withCommunity

array

Specifies the prefixes associated with an advertised BGP community. You must include the prefixes associated with a local preference in the list of prefixes that you want to advertise.

spec.bgp.routers.neighbors.toAdvertise.withCommunity.prefixes

string array

Specifies the prefixes associated with the community.

spec.bgp.routers.neighbors.toAdvertise.withCommunity.community

string

Specifies the community associated with the prefixes.

spec.bgp.routers.neighbors.toReceive

array

Specifies the prefixes to receive from a neighbor.

spec.bgp.routers.neighbors.toReceive.allowed

array

Specifies the information that you want to receive from a neighbor.

spec.bgp.routers.neighbors.toReceive.allowed.prefixes

array

Specifies the prefixes allowed from a neighbor.

spec.bgp.routers.neighbors.toReceive.allowed.mode

string

Specifies the mode to use when handling the prefixes. When set to filtered, only the prefixes in the prefixes list are allowed. When set to all, all the prefixes configured on the router are allowed.

spec.bgp.routers.neighbors.disableMP

boolean

Disables MP BGP to prevent it from separating IPv4 and IPv6 route exchanges into distinct BGP sessions.

spec.bgp.routers.prefixes

string array

Specifies all prefixes to advertise from this router instance.

spec.bgp.bfdProfiles

array

Specifies the list of BFD profiles to use when configuring the neighbors.

spec.bgp.bfdProfiles.name

string

The name of the BFD Profile to be referenced in other parts of the configuration.

spec.bgp.bfdProfiles.receiveInterval

integer

Specifies the minimum interval at which this system can receive control packets, in milliseconds. Defaults to 300ms.

spec.bgp.bfdProfiles.transmitInterval

integer

Specifies the minimum transmission interval, excluding jitter, that this system wants to use to send BFD control packets, in milliseconds. Defaults to 300ms.

spec.bgp.bfdProfiles.detectMultiplier

integer

Configures the detection multiplier to determine packet loss. To determine the connection loss-detection timer, multiply the remote transmission interval by this value.

spec.bgp.bfdProfiles.echoInterval

integer

Configures the minimal echo receive transmission-interval that this system can handle, in milliseconds. Defaults to 50ms.

spec.bgp.bfdProfiles.echoMode

boolean

Enables or disables the echo transmission mode. This mode is disabled by default, and not supported on multihop setups.

spec.bgp.bfdProfiles.passiveMode

boolean

Mark session as passive. A passive session does not attempt to start the connection and waits for control packets from peers before it begins replying.

spec.bgp.bfdProfiles.MinimumTtl

integer

For multihop sessions only. Configures the minimum expected TTL for an incoming BFD control packet.

spec.nodeSelector

string

Limits the nodes that attempt to apply this configuration. If specified, only those nodes whose labels match the specified selectors attempt to apply the configuration. If it is not specified, all nodes attempt to apply this configuration.

status

string

Defines the observed state of FRRConfiguration.

You can use no-overlay mode to route layer 3 pod traffic directly over the underlay network with BGP, which reduces encapsulation overhead and improves east-west performance.

No-overlay mode disables the default encapsulation for the default cluster network and uses BGP-learned routes to forward pod traffic across nodes. A cluster can run overlay and no-overlay networks at the same time.

For the default cluster network, no-overlay supports managed and unmanaged routing. With managed routing, OVN-Kubernetes creates a full-mesh BGP fabric between cluster nodes only, so no external BGP routers are required and pod routes are not advertised outside the cluster (intra-cluster traffic only). Managed routing requires nodes to be directly connected at layer 2; it is not suitable for clusters with nodes in different subnets. With unmanaged routing on the default network, you configure external BGP peers and use RouteAdvertisements custom resources (CRs) to advertise pod subnets to your existing BGP infrastructure.

For a primary network defined by a ClusterUserDefinedNetwork CR, no-overlay supports unmanaged routing only. Configure external BGP peers and RouteAdvertisements CRs for the CUDN.

Requirements
  • A bare-metal cluster that uses the OVN-Kubernetes network plugin.
  • Single-node zone interconnect mode enabled for the cluster.
  • BGP routing enabled and FRR-K8s deployed.
  • Layer 3 networks only (the default network or a primary network defined by a ClusterUserDefinedNetwork CR).
Limitations
  • No-overlay mode is not supported for layer 2 networks.
  • EgressIP, EgressService, IPsec, multicast, and multiple external gateways are not supported for no-overlay networks.
  • Switching an existing network between overlay and no-overlay modes is not supported using a ClusterUserDefinedNetwork CR.
Supported gateway modes
  • On the default cluster network, no-overlay is supported in both local gateway (LGW) mode and shared gateway (SGW) mode.
  • On a primary network defined by a ClusterUserDefinedNetwork CR, no-overlay is supported in both LGW and SGW modes.

    Important

    Pods running on a CUDN configured with NoOverlay transport mode cannot establish TCP connections to NodePort services when externalTrafficPolicy is set to Cluster and the backend pod resides on a different node than the one targeted by the request. This issue occurs regardless of whether outbound SNAT is enabled or disabled.

Border Gateway Protocol (BGP) Cloud Connector integrates Red Hat OpenShift Service on AWS with AWS Route Server allowing direct, routed connectivity to OpenShift Virtualization virtual machines (VMs) on AWS.

By using the BGP Cloud Connector, you do not need Network Address Translation (NAT).

VM workloads are often designed to require that a network interface of the VM is routable to and from an outside network on the same IP address the VM sees. Mechanisms to do this on on-premise networks, such as localnet bridges, require an external Layer 2 network. AWS Virtual Private Cloud (VPCs) operate at Layer 3.

By using the BGP Cloud Connector, you can use compute nodes as routers to pass traffic between workloads within your cluster and the VPC of the cluster. BGP Cloud Connector configures compute nodes to establish Border Gateway Protocol (BGP) peering with the AWS Route Server. BGP uses this configuration to advertise pod and VM network routes from Cluster User Defined Networks (CUDNs) directly into your AWS VPC.

BGP Cloud Connector consists of the following two core layers:

  • Cloud infrastructure layer, where the underlying AWS VPC, subnets, and AWS Route Server get provisioned alongside your cluster.
  • In-cluster Operator layer, where an Operator that manages cluster-wide and project-scoped custom resources (CRs) configure routing, BGP peering, and network interfaces.

The Operator automatically discovers your AWS Route Server topology and establishes BGP peering sessions between designated compute nodes and local subnet Route Server endpoints by generating FRRConfiguration CRs.

The Operator also automates the following required AWS-side networking configuration:

  • Managing Route Server peers dynamically as nodes scale, reboot, or undergo cluster upgrades.
  • Disabling source/destination checks on primary compute node Elastic Network Interfaces (ENIs) so BGP-enabled compute nodes can forward external traffic.

The following list details key benefits of using AWS Route Server with BGP Cloud Connector:

  • Direct, NAT-free routed connectivity between VM network interfaces and the VPC.
  • Native cloud routing integration without custom downstream implementations.
  • Compatibility with standard enterprise BGP tools and multicloud architectures.

Before you can configure BGP Cloud Connector on your cluster, you must prepare the supporting AWS infrastructure. This preparation ensures the BGP Cloud Connector discovers and peers with an AWS Route Server that already exists.

Prerequisites

  • You have an Red Hat OpenShift Service on AWS cluster running on AWS with an existing VPC.
  • You have an AWS IAM user that you use to perform this setup.

Procedure

  1. Get the OpenID Connect (OIDC) provider and AWS account ID for the cluster by entering the following commands:

    $ OIDC_PROVIDER=$(oc get authentication cluster -o jsonpath='{.spec.serviceAccountIssuer}' | sed 's|https://||')
    $ AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
  2. Create an AWS IAM permission policy for the BGP Cloud Connector Operator.

    1. Create the permission policy document file by entering the following command:

      $ cat <<EOF > operator-permission-policy.json
      {
        "Version": "2012-10-17",
        "Statement": [{
          "Effect": "Allow",
          "Action": [
            "sts:GetCallerIdentity",
            "ec2:DescribeRouteServers",
            "ec2:DescribeRouteServerEndpoints",
            "ec2:DescribeSubnets",
            "ec2:DescribeRouteServerPeers",
            "ec2:CreateRouteServerPeer",
            "ec2:DeleteRouteServerPeer",
            "ec2:CreateTags",
            "ec2:DescribeInstances",
            "ec2:ModifyNetworkInterfaceAttribute"
          ],
          "Resource": "*"
        }]
      }
      EOF
    2. Create the IAM permission policy by entering the following command:

      $ POLICY_ARN=$(aws iam create-policy \
          --policy-name bgp-cloud-connector-operator-policy \
          --policy-document file://operator-permission-policy.json \
          --query 'Policy.Arn' --output text)
  3. Create an AWS IAM role for the BGP Cloud Connector Operator:

    1. Create the trust policy document for the Operator role by entering the following command:

      $ cat <<EOF > operator-trust-policy.json
      {
        "Version": "2012-10-17",
        "Statement": [{
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "${OIDC_PROVIDER}:sub": "system:serviceaccount:bgp-cloud-connector:openshift-bgp-cloud-connector-controller-manager"
            }
          }
        }]
      }
      EOF
    2. Create the IAM role by using the trust policy by entering the following command:

      $ aws iam create-role --role-name bgp-cloud-connector-operator \
          --assume-role-policy-document file://operator-trust-policy.json
    3. Attach the permission policy to the IAM role by entering the following command:

      $ aws iam attach-role-policy \
          --role-name bgp-cloud-connector-operator \
          --policy-arn ${POLICY_ARN}
  4. Create a dedicated security group for BGP traffic in your cluster’s VPC by entering the following command:

    $ BGP_SG_ID=$(aws ec2 create-security-group \
        --group-name "bgp-peering-sg" \
        --description "Security group for BGP Cloud Connector peering traffic" \
        --vpc-id ${vpc_id} \
        --query 'GroupId' --output text)

    Replace vpc_id with the ID of the VPC of the cluster.

  5. Add rules to the security group to allow the following BGP traffic and workload traffic patterns. You can add any ports to the security group that your VMs or pods on the CUDN need for traffic. You can edit this security group at a later stage.

    Note

    If you plan to use Bidirectional Forwarding Detection (BFD), repeat the commands to allow the appropriate UDP control traffic ports,such as UDP port 3784. Restrict the --cidr range to your specific Route Server endpoint subnets if required by the security policies of your organization.

    • Allow TCP Ingress/Egress on port 179 for bidirectional BGP traffic by running the following command:

      $ aws ec2 authorize-security-group-egress --group-id ${BGP_SG_ID} --ip-permissions '[
        {"IpProtocol": "tcp", "FromPort": 179, "ToPort": 179, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "BGP"}]}
      ]'
    • Allow TCP/UDP Ingress traffic on ports 32768-60999, because bidirectional traffic originating from a VM might enter the cluster through a different compute node than the bidirectional traffic exits. Run the following command:

      $ aws ec2 authorize-security-group-ingress --group-id ${BGP_SG_ID} --ip-permissions '[
        {"IpProtocol": "tcp", "FromPort": 179, "ToPort": 179, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "BGP"}]},
        {"IpProtocol": "tcp", "FromPort": 32768, "ToPort": 60999, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "Ephemeral"}]},
        {"IpProtocol": "udp", "FromPort": 32768, "ToPort": 60999, "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "Ephemeral"}]}
      ]'
  6. Create one or more new Red Hat OpenShift Service on AWS machine pools that include the BGP security group and the required BGP router label by running the following command:

    $ rosa create machinepool \
        --cluster <cluster_name> \
        --name bgp-workers \
        --availability-zone <availability_zone> \
        --additional-security-group-ids ${BGP_SG_ID} \
        --labels "bgp_router=true" \
        --instance-type <instance_type> \
        --replicas 2

    where:

    <cluster_name>
    Specifies the name of the cluster.
    bgp-workers
    Specifies the name of the new machine pool dedicated to BGP workloads.
    <availability_zone>
    Specifies the AWS availability zone where the machine pool gets created.
    --additional-security-group-ids
    Attaches the BGP security group created in an earlier step to all compute nodes provisioned in the machine pool.
    --labels "bgp_router=true"
    Automatically labels all compute nodes in this machine pool to participate in BGP.
    <instance_type>
    Specifies the AWS instance type of the compute nodes.
    --replicas 2
    Specifies the number of compute nodes the machine pool should have.
  7. Verify that the new machine pool was created with the additional security group and label by entering the following command:

    $ rosa describe machinepool --cluster <cluster_name> bgp-workers

    Replace <cluster_name> with the name of your cluster.

  8. Confirm that the compute nodes provisioned by the machine pool inherit the bgp_router=true label by running the following command:

    $ oc get nodes -l bgp_router=true
  9. Create an AWS Route Server by entering the following command:

    $ aws ec2 create-route-server --amazon-side-asn <asn>

    Replace <asn> with the Border Gateway Protocol (BGP) Autonomous System Number (ASN) that you want the Route Server to use. Note the RouteServerId value in the command output that is required in a later step. In the example that follows, the ID is rs-0abc123456789abcd.

    {
       "RouteServer": {
           "RouteServerId": "rs-0abc123456789abcd",
           "AmazonSideAsn": 65100,
           "State": "pending",
           "PersistRoutes": "disable",
           "SnsNotificationsEnabled": false
       }
    }
  10. Associate the Route Server with the VPC of the cluster by entering the following command:

    $ aws ec2 associate-route-server --route-server-id <route_server_id> \
       --vpc-id <vpc_id>

    where:

    <route_server_id>
    Specifies the Route Server ID from an earlier step.
    <vpc_id>
    Specifies the ID of the VPC of the cluster.
  11. Find the private subnets used by the compute nodes of the cluster by entering the following command:

    $ rosa list machinepools --cluster <cluster_name>

    Replace <cluster_name> with the name of the cluster.

    Note

    From the output of the command, ignore any duplicate subnet IDs in the SUBNET column

  12. For each private subnet that contains BGP-enabled compute nodes, create Route Server endpoints, two per subnet:

    $ aws ec2 create-route-server-endpoint --route-server-id <route_server_id> \
       --subnet-id <subnet_id> && \
       aws ec2 create-route-server-endpoint --route-server-id <route_server_id> \
       --subnet-id <subnet_id>

    Replace <route_server_id> with the ID of your Route Server.

    Replace <subnet_id> with the ID of the subnet. Repeat this command for each private subnet that contains BGP-enabled compute nodes.

    Note

    AWS allows a maximum of two Route Server endpoints per subnet.

  13. Enable route propagation from the Route Server to the relevant VPC route tables.

    1. Identify the route tables associated with your VPC by entering the following command:

      $ aws ec2 describe-route-tables \
        --filters "Name=vpc-id,Values=<vpc_id>" \
        --query "RouteTables[].{RouteTableId: RouteTableId, Name: Tags[?Key=='Name'].Value | [0], Subnets: Associations[].SubnetId}" \
        --output table

      Replace <vpc_id> with the ID of the VPC for your cluster.

    2. Enable route propagation for each route table by entering the following command:

      $ aws ec2 enable-route-server-propagation --route-server-id <route_server_id> \
        --route-table-id <route_table_id>

      Replace <route_server_id> with the ID of your Route Server, and replace <route_table_id> with the ID of a route table identified in an earlier step.

      Repeat this command for all of the following route tables:

      • Compute node subnets (Minimum): Every route table associated with the private subnets containing your compute nodes.
      • External connectivity subnets (If applicable): Any route table associated with subnets that host network interfaces for external connectivity mechanisms into the VPC, such as Transit Gateway ENIs.

Verification

  • Confirm that the network ACLs for both the compute node subnet and the Route Server endpoint subnet allow this traffic. To do this task, enter the following the command. This configuration is required because network ACLs are stateless and apply in addition to security groups.

    $ aws ec2 describe-network-acls --filters \
       "Name=association.subnet-id,Values=<subnet_id>" --query \
       "NetworkAcls[].Entries"

    Replace <subnet_id> with the ID of the compute node subnet. Repeat the command for the Route Server endpoint subnet.

    In the output, confirm that both the inbound and outbound rule sets include an Allow entry for TCP port 179 between the CIDR blocks in the two subnets.

    Important

    Network ACL rules are evaluated in ascending order by rule number, and the first matching rule wins. A Deny rule with a lower rule number than your Allow rule blocks the traffic even though an Allow rule exists further down the list. If your VPC uses the default network ACL, all traffic is allowed by default and no further action is needed.

You can install the BGP Cloud Connector Operator on an Red Hat OpenShift Service on AWS cluster by using either the OpenShift CLI (oc) or the web console. After you install the Operator, you can deploy the Operator through the Operator Lifecycle Manager (OLM).

Procedure

  1. To install the BGP Cloud Connector Operator by using the OpenShift CLI (oc), complete the following steps:

    1. Create a dedicated namespace and an OperatorGroup manifest file for the BGP Cloud Connector Operator by entering the following command:

      $ oc create namespace bgp-cloud-connector
    2. Create an OperatorGroup manifest file in the dedicated namespace by entering the following command:

      $ echo '{"apiVersion":"operators.coreos.com/v1","kind":"OperatorGroup","metadata":{"name":"bgp-cloud-connector-operatorgroup","namespace":"bgp-cloud-connector"}, "spec":{"targetNamespaces":["bgp-cloud-connector"]}}' | oc apply -f -
    3. Configure AWS authentication for the Operator based on the credential mode of your cluster. The Cloud Credential Operator (CCO) automatically manages AWS credentials for the Operator based on the credential mode of your cluster.

      • STS Mode: Pass your pre-created IAM role ARN to the Operator by setting the ROLEARN environment variable in the Subscription custom resource (CR) or specifying it in the Role ARN field in the web console.

        If you are deploying the Operator manually through a Subscription CR, set the ROLEARN environment variable in your manifest:

        apiVersion: operators.coreos.com/v1alpha1
        kind: Subscription
        metadata:
          name: bgp-cloud-connector-operator
          namespace: bgp-cloud-connector
        spec:
          channel: stable
          name: bgp-cloud-connector
          source: redhat-operators
          sourceNamespace: openshift-marketplace
          config:
            env:
              - name: ROLEARN
                value: arn:aws:iam::<aws_account_id>:role/<iam_role_name>
        Note

        If you install the Operator by using the web console, the console automatically prompts you for the Role ARN and then populates ROLEARN for you.

        You must create the IAM role in AWS before setting ROLEARN. The Operator cannot generate its own IAM role. Ensure the trust policy of the role trusts the OIDC provider of your cluster.

    4. Verify that the Operator installation succeeded by entering the following command:

      $ oc get csv -n bgp-cloud-connector

      Confirm that the PHASE column displays Succeeded.

  2. To install BGP Cloud Connector Operator by using the web console, complete the following steps:

    1. Log in to the web console as a cluster administrator.
    2. Go to Ecosystem Software Catalog
    3. Search for BGP cloud connector.
    4. Click the Install button.
    5. Select bgp-cloud-connector as the namespace.
    6. Click the Install button.

After you prepare the AWS environment, configure BGP Cloud Connector so that Red Hat OpenShift Service on AWS compute nodes establish BGP peering sessions with the AWS Route Server and advertise OpenShift Virtualization virtual machine (VM) network routes.

When BGP peering establishes, the cluster advertises <pod_network_cidr> routes to the AWS Route Server by using Elastic Network Interface (ENI) IP addresses of compute nodes. Each compute node must have a matching routerNodeSelector label. The Route Server injects these routes into VPC route tables.

If ingress traffic reaches a non-target node, the Cluster User Defined Network (CUDN) transparently forwards the traffic, enabling direct, NAT-free access. If a next-hop node fails, the Route Server automatically points route tables to an alternate node.

Prerequisites

  • You have prepared the AWS environment for BGP peering.
  • You have installed the BGP Cloud Connector Operator on your cluster.
  • You have the AWS Region, Route Server ID, and an AWS autonomous system number (ASN) that you noted while preparing the AWS environment.

Procedure

  1. Create a BGPCloudConfiguration custom resource (CR) to define the cluster-wide BGP configuration:

    apiVersion: networking.openshift.io/v1beta1
    kind: BGPCloudConfiguration
    metadata:
      name: cluster
    spec:
      platform: AWS
      bgp:
        localASN: <local_asn>
        livenessDetection: bgp-keepalive
      routerNodeSelector:
        bgp_router: "true"
      aws:
        region: <aws_region>
        routeServerIDs:
          - <route_server_id>

    where:

    spec.bgp.localASN.<local_asn>
    Specifies the Autonomous System Number (ASN) for the FRRouting (FRR) router of your cluster. The <local_asn> value must be different from the Route Server ASN that you configured with --amazon-side-asn, which the Operator discovers automatically. Ensure you note the ARN of the role from the output.
    spec.routerNodeSelector.bgp_router

    Specifies the label key used in the routerNodeSelector to identify which compute nodes participate in BGP routing. Nodes that match this selector have the following characteristics:

    • Establish BGP peering sessions with Route Server Endpoints in their local subnet.
    • Act as the next-hop for BGP-advertised routes for traffic that ingresses from the VPC to the primary Cluster User Default Network (CUDN) of the workload.
    • Have source/destination checks disabled on their Elastic Network Interfaces (ENIs).

      Important

      Traffic always egresses from pods or VMs directly through their own compute node ENI. Therefore, you must apply this selector to any node where these workloads can be scheduled, not just the nodes intended to receive incoming traffic.

    spec.aws.region.<aws_region>
    Specifies the AWS region in which cloud resources get created. Replace <aws_region> with the AWS Region of your Route Server.
    spec.aws.routeServerIDs.<route_server_id>
    Specifies the Route Server ID. Replace <route_server_id> with the Route Server ID that you noted while preparing the AWS environment.
  2. Apply the updates to the BGP cloud configuration resource on your cluster by entering the following command:

    $ oc apply -f bgpcloudconfiguration.yaml
    Note

    BGPCloudConfiguration is a cluster-scoped singleton. You must provide the name cluster to the CR.

  3. Create a namespace for your workload. Use the labels that the BGP Cloud Connector requires.

    apiVersion: v1
    kind: Namespace
    metadata:
      name: <namespace_name>
      labels:
        k8s.ovn.org/primary-user-defined-network: ""
        cluster-udn: <network_name>

    Replace <namespace_name> with a name for the namespace. Replace <network_name> with the network name that you plan to use in the following step.

    Important

    You must set the k8s.ovn.org/primary-user-defined-network label when you create the namespace. Red Hat OpenShift Service on AWS admission policy prevents you from adding this label to an existing namespace.

  4. Create the Namespace object by running the following command:

    $ oc apply -f namespace.yaml
  5. Create a BGPRouting CR to declare the network to advertise over BGP:

    apiVersion: networking.openshift.io/v1beta1
    kind: BGPRouting
    metadata:
      name: <routing_name>
    spec:
      network:
        name: <network_name>
        subnets:
          - <pod_network_cidr>

    where:

    <routing_name>
    Specifies the name for the CR.
    <network_name>
    Specifies the Layer 2 ClusterUserDefinedNetwork to create. The value must be the same value that you used for cluster-udn in an earlier step.
    <pod_network_cidr>

    The CIDR block that the primary network interfaces of each VM get assigned from. For example 10.100.0.0/16. The value is set as the spec.network.layer2.subnets of the CUDN. The value must not overlap with any of the CIDRs in your VPC.

    Note

    BGPRouting resources create a Layer 2 ClusterUserDefinedNetwork based upon the name and subnets you specify. BGP Cloud Connector advertises routes for the subnets to your AWS Route Server.

    The spec.namespaceSelector.matchLabels label for ClusterUserDefinedNetwork is set to cluster-udn: <network_name> to match the namespace you created in an earlier step. The name of the CUDN is cluster-udn-<network_name>.

    Layer 2 CUDNs only allow a single IPv4 and a single IPv6 CIDR per subnet.

  6. Apply the BGPRouting CR by running the following command:

    $ oc apply -f bgprouting.yaml

Verification

  1. Confirm that both custom resources report a Ready phase by entering the following commands:

    $ oc get bgpcloudconfiguration cluster -o jsonpath='{.status.phase}'
    $ oc get bgprouting <routing_name> -o jsonpath='{.status.phase}'
  2. Optional: If either resource reports Degraded, inspect its conditions for the failure reason by running the following command:

    $ oc get bgpcloudconfiguration cluster -o jsonpath='{.status.conditions}' | jq .
  3. Confirm that the Operator generated the supporting resources by entering the following commands:

    $ oc get frrconfiguration -n openshift-frr-k8s
    $ oc get clusteruserdefinednetwork
    $ oc get routeadvertisements
  4. Deploy a virtual machine into the namespace that you created, and verify that it uses bridge binding on its network interface:

    spec:
      domain:
        devices:
          interfaces:
            - name: default
              bridge: {}
      networks:
        - name: default
          pod: {}
    Important

    Use bridge binding, not masquerade binding. masquerade binding installs nftables rules that drop inbound traffic on the user-defined network (UDN) interface, which blocks the direct connectivity that this feature provides.

  5. From an EC2 instance within the VPC, verify that you can reach the VM at its pod network IP address by entering the following command:

    $ ping <vm_pod_ip>

    Replace <vm_pod_ip> with the pod network IP address of the VM.

  6. Optional: To verify connectivity from an external network, such as an on-premises network connected over AWS Direct Connect or a VPN, first ensure that the external network can route traffic for the VM pod network into the VPC.

The AWS Route Server advertises the virtual machine (VM) pod network routes only into the route tables of the virtual private cloud (VPC) that hosts your cluster.

The Route Server does not advertise these routes to networks outside the VPC, such as an on-premise network connected over AWS Direct Connect or a VPN, or a peered VPC.

The recommended architecture is to set static routes in external networks that point pod network to the next-hops of Classless Inter-Domain Routings (CIDRs) into the VPC. The VPC can then use the routes injected by the Route Server to forward the traffic to compute nodes.

Important

Red Hat does not recommended using the BGP Cloud Connector to directly peer with routers in other networks or with services other than the Route Server. The reason for this recommendation is that when using platform: manual, the list of peers do not get updates as compute nodes join or leave the cluster.

Configure external connectivity so that both of the following conditions are met:

  • The external network has a route for the VM <pod_network_cidr> whose next hop lands the traffic inside the VPC. For example, if the external network is a VPC joined to the VPC of the cluster through a Transit Gateway, the external network should have a route whose CIDR block matches a BGPRouting.spec.network.subnets entry and whose target is the Transit Gateway. You can add this route statically or by propagating the route through your dynamic routing configuration.
  • No NAT device is placed in the path between the external host and the VM, because the VM must be reachable at its pod network IP address.

1.2. Enabling BGP routing

To support dynamic route advertisement and integration with external network infrastructure, you can enable Border Gateway Protocol (BGP) routing for your cluster as a cluster administrator.

As a cluster administrator, you can enable OVN-Kubernetes BGP routing support for your cluster.

To allow external network integration and route advertisement on supported infrastructure, you can enable Border Gateway Protocol (BGP) routing for your cluster by configuring the cluster network to use an FRR-based dynamic routing provider.

As a cluster administrator, you can enable BGP routing support for your cluster on bare-metal infrastructure.

If you are using BGP routing in conjunction with the MetalLB Operator, the necessary BGP routing support is enabled automatically. You do not need to manually enable BGP routing support.

Prerequisites

  • You have installed the OpenShift CLI (oc).
  • You are logged in to the cluster as a user with the cluster-admin role.
  • The cluster is installed on compatible infrastructure.

Procedure

  • To enable a dynamic routing provider, enter the following command:

    $ oc patch Network.operator.openshift.io/cluster --type=merge -p '{
      "spec": {
        "additionalRoutingCapabilities": {
          "providers": ["FRR"]
        }
      }
    }'

1.3. Disabling BGP routing

To stop external route advertisement and restore standard cluster networking behavior, disable OVN-Kubernetes Border Gateway Protocol (BGP) routing.

As a cluster administrator, you can disable OVN-Kubernetes BGP routing support for your cluster.

Disable Border Gateway Protocol (BGP) routing for your cluster by removing additional routing capabilities from the network configuration.

As a cluster administrator, you can disable BGP routing support for your cluster on bare-metal infrastructure.

Prerequisites

  • You have installed the OpenShift CLI (oc).
  • You are logged in to the cluster as a user with the cluster-admin role.
  • The cluster is installed on compatible infrastructure.

Procedure

  • To disable dynamic routing, enter the following command:

    $ oc patch Network.operator.openshift.io/cluster --type=merge -p '{
      "spec": { "additionalRoutingCapabilities": null }
    }'
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat Documentation

Legal Notice

Theme

© 2026 Red Hat
Back to top