Help us shape the future of Go! Take the 2026 Go Developer Survey

pathosd

module
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2026 License: Apache-2.0

README

pathosd

Health-aware BGP VIP announcer. Runs local health checks (HTTP, HTTPS, DNS, ICMP ping, TCP, UDP, gRPC, SQL, Kafka, listening socket) with HAProxy-style rise/fall hysteresis, and announces or withdraws VIP routes over BGP based on service health.

Why pathosd?

High-availability services need a single, stable IP that fails over with the service. Classic approaches fall short:

  • Keepalived (VRRP): ties failover to a shared virtual MAC and requires a master/backup election. It couples the health decision to link-layer state and doesn't interoperate with routing fabrics.
  • Static VIPs: a load balancer or router advertises a VIP unconditionally — traffic is black-holed whenever the service behind it is down.
  • Plain BGP speakers: GoBGP/BIRD can advertise a prefix, but you still have to build the health-checking, hysteresis, and withdraw logic and wire it into the route originator.

pathosd combines the health check and the BGP originator in one process, so the health decision and the route state are always consistent. It is a service route originator, not a router: it embeds GoBGP to advertise /32 (or any) prefixes for Virtual IPs when the backing service is healthy, and withdraws them when it is not.

  • Fail-closed by design: if pathosd dies, BGP sessions drop and every route is withdrawn. A dead health checker never leaves stale routes in the network.
  • VIPs start withdrawn: no route is announced until the service proves healthy.
  • Single process, no IPC: check results feed directly into route decisions. Nothing can drift out of sync.
  • Works with any BGP fabric: peers with FRR, BIRD, or any standard BGP router — no VRRP, no shared MAC, no proprietary protocol.
  • IPv4 and IPv6: announce IPv4 /32 and IPv6 /128 VIPs (or any prefix) over standard BGP/MP-BGP.
  • One moving part: pure static binary, no sidecars, no agent to coordinate with.

Features

  • Health checks: HTTP/HTTPS (TLS, custom headers, response codes/text/regex/JQ, forward proxy), DNS (A/AAAA/CNAME/etc.), ICMP ping (loss ratio), TCP, UDP, gRPC (standard Health Checking Protocol + arbitrary unary methods), SQL (MySQL/MariaDB and PostgreSQL, custom queries with jq conditions), Kafka (broker metadata with TLS/SASL, optional topic leadership), listening socket (no traffic sent)
  • Rise/Fall hysteresis: configurable consecutive success/failure thresholds before state transitions (HAProxy-style)
  • Several checks per VIP: each with its own interval/thresholds, combined with all, any or a boolean expression such as web || (dns && ping)
  • Policy actions: withdraw (remove route entirely) or lower_priority (AS-path prepend + communities), plus a lower_priority_file drain switch
  • Standby ordering: per-VIP announce.as_path_prepend / communities applied while healthy, so several pathosd nodes can rank the same VIP in a fixed order over eBGP
  • IPv4 + IPv6 VIPs: IPv6 routes are carried over IPv4-transport MP-BGP with a dedicated IPv6 next-hop
  • BGP session security: per-neighbor TCP MD5 (auth_password), graceful restart, passive peers, eBGP multihop
  • Observability: Prometheus metrics (plus GoBGP's built-in collectors), opt-in per-check-type metrics, OpenTelemetry traces/metrics/logs export, a Grafana dashboard
  • HTTP API: landing page (/), /healthz, /readyz, /status, /metrics, ad-hoc check trigger, config reload
  • Hot reload: SIGHUP, systemctl reload or POST /api/v1/reload apply VIP and log-level changes without dropping BGP sessions; changed checks prove themselves in shadow before they take over, and a rejected or forgotten reload is visible in metrics, /status and the status page
  • Optional GoBGP gRPC API: enable for gobgp CLI inspection/debugging
  • YAML and TOML config with JSON Schema validation and environment placeholders
  • Packaging: static Linux binaries (amd64/arm64), multi-arch non-root FROM scratch container image with a built-in health check, Debian and RPM packages with a hardened systemd unit
  • CLI: pathosd check runs the configured checks once from a shell with test(1)-style exit codes; pathosd validate checks a config without starting; pathosd healthcheck calls /readyz for container health checks; pathosd reload applies an edited config and fails when the daemon could not

Quick start

Install the package for your distribution (static binaries and a container image are on the releases page; details in Installation and running):

sudo apt install ./pathosd_<version>_linux_amd64.deb      # Debian / Ubuntu
sudo dnf install ./pathosd_<version>_linux_amd64.rpm      # EL9 / EL10 / Fedora

Describe the router, at least one BGP neighbor and the VIPs with their health checks. The smallest useful config announces one /32 while an HTTP endpoint on it answers 200:

schema: v1
router:
  asn: 65001
  router_id: 192.0.2.10
  local_address: 192.0.2.10
bgp:
  neighbors:
    - name: tor
      address: 192.0.2.1
      peer_asn: 65000
vips:
  - name: web
    prefix: 10.10.1.1/32
    check:
      type: http
      http: { url: /healthz }   # host defaults to the VIP address
    policy:
      fail_action: withdraw

Validate it, try the checks without touching BGP, then start the service:

pathosd validate --config /etc/pathosd/pathosd.yaml
pathosd check --config /etc/pathosd/pathosd.yaml
sudo systemctl enable --now pathosd

The VIP starts withdrawn and is announced once the check has passed rise times; systemctl status pathosd and http://127.0.0.1:59179/ show the live state. The host must own the VIP address, see Owning the VIP address. Complete, commented configs: examples/pathosd.yaml and examples/pathosd.toml.

Documentation

Page What it covers
Installation and running binary, deb/rpm with the systemd unit, container capabilities, owning the VIP address
Configuration YAML/TOML, validation and JSON Schema, environment placeholders, config rules
CLI run, validate, check, jq-test, exit codes
Health checks rise/fall, how a result becomes a route change, several checks per VIP, reaction time, local address guard, running checks on demand
Check reference one guide per check type: http, dns, ping, tcp, udp, grpc, listen, sql, kafka
Announce policy fail_action, drain file, AS-path prepends and communities, standby ordering
BGP peering TCP MD5, OpenWrt/BIRD localhost peering, GoBGP CLI
HTTP API endpoints, readiness vs liveness, security
Observability metrics, Grafana dashboard, OpenTelemetry
Troubleshooting peers that never establish, VIPs that stay withdrawn, rejected routes, flapping
Development building, the pre-PR gate, e2e tests
Design notes why there is no exec check and no embedded scripting

License

See LICENSE.

Directories

Path Synopsis
cmd
pathosd command
internal
bgp
caps
Package caps raises file capabilities granted to the binary so pathosd can bind port 179 and open raw ICMP sockets without running as root.
Package caps raises file capabilities granted to the binary so pathosd can bind port 179 and open raw ICMP sockets without running as root.
reload
Package reload applies a changed config file to a running daemon.
Package reload applies a changed config file to a running daemon.
systemd
Package systemd integrates with a systemd service manager when one is present: sd_notify readiness/status/stopping messages (Type=notify units) and detection of journald as the log sink.
Package systemd integrates with a systemd service manager when one is present: sd_notify readiness/status/stopping messages (Type=notify units) and detection of journald as the log sink.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL