Package: anycastd
anycastdanycastdfunctions as a daemon managing the announcement of network prefixes employed by redundant services using multiple backends that share a common set of service prefixes.
Each prefix is announced individually to the network, forming a load-balancing strategy with redundancy, commonly referred to as Anycast.
This tool ensures that service prefixes are exclusively announced when all underlying service components are confirmed to be in a healthy state.
By doing so,anycastdprevents the attraction of traffic to service instances that may be malfunctioning, avoiding service diruption.Table of ContentsUsage ExampleServicesPrefixesFRRoutingHealth ChecksCabourotteConfigurationSchemaUsage ExampleIn the following example, we will useanycastdto manage the prefixes of two dual-stacked services commonly run on the same host.FRRoutingis used to announce the prefixes of both services which are health checked throughCabourotte.anycastdconfigurationTo configure the two services inanycastd, we create the/etc/anycastd/config.tomlconfiguration file with the following contents.[services.dns]prefixes.frrouting=["2001:db8::b19:bad:53","203.0.113.53"]checks.cabourotte=["dns"][services.ntp]prefixes.frrouting=[{"prefix"="2001:db8::123:7e11:713e","vrf"="123"},{"prefix"="203.0.113.123","vrf"="123"},]checks.cabourotte=[{"name"="ntp_v6","interval"=1},{"name"="ntp_v4","interval"=1},]The first service, aptly named "dns", simply configures a DNS resolver service that announces the prefixes2001:db8::b19:bad:53/128&203.0.113.53/32throughFRRoutingas long as theCabourottehealth checkdnsis reported as healthy.The second service, "ntp" is similar in functionality, although its configuration is a bit more verbose. Rather than omitting values that have a preconfigured default, aVRFas well as a health check interval are explicitly specified.FRRouting configurationNext, we need to configureFRRoutingso thatanycastdcan add and remove prefixes based on the services health checks. To do this, we create the/etc/frr/frr.confwith the following minimal configuration.!
router bgp 65536
 bgp router-id 203.0.113.179
 neighbor unnumbered peer-group
 neighbor unnumbered remote-as external
 neighbor unnumbered capability extended-nexthop
 neighbor eth0 interface peer-group unnumbered
 !
 address-family ipv4 unicast
  redistribute static
 !
 address-family ipv6 unicast
  redistribute static
  neighbor fabric activate
  neighbor fabric nexthop-local unchanged
!This creates a single unnumbered BGP session over which we can route the service prefixes.
The most important statement here isredistribute staticfor both IPv4 and IPv6, instructingFRRoutingto redistribute the static routes containing the service prefixes that will later be created byanycastd.Cabourotte configurationThe last thing we have to configure isCabourotte, which performs the actual health checks. We create the following/etc/cabourotte/config.yml.---http:host:127.0.0.1port:9013dns-checks:# Assumes that the DNS service is used as system wide resolver.-name:dnsdomain:check.localtimeout:1sinterval:5sexpected-ips:["2001:db8::15:600d"]command-checks:-name:ntp_v6timeout:3sinterval:5scommand:ntpdatearguments:["-q","2001:db8::123:7e11:713e"]-name:ntp_v4timeout:3sinterval:5scommand:ntpdatearguments:["-q","203.0.113.123"]This sets up two fairly rudimentary health checks. The first renders healthy if a request to the DNS service for thecheck.localname returns the IPv6 address2001:db8::15:600din the form of anAAAArecord. The other two checks,ntp_v6andntp_v4use thentpdateCLI utility to determine if a date is returned by the NTP service.Starting the serviceTo finish up, we need to start our services. For this example we assume that both services as well asCabourotteare run usingsystemdwhileanycastdis run directly for the purposes of this example.So, to start the DNS, NTP andCabourotteservices we run$systemctlstartdns.servicentp.servicecabourotte.serviceAfter which we can startanycastditself.$anycastd[2024-01-09T16:20:00ZINFOanycastd]Readingconfigurationfrom/etc/anycastd/config.toml.
......ServicesServices are the main unit of abstraction withinanycastdand are used to form a logical relationship between health checks and network prefixes containing IP addresses related to the underlying application represented by the service. They work by continuously monitoring defined health checks and announcing/denouncing their prefixes based on
the combination of check results using the logic described below.┌─[Service]─────────────┐                        ┌──────────┐
│                       │                   ┌──> │ HLTH CHK │
│           ┌───────────────────────────────┤    └──────────┘
│ IF healthy•:          │                   │    ┌──────────┐
│     announce prefixes │                   ├──> │ HLTH CHK │
│ ELSE:           •─────────────────────┐   │    └──────────┘
│     denounce prefixes │               │   │    ┌──────────┐
└───────────────────────┘               │   └──> │ HLTH CHK │
                                        │        └──────────┘
                                        │
┌─[Routing Daemon]────────────────┐     │
│ ┌──────────────────────────┐    │     │
│ │ Prefix                   │ <────────┤
│ │ 2001:db8::b19:bad:53/128 │    │     │
│ └──────────────────────────┘    │     │
│ ┌──────────────────────────┐    │     │
│ │ Prefix                   │ <────────┘
│ │ 203.0.113.53/32          │    │
│ └──────────────────────────┘    │
└─────────────────────────────────┘PrefixesRepresents a BGP network prefix that can be announced or denounced as part of the service.
Typically, these are networks containing "service IPs", meaning the IP addresses exposed by a particular service, serving as the points of contact for clients to make requests while being completely agnostic to the specifics of anycast.anycastddoes not come with its own BGP implementation, but rather aims to provide abstractions
that interface with commonly used BGP daemons.Supported BGP daemons along with their configuration options are described below.FRRoutingFree Range Routing,FRRouting, or simply FRR is a free and open source Internet routing protocol suite for Linux and Unix platforms.
Amongst others, it provides a BGP implementation that can be used to announce BGP service prefixes dynamically.OptionsOptionDescriptionDefaultExamplesprefix(required)The network prefix to create when healthy.null2001:db8:4:387b::/64192.0.2.240/282001:db8::b19:bad:53vrfA VRF to create the prefix in. If omitted, the default VRF is used.NoneEDGEvtyshThe path to the vtysh binary used to configure FRRouting./usr/bin/vtysh/usr/local/bin/vtyshHealth ChecksAssessments on individual components constituting the service to ascertain the overall operational status of the service.
A service is considered healthy as a whole if all of its health checks report a healthy status. Possible health check types along with their configuration options are described below.CabourotteCabourotteis a general purpose healthchecking tool written in Golang that can be configured to execute checks, exposing their results via API.OptionsOptionDescriptionDefaultExamplesname(required)The name of the health check, as defined inCabourotte.nullanycast-dnsurlThe base URL of the Cabourotte API.http://127.0.0.1:9013https:://healthz.localintervalThe interval in seconds at which the health check should be executed.52Configurationanycastdcan be configured using a TOML configuration file located at/etc/anycastd/config.toml, or a path specified through the--configurationparameter.
For a quick primer on TOML, seeA Quick Tour of TOML.Schema[services]# A definition of services to be managed by `anycastd`.[services.<service-name>]# A service with a unique and recognizable name.[[prefixes.<prefix-type>]]# A prefix of the specified type.# Options related to the specified prefix type.[[checks.<check-type>]]# A check of the specified type.# Options related to the specified check type.