Wouter0100/galera-arbitrator

★ 0Forks 0DockerfileGitHub ↗Compare

README

galera-arbitrator

A container image for garbd, the MariaDB Galera arbitrator. It joins a cluster as a voting member that stores no data.

docker run --network host ghcr.io/wouter0100/galera-arbitrator:v0.1.0 \
  --address "gcomm://10.0.0.1,10.0.0.2" \
  --group "My Production cluster" \
  --name arbitrator \
  --log /dev/stdout

Why this exists

garbd ships in galera-arbitrator-4, which the official mariadb image does not install — it has galera-4, the replication provider, and nothing else. The images on Docker Hub are all personal namespaces with no provenance, which is not what you want holding a vote in a production cluster. So this builds garbd from the same mariadb.org repository the database hosts install from.

Why an arbitrator

A two-node Galera cluster has no fault tolerance. Losing either node leaves one of two members, which is not a majority, so the survivor drops out of the primary component and goes read-only — precisely when you needed it to keep serving. An arbitrator is a third vote, so the survivor holds two of three and stays writable. It participates in group communication and certification but keeps no dataset, so it can run somewhere far cheaper than a database node.

It cannot be a donor for a state transfer, and it does not reduce the need for backups: three votes, two copies of the data.

Version pinning

GALERA_VERSION is pinned to the galera-4 version on the data nodes, because all members of a cluster speak one group communication protocol. Build a matching image when the data nodes are upgraded:

docker build --build-arg GALERA_VERSION=26.4.28-ubu2404 -t galera-arbitrator:test .

MARIADB_SERIES selects the repository the package comes from (default 11.4), and MARIADB_MIRROR the mirror.

Networking

Galera is a full mesh: every member must be able to open a TCP connection to every other on 4567. That is the constraint that decides how this is deployed. In Kubernetes, whether a pod address is enough depends on the CNI: with Cilium in native routing mode and masquerading off, members outside the cluster can route to a pod address and see it as the source, so ordinary pod networking works. Where pod addresses are not routable from the other members, or egress is masqueraded, the pod needs hostNetwork: true instead. Test both directions before assuming either.

Deployment

For the GoodMoovs production cluster this runs as custom-database-arbitrator.yaml in the gitops repository under cap/gm/clusters/production.

Contributors

Wouter0100

Issues