High availability

Active/Active clustering

Route health injection Jump to heading

Use Route Health Injection to set up a cluster of HAProxy ALOHA instances that receive traffic simultaneously.

The Route Health Injection (RHI) service interacts with the BIRD Internet Routing Daemon to start or stop the flow of traffic to this HAProxy ALOHA instance depending on the health of the network and your load balanced servers. RHI is useful for scaling out an HAProxy ALOHA cluster in an active/active manner, ensuring high availability by relying on well established routing network protocols.

The RHI service adds this HAProxy ALOHA instance as a route in BIRD’s configuration using a custom route table named volatile. BIRD then broadcasts these routes to peer routers using the BGP, RIP, or OSPF protocol. If either a virtual service or a server farm is down, then the RHI service removes the route from the volatile table, notifying BIRD to stop advertising this HAProxy ALOHA instance as a route on the network, diverting the flow of traffic to the other HAProxy ALOHA instance in the active-active cluster. You can configure ECMP on your router to load balance traffic to both HAProxy ALOHA instances via the advertised routes.

RHI Diagram

Configure route health injection Jump to heading

  1. Set transparent mode on your bound IP address.

    If you are using Layer 4 load balancing, then transparent mode is implicit and you can skip this step.

    If you are using Layer 7 load balancing, then select the LB Layer7 tab and:

    • in the frontend section, change the addresses on the bind lines so that they use a specific IP address instead of 0.0.0.0. The IP address should be a new address that is not assigned to one of the network interfaces.
    • add the transparent parameter to the bind lines. This indicates that IP address should be bound even though it does not belong to the local machine. Packets targeting this address will be intercepted as if the address were locally configured.
    haproxy
    frontend webservice
    bind 192.168.1.10:80 name http transparent
    bind 192.168.1.10:443 name https transparent ssl crt default
    haproxy
    frontend webservice
    bind 192.168.1.10:80 name http transparent
    bind 192.168.1.10:443 name https transparent ssl crt default

    Click OK and then Apply to save the changes.

    Each HAProxy ALOHA instance should be assigned the same IP address. Later, consult your router’s documentation for how to configure ECMP to distribute traffic to both HAProxy ALOHA instances at that address.

  2. Start the BIRD services.

    Select the Services tab, then click the start service button on the bird service and, optionally, bird6 service. The former is the IPv4 version of BIRD, while the latter is for IPv6.

  3. Configure BIRD for BGP or OSPF, which are used to advertise routes to peer routers.

    • Click the advanced mode link at the bottom of the screen.

    • Click the Edit bird configuration button on the bird service row.

    • Edit the configuration. Add a section for either BGP or OSPF, depending on which protocol you intend to use for advertising routes to peers. Within it, add an export line that advertises routes from the volatile table, vol1.

      An example BGP configuration section:

      text
      protocol bgp r1 {
      local 192.168.0.101 as 65001;
      neighbor 192.168.0.1 as 65001;
      graceful restart on;
      import none;
      # advertise the IP route
      export where proto = "vol1";
      }
      text
      protocol bgp r1 {
      local 192.168.0.101 as 65001;
      neighbor 192.168.0.1 as 65001;
      graceful restart on;
      import none;
      # advertise the IP route
      export where proto = "vol1";
      }

      In this example:

      • the local directive refers to the IP address assigned to this HAProxy ALOHA instance’s network interface and assigns the Autonomous System Number 65001.
      • the neighbor directive refers to the layer 3 device, such as the gateway router, with which we are establishing a BGP session.

      An example OSPF configuration section:

      text
      protocol ospf anycast {
      tick 2;
      import none;
      # advertise the IP route
      export where proto = "vol1";
      area 0.0.0.0 {
      stub no;
      interface "eth0" {
      hello 10;
      retransmit 6;
      cost 10;
      transmit delay 5;
      dead count 4;
      wait 50;
      type broadcast;
      };
      };
      }
      text
      protocol ospf anycast {
      tick 2;
      import none;
      # advertise the IP route
      export where proto = "vol1";
      area 0.0.0.0 {
      stub no;
      interface "eth0" {
      hello 10;
      retransmit 6;
      cost 10;
      transmit delay 5;
      dead count 4;
      wait 50;
      type broadcast;
      };
      };
      }
    • Save the configuration. Click OK.

    • Close the configuration editor.

    • Click the restart service button on the bird row.

    Repeat these steps for the bird6 service if using IPv6.

  4. Configure the RHI service.

    • Click the advanced mode link at the bottom of the Services screen.

    • Click the Edit rhi configuration button on the rhi service row. The Configuration text area appears.

      text
      # This is an example configuration file
      #
      # 192.168.1.30, 2002:2000::1 = any(b:webfarm)
      #
      # 10.33.0.0/16, 2002:2002::0/16 = any(f:webservice)
      #
      text
      # This is an example configuration file
      #
      # 192.168.1.30, 2002:2000::1 = any(b:webfarm)
      #
      # 10.33.0.0/16, 2002:2002::0/16 = any(f:webservice)
      #

      This file contains a list of routes that the RHI service should add to BIRD, but only if a given rule returns true; a rule checks the status of one or more virtual services or server farms to see if they are up or down. A server farm is treated as down if all servers fail their health checks or if you manually disable the servers. A virtual service is down if you disable it manually.

      For example, the following line uses the all rule to announce the 192.168.1.10/32 IP only when both the be_static and be_app server farms are up and running. When the condition is false, the IP is removed from the list of advertised routes:

      text
      192.168.1.10/32 = all(b:be_static,b:be_app)
      text
      192.168.1.10/32 = all(b:be_static,b:be_app)

      Or, the following line uses the any rule to advertise the IP if either the be_app or be_app2 farms are up and running:

      text
      192.168.1.10/32 = any(b:be_app,b:be_app2)
      text
      192.168.1.10/32 = any(b:be_app,b:be_app2)
    • Save the configuration. Click OK.

    • Close the configuration editor.

    • Click the apply new configuration button on the rhi row.

    • Click the restart service button on the rhi row.

  5. Verify that RHI added a route to BIRD by logging into HAProxy ALOHA CLI and running the birdc show route command. The IP should display.

    nix
    sudo birdc show route
    nix
    sudo birdc show route
    output
    text
    192.168.1.10/32 dev auto [vol1 19.54:40] * (0)
    output
    text
    192.168.1.10/32 dev auto [vol1 19.54:40] * (0)

    When you disable all servers in the farm, the command should not return this route.

  6. Configure ECMP on your peer router to distribute traffic to this IP.

  7. To make your changes persistent after a reboot, click the Setup tab. Then click Save under Configuration.

Volatile table Jump to heading

BIRD stores routes in routing tables, with each table associated with a particular protocol such as BGP or OSPF. HAProxy ALOHA adds its own table named volatile, which allows it to add routes to BIRD dynamically.

To see the volatile table definition, edit the BIRD configuration.

  1. Select the Services tab, then click the advanced mode link at the bottom of the screen.

  2. Click the Edit bird configuration button on the bird service row.

  3. In the Configuration text area, scroll down to the protocol volatile section.

    text
    protocol volatile vol1 {
    # gateway <ip>
    }
    text
    protocol volatile vol1 {
    # gateway <ip>
    }

    By default, BIRD announces routes through the gateway configured on the network interface, but you can specify a different network gateway by uncommenting the gateway directive and typing its IP address.

    For example:

    text
    protocol volatile vol1 {
    gateway 192.168.1.244
    }
    text
    protocol volatile vol1 {
    gateway 192.168.1.244
    }
  4. You can add more volatile tables to support advertising routes for different virtual services:

    text
    protocol volatile vol1 {
    }
    protocol volatile vol2 {
    }
    text
    protocol volatile vol1 {
    }
    protocol volatile vol2 {
    }

    Then, prefix each route in the rhi service’s configuration with a table’s name:

    text
    vol1%192.168.1.10/32 = all(b:be_static,b:be_app)
    vol2%192.168.1.11/32 = any(b:k8s_servers)
    text
    vol1%192.168.1.10/32 = all(b:be_static,b:be_app)
    vol2%192.168.1.11/32 = any(b:k8s_servers)
  5. To make your changes persistent after a reboot, click the Setup tab. Then click Save under Configuration.

Rules syntax Jump to heading

This section describes the syntax of the RHI configuration file.

text
<network>[,<network>,[...]] = <agg>(<b:|f:><name>[,<b:|f:><name>,[...]])
text
<network>[,<network>,[...]] = <agg>(<b:|f:><name>[,<b:|f:><name>,[...]])

The terms are as follows:

Term Description
<network> [%<protoname>]{<ipv4>,<ipv6>}[/<mask>]
Specify an IPv4 or IPv6 CIDR subnet or list of several comma-delimited subnets. If you do not specify any subnet mask, RHI applies the /32 mask. For advanced configuration, you can supply the name of a volatile table in the %<protoname> section (default is vol1).
<agg> Aggregation function, one of:
- all returns true if all listed proxies are active
- any returns true if at least one of the proxies listed is active
- never returns false always, for debugging purposes
- always returns true always, for debugging purposes.
<b:|f:> Prefix of either b for backend (server farm) or f for frontend (virtual service).
<name> Name of the virtual service or server farm.

See also Jump to heading

Do you have any suggestions on how we can improve the content of this page?