anycastd


Nameanycastd JSON
Version 0.1.10 PyPI version JSON
download
home_pageNone
SummaryA daemon to manage anycasted services based on status checks.
upload_time2024-03-27 16:58:19
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseApache-2.0
keywords anycast bgp dns frrouting monitoring networking infrastructure routing healthcheck
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <h1 align="center"><code>anycastd</code></h1>

<div align="center">
  <a href="https://github.com/gecio/anycastd/actions">
    <img src="https://github.com/gecio/anycastd/workflows/CI/badge.svg" alt="CI status">
  </a>
  <a href="https://github.com/astral-sh/ruff">
    <img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="ruff">
  </a>
  <a href="https://github.com/python/mypy">
    <img src="https://img.shields.io/badge/Types-Mypy-blue.svg" alt="typecheck">
  </a>
  <a>
    <img src="https://img.shields.io/badge/v3.11+-black?style=flat&color=FFFF00&label=Python" alt="python version">
  </a>
  <a href="https://pdm.fming.dev">
    <img src="https://img.shields.io/badge/pdm-managed-blueviolet" alt="pdm">
  </a>
</div>
<br>

`anycastd` functions 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, `anycastd` prevents the attraction of traffic to service instances that may be malfunctioning, avoiding service diruption.

## Table of Contents

- [Usage Example](#usage-example)
- [Services](#services)
  - [Prefixes](#prefixes)
    - [FRRouting](#frrouting)
  - [Health Checks](#health-checks)
    - [Cabourotte](#cabourotte)
- [Configuration](#configuration)
  - [Schema](#schema)

## Usage Example

In the following example, we will use `anycastd` to manage the prefixes of two dual-stacked services commonly run on the same host. [FRRouting] is used to announce the prefixes of both services which are health checked through [Cabourotte].

### `anycastd` configuration

To configure the two services in `anycastd`, we create the `/etc/anycastd/config.toml` configuration file with the following contents.

```toml
[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 prefixes `2001:db8::b19:bad:53/128` & `203.0.113.53/32` through [FRRouting] as long as the [Cabourotte] health check `dns` is 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, a [VRF] as well as a health check interval are explicitly specified.

### FRRouting configuration

Next, we need to configure [FRRouting] so that `anycastd` can add and remove prefixes based on the services health checks. To do this, we create the `/etc/frr/frr.conf` with 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
!
router bgp 65537 vrf 123
 bgp router-id 203.0.113.181
 neighbor unnumbered peer-group
 neighbor unnumbered remote-as external
 neighbor unnumbered capability extended-nexthop
 neighbor eth1 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 two BGP instances, `AS65536` in the default [VRF] and `AS65537` in [VRF] `123`.
Both of them have a single unnumbered session that will be used to advertise the service prefixes.
The most important statement here is `redistribute static` for both IPv4 and IPv6, instructing [FRRouting] to redistribute the static routes containing the service prefixes that will later be created by `anycastd`.

### Cabourotte configuration

The last thing we have to configure is [Cabourotte], which performs the actual health checks. We create the following `/etc/cabourotte/config.yml`.

```yaml
---
http:
  host: 127.0.0.1
  port: 9013

dns-checks:
  # Assumes that the DNS service is used as system wide resolver.
  - name: dns
    domain: check.local
    timeout: 1s
    interval: 5s
    expected-ips: ["2001:db8::15:600d"]

command-checks:
  - name: ntp_v6
    timeout: 3s
    interval: 5s
    command: ntpdate
    arguments: ["-q", "2001:db8::123:7e11:713e"]
  - name: ntp_v4
    timeout: 3s
    interval: 5s
    command: ntpdate
    arguments: ["-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 the `check.local` name returns the IPv6 address `2001:db8::15:600d` in the form of an `AAAA` record. The other two checks, `ntp_v6` and `ntp_v4` use the `ntpdate` CLI utility to determine if a date is returned by the NTP service.

### Starting services

To finish up, we need to start our services. For this example we assume that both services as well as [Cabourotte] are run using [systemd] while `anycastd` is run directly for the purposes of this example.

So, to start the DNS, NTP and [Cabourotte] services we run

```sh
$ systemctl start dns.service ntp.service cabourotte.service
```

After which we can start `anycastd` itself.

```sh
$ anycastd run
2024-03-25T15:17:23.783539Z [info     ] Reading configuration from /etc/anycastd/config.toml. config_path=/etc/anycastd/config.toml
2024-03-25T15:17:23.785613Z [info     ] Starting service "dns".      service_health_checks=['dns'] service_healthy=False service_name=dns service_prefixes=['2001:db8::b19:bad:53', '203.0.113.53']
2024-03-25T15:17:23.785613Z [info     ] Starting service "ntp".      service_health_checks=['ntp_v4', 'ntp_v6'] service_healthy=False service_name=ntp service_prefixes=['2001:db8::123:7e11:713e', '203.0.113.123']
2024-03-25T15:17:23.797760Z [info     ] Service "dns" is now considered healthy, announcing related prefixes. service_health_checks=['dns'] service_healthy=True service_name=dns service_prefixes=['2001:db8::b19:bad:53', '203.0.113.53']
2024-03-25T15:17:23.812260Z [info     ] Service "ntp" is now considered healthy, announcing related prefixes. service_health_checks=['ntp_v4', 'ntp_v6'] service_healthy=True service_name=ntp service_prefixes=['2001:db8::123:7e11:713e', '203.0.113.123']
```

`anycastd` will execute the health checks and, since all of them pass, announce the configured service IPs, which we can verify by looking at the new [FRRouting] running configuration.

```diff
@@ -7,9 +7,11 @@
  neighbor eth0 interface peer-group unnumbered
  !
  address-family ipv4 unicast
+  network 203.0.113.53/32
   redistribute static
  !
  address-family ipv6 unicast
+  network 2001:db8::b19:bad:53/128
   redistribute static
   neighbor fabric activate
   neighbor fabric nexthop-local unchanged
@@ -22,9 +24,11 @@
  neighbor eth1 interface peer-group unnumbered
  !
  address-family ipv4 unicast
+  network 203.0.113.123/32
   redistribute static
  !
  address-family ipv6 unicast
+  network 2001:db8::123:7e11:713e/128
   redistribute static
   neighbor fabric activate
   neighbor fabric nexthop-local unchanged
```

### Stopping services

`anycastd` will keep prefixes announced as long as health checks pass.
To stop announcing prefixes, even though the underlying services are healthy, for example to perform maintenance,
simply stop `anycastd`, causing all service prefixes to be denounced.

```sh
^C
2024-03-25T15:20:29.738135Z [info     ] Received SIGINT, terminating.
2024-03-25T15:20:29.817023Z [info     ] Service "dns" terminated.    service=dns
2024-03-25T15:20:29.819003Z [info     ] Service "ntp" terminated.    service=ntp
```

## Services

Services are the main unit of abstraction within `anycastd` and 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          │    │
│ └──────────────────────────┘    │
└─────────────────────────────────┘
```

### Prefixes

Represents 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.

**`anycastd` does 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.

---

#### FRRouting

Free 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.

##### Options

| Option                     | Description                                                         | Default          | Examples                                                                 |
| -------------------------- | ------------------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------ |
| **prefix** <br> (required) | The network prefix to create when healthy.                          | `null`           | `2001:db8:4:387b::/64` <br> `192.0.2.240/28` <br> `2001:db8::b19:bad:53` |
| _vrf_                      | A VRF to create the prefix in. If omitted, the default VRF is used. | `None`           | `EDGE`                                                                   |
| _vtysh_                    | The path to the vtysh binary used to configure FRRouting.           | `/usr/bin/vtysh` | `/usr/local/bin/vtysh`                                                   |

### Health Checks

Assessments 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.

---

#### Cabourotte

[Cabourotte] is a general purpose healthchecking tool written in Golang that can be configured to execute checks, exposing their results via API.

##### Options

| Option                   | Description                                                           | Default                 | Examples                 |
| ------------------------ | --------------------------------------------------------------------- | ----------------------- | ------------------------ |
| **name** <br> (required) | The name of the health check, as defined in [Cabourotte].             | `null`                  | `anycast-dns`            |
| _url_                    | The base URL of the Cabourotte API.                                   | `http://127.0.0.1:9013` | `https:://healthz.local` |
| _interval_               | The interval in seconds at which the health check should be executed. | `5`                     | `2`                      |

---

## Configuration

`anycastd` can be configured using a TOML configuration file located at `/etc/anycastd/config.toml`, or a path specified through the `--configuration` parameter.
For a quick primer on TOML, see [A Quick Tour of TOML](https://toml.io).

### Schema

```toml
[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.
```

[Anycast]: https://en.wikipedia.org/wiki/Anycast
[FRRouting]: https://github.com/FRRouting/frr
[Cabourotte]: https://github.com/appclacks/cabourotte
[VRF]: https://en.wikipedia.org/wiki/Virtual_routing_and_forwarding
[systemd]: https://systemd.io/

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "anycastd",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": null,
    "keywords": "anycast bgp dns frrouting monitoring networking infrastructure routing healthcheck",
    "author": null,
    "author_email": "Marvin Vogt <m@rvinvogt.com>",
    "download_url": "https://files.pythonhosted.org/packages/cc/7d/b6be7280b461313904daaea7cd08d55196fed7852ce54ab956f56a434fff/anycastd-0.1.10.tar.gz",
    "platform": null,
    "description": "<h1 align=\"center\"><code>anycastd</code></h1>\n\n<div align=\"center\">\n  <a href=\"https://github.com/gecio/anycastd/actions\">\n    <img src=\"https://github.com/gecio/anycastd/workflows/CI/badge.svg\" alt=\"CI status\">\n  </a>\n  <a href=\"https://github.com/astral-sh/ruff\">\n    <img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"ruff\">\n  </a>\n  <a href=\"https://github.com/python/mypy\">\n    <img src=\"https://img.shields.io/badge/Types-Mypy-blue.svg\" alt=\"typecheck\">\n  </a>\n  <a>\n    <img src=\"https://img.shields.io/badge/v3.11+-black?style=flat&color=FFFF00&label=Python\" alt=\"python version\">\n  </a>\n  <a href=\"https://pdm.fming.dev\">\n    <img src=\"https://img.shields.io/badge/pdm-managed-blueviolet\" alt=\"pdm\">\n  </a>\n</div>\n<br>\n\n`anycastd` functions as a daemon managing the announcement of network prefixes employed by redundant services using multiple backends that share a common set of service prefixes.\nEach prefix is announced individually to the network, forming a load-balancing strategy with redundancy, commonly referred to as Anycast.\nThis tool ensures that service prefixes are exclusively announced when all underlying service components are confirmed to be in a healthy state.\nBy doing so, `anycastd` prevents the attraction of traffic to service instances that may be malfunctioning, avoiding service diruption.\n\n## Table of Contents\n\n- [Usage Example](#usage-example)\n- [Services](#services)\n  - [Prefixes](#prefixes)\n    - [FRRouting](#frrouting)\n  - [Health Checks](#health-checks)\n    - [Cabourotte](#cabourotte)\n- [Configuration](#configuration)\n  - [Schema](#schema)\n\n## Usage Example\n\nIn the following example, we will use `anycastd` to manage the prefixes of two dual-stacked services commonly run on the same host. [FRRouting] is used to announce the prefixes of both services which are health checked through [Cabourotte].\n\n### `anycastd` configuration\n\nTo configure the two services in `anycastd`, we create the `/etc/anycastd/config.toml` configuration file with the following contents.\n\n```toml\n[services.dns]\nprefixes.frrouting = [\"2001:db8::b19:bad:53\", \"203.0.113.53\"]\nchecks.cabourotte = [\"dns\"]\n\n[services.ntp]\nprefixes.frrouting = [\n    { \"prefix\" = \"2001:db8::123:7e11:713e\", \"vrf\" = \"123\" },\n    { \"prefix\" = \"203.0.113.123\", \"vrf\" = \"123\" },\n]\nchecks.cabourotte = [\n    { \"name\" = \"ntp_v6\", \"interval\" = 1 },\n    { \"name\" = \"ntp_v4\", \"interval\" = 1 },\n]\n```\n\nThe first service, aptly named \"dns\", simply configures a DNS resolver service that announces the prefixes `2001:db8::b19:bad:53/128` & `203.0.113.53/32` through [FRRouting] as long as the [Cabourotte] health check `dns` is reported as healthy.\n\nThe second service, \"ntp\" is similar in functionality, although its configuration is a bit more verbose. Rather than omitting values that have a preconfigured default, a [VRF] as well as a health check interval are explicitly specified.\n\n### FRRouting configuration\n\nNext, we need to configure [FRRouting] so that `anycastd` can add and remove prefixes based on the services health checks. To do this, we create the `/etc/frr/frr.conf` with the following minimal configuration.\n\n```\n!\nrouter bgp 65536\n bgp router-id 203.0.113.179\n neighbor unnumbered peer-group\n neighbor unnumbered remote-as external\n neighbor unnumbered capability extended-nexthop\n neighbor eth0 interface peer-group unnumbered\n !\n address-family ipv4 unicast\n  redistribute static\n !\n address-family ipv6 unicast\n  redistribute static\n  neighbor fabric activate\n  neighbor fabric nexthop-local unchanged\n!\nrouter bgp 65537 vrf 123\n bgp router-id 203.0.113.181\n neighbor unnumbered peer-group\n neighbor unnumbered remote-as external\n neighbor unnumbered capability extended-nexthop\n neighbor eth1 interface peer-group unnumbered\n !\n address-family ipv4 unicast\n  redistribute static\n !\n address-family ipv6 unicast\n  redistribute static\n  neighbor fabric activate\n  neighbor fabric nexthop-local unchanged\n!\n```\n\nThis creates two BGP instances, `AS65536` in the default [VRF] and `AS65537` in [VRF] `123`.\nBoth of them have a single unnumbered session that will be used to advertise the service prefixes.\nThe most important statement here is `redistribute static` for both IPv4 and IPv6, instructing [FRRouting] to redistribute the static routes containing the service prefixes that will later be created by `anycastd`.\n\n### Cabourotte configuration\n\nThe last thing we have to configure is [Cabourotte], which performs the actual health checks. We create the following `/etc/cabourotte/config.yml`.\n\n```yaml\n---\nhttp:\n  host: 127.0.0.1\n  port: 9013\n\ndns-checks:\n  # Assumes that the DNS service is used as system wide resolver.\n  - name: dns\n    domain: check.local\n    timeout: 1s\n    interval: 5s\n    expected-ips: [\"2001:db8::15:600d\"]\n\ncommand-checks:\n  - name: ntp_v6\n    timeout: 3s\n    interval: 5s\n    command: ntpdate\n    arguments: [\"-q\", \"2001:db8::123:7e11:713e\"]\n  - name: ntp_v4\n    timeout: 3s\n    interval: 5s\n    command: ntpdate\n    arguments: [\"-q\", \"203.0.113.123\"]\n```\n\nThis sets up two fairly rudimentary health checks. The first renders healthy if a request to the DNS service for the `check.local` name returns the IPv6 address `2001:db8::15:600d` in the form of an `AAAA` record. The other two checks, `ntp_v6` and `ntp_v4` use the `ntpdate` CLI utility to determine if a date is returned by the NTP service.\n\n### Starting services\n\nTo finish up, we need to start our services. For this example we assume that both services as well as [Cabourotte] are run using [systemd] while `anycastd` is run directly for the purposes of this example.\n\nSo, to start the DNS, NTP and [Cabourotte] services we run\n\n```sh\n$ systemctl start dns.service ntp.service cabourotte.service\n```\n\nAfter which we can start `anycastd` itself.\n\n```sh\n$ anycastd run\n2024-03-25T15:17:23.783539Z [info     ] Reading configuration from /etc/anycastd/config.toml. config_path=/etc/anycastd/config.toml\n2024-03-25T15:17:23.785613Z [info     ] Starting service \"dns\".      service_health_checks=['dns'] service_healthy=False service_name=dns service_prefixes=['2001:db8::b19:bad:53', '203.0.113.53']\n2024-03-25T15:17:23.785613Z [info     ] Starting service \"ntp\".      service_health_checks=['ntp_v4', 'ntp_v6'] service_healthy=False service_name=ntp service_prefixes=['2001:db8::123:7e11:713e', '203.0.113.123']\n2024-03-25T15:17:23.797760Z [info     ] Service \"dns\" is now considered healthy, announcing related prefixes. service_health_checks=['dns'] service_healthy=True service_name=dns service_prefixes=['2001:db8::b19:bad:53', '203.0.113.53']\n2024-03-25T15:17:23.812260Z [info     ] Service \"ntp\" is now considered healthy, announcing related prefixes. service_health_checks=['ntp_v4', 'ntp_v6'] service_healthy=True service_name=ntp service_prefixes=['2001:db8::123:7e11:713e', '203.0.113.123']\n```\n\n`anycastd` will execute the health checks and, since all of them pass, announce the configured service IPs, which we can verify by looking at the new [FRRouting] running configuration.\n\n```diff\n@@ -7,9 +7,11 @@\n  neighbor eth0 interface peer-group unnumbered\n  !\n  address-family ipv4 unicast\n+  network 203.0.113.53/32\n   redistribute static\n  !\n  address-family ipv6 unicast\n+  network 2001:db8::b19:bad:53/128\n   redistribute static\n   neighbor fabric activate\n   neighbor fabric nexthop-local unchanged\n@@ -22,9 +24,11 @@\n  neighbor eth1 interface peer-group unnumbered\n  !\n  address-family ipv4 unicast\n+  network 203.0.113.123/32\n   redistribute static\n  !\n  address-family ipv6 unicast\n+  network 2001:db8::123:7e11:713e/128\n   redistribute static\n   neighbor fabric activate\n   neighbor fabric nexthop-local unchanged\n```\n\n### Stopping services\n\n`anycastd` will keep prefixes announced as long as health checks pass.\nTo stop announcing prefixes, even though the underlying services are healthy, for example to perform maintenance,\nsimply stop `anycastd`, causing all service prefixes to be denounced.\n\n```sh\n^C\n2024-03-25T15:20:29.738135Z [info     ] Received SIGINT, terminating.\n2024-03-25T15:20:29.817023Z [info     ] Service \"dns\" terminated.    service=dns\n2024-03-25T15:20:29.819003Z [info     ] Service \"ntp\" terminated.    service=ntp\n```\n\n## Services\n\nServices are the main unit of abstraction within `anycastd` and 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\nthe combination of check results using the logic described below.\n\n```\n\u250c\u2500[Service]\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510                        \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                       \u2502                   \u250c\u2500\u2500> \u2502 HLTH CHK \u2502\n\u2502           \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\u2502 IF healthy\u2022:          \u2502                   \u2502    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502     announce prefixes \u2502                   \u251c\u2500\u2500> \u2502 HLTH CHK \u2502\n\u2502 ELSE:           \u2022\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510   \u2502    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\u2502     denounce prefixes \u2502               \u2502   \u2502    \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518               \u2502   \u2514\u2500\u2500> \u2502 HLTH CHK \u2502\n                                        \u2502        \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                                        \u2502\n\u250c\u2500[Routing Daemon]\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510     \u2502\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u2502     \u2502\n\u2502 \u2502 Prefix                   \u2502 <\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 \u2502 2001:db8::b19:bad:53/128 \u2502    \u2502     \u2502\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2502     \u2502\n\u2502 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u2502     \u2502\n\u2502 \u2502 Prefix                   \u2502 <\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\u2502 \u2502 203.0.113.53/32          \u2502    \u2502\n\u2502 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n### Prefixes\n\nRepresents a BGP network prefix that can be announced or denounced as part of the service.\nTypically, 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.\n\n**`anycastd` does not come with its own BGP implementation, but rather aims to provide abstractions\nthat interface with commonly used BGP daemons.** Supported BGP daemons along with their configuration options are described below.\n\n---\n\n#### FRRouting\n\nFree Range Routing, [FRRouting], or simply FRR is a free and open source Internet routing protocol suite for Linux and Unix platforms.\nAmongst others, it provides a BGP implementation that can be used to announce BGP service prefixes dynamically.\n\n##### Options\n\n| Option                     | Description                                                         | Default          | Examples                                                                 |\n| -------------------------- | ------------------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------ |\n| **prefix** <br> (required) | The network prefix to create when healthy.                          | `null`           | `2001:db8:4:387b::/64` <br> `192.0.2.240/28` <br> `2001:db8::b19:bad:53` |\n| _vrf_                      | A VRF to create the prefix in. If omitted, the default VRF is used. | `None`           | `EDGE`                                                                   |\n| _vtysh_                    | The path to the vtysh binary used to configure FRRouting.           | `/usr/bin/vtysh` | `/usr/local/bin/vtysh`                                                   |\n\n### Health Checks\n\nAssessments on individual components constituting the service to ascertain the overall operational status of the service.\nA 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.\n\n---\n\n#### Cabourotte\n\n[Cabourotte] is a general purpose healthchecking tool written in Golang that can be configured to execute checks, exposing their results via API.\n\n##### Options\n\n| Option                   | Description                                                           | Default                 | Examples                 |\n| ------------------------ | --------------------------------------------------------------------- | ----------------------- | ------------------------ |\n| **name** <br> (required) | The name of the health check, as defined in [Cabourotte].             | `null`                  | `anycast-dns`            |\n| _url_                    | The base URL of the Cabourotte API.                                   | `http://127.0.0.1:9013` | `https:://healthz.local` |\n| _interval_               | The interval in seconds at which the health check should be executed. | `5`                     | `2`                      |\n\n---\n\n## Configuration\n\n`anycastd` can be configured using a TOML configuration file located at `/etc/anycastd/config.toml`, or a path specified through the `--configuration` parameter.\nFor a quick primer on TOML, see [A Quick Tour of TOML](https://toml.io).\n\n### Schema\n\n```toml\n[services] # A definition of services to be managed by `anycastd`.\n\n  [services.<service-name>] # A service with a unique and recognizable name.\n    [[prefixes.<prefix-type>]] # A prefix of the specified type.\n      # Options related to the specified prefix type.\n\n    [[checks.<check-type>]] # A check of the specified type.\n      # Options related to the specified check type.\n```\n\n[Anycast]: https://en.wikipedia.org/wiki/Anycast\n[FRRouting]: https://github.com/FRRouting/frr\n[Cabourotte]: https://github.com/appclacks/cabourotte\n[VRF]: https://en.wikipedia.org/wiki/Virtual_routing_and_forwarding\n[systemd]: https://systemd.io/\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "A daemon to manage anycasted services based on status checks.",
    "version": "0.1.10",
    "project_urls": {
        "Issues": "https://github.com/gecio/anycastd/issues",
        "Repository": "https://github.com/gecio/anycastd"
    },
    "split_keywords": [
        "anycast",
        "bgp",
        "dns",
        "frrouting",
        "monitoring",
        "networking",
        "infrastructure",
        "routing",
        "healthcheck"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4af2007b56171fb8eb750776b3fb9cba990b648c7fdfabba1d673c0663e878e3",
                "md5": "c91d8865e51b95ac055851b7794ac314",
                "sha256": "bb07753926d9b2c5053a920964575706c270a9afbf8b501279ecbba46e0a01ad"
            },
            "downloads": -1,
            "filename": "anycastd-0.1.10-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c91d8865e51b95ac055851b7794ac314",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 33535,
            "upload_time": "2024-03-27T16:58:17",
            "upload_time_iso_8601": "2024-03-27T16:58:17.488179Z",
            "url": "https://files.pythonhosted.org/packages/4a/f2/007b56171fb8eb750776b3fb9cba990b648c7fdfabba1d673c0663e878e3/anycastd-0.1.10-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "cc7db6be7280b461313904daaea7cd08d55196fed7852ce54ab956f56a434fff",
                "md5": "d6070e9e6b4ef287aad738fe9f47207f",
                "sha256": "03e0479900c9980a4aeb19b3d3a92636db246c6ab2b7e38be5190c011cff66b3"
            },
            "downloads": -1,
            "filename": "anycastd-0.1.10.tar.gz",
            "has_sig": false,
            "md5_digest": "d6070e9e6b4ef287aad738fe9f47207f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 48002,
            "upload_time": "2024-03-27T16:58:19",
            "upload_time_iso_8601": "2024-03-27T16:58:19.190211Z",
            "url": "https://files.pythonhosted.org/packages/cc/7d/b6be7280b461313904daaea7cd08d55196fed7852ce54ab956f56a434fff/anycastd-0.1.10.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-27 16:58:19",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "gecio",
    "github_project": "anycastd",
    "github_not_found": true,
    "lcname": "anycastd"
}
        
Elapsed time: 0.28470s