#import "../Helpers/code-snippets.typ": code

== HAProxy
Patroni benötigt einen Load Balancer, der die Anfragen an den derzeitigen Cluster-Leader weiterleitet. Wir haben uns für HAProxy entschieden, weil Patroni eine empfohlene HAProxy Konfiguration zur Verfügung stellt (https://github.com/zalando/patroni/blob/master/haproxy.cfg). HAProxy läuft containerisiert im K3s Cluster, weil es dort sehr einfach zu installieren ist und sowieso nur aus K3s auf die Datenbank zugegriffen wird. Die Kubernetes Manifeste befinden sich in unserem Gitlab Repository unter `kubernetes/haproxy`.

HAProxy fragt alle 3s mit http den Port 8008 (Patroni API) der drei Nodes an. Beim Leader kommt HTTP Code 200 zurück, bei den Followern HTTP Code 503. HAProxy leitet die Anfragen dann ausschliesslich an den Leader weiter. Write Operationen sind nur auf dem Leader erlaubt, Read Operationen auf allen Nodes. Wenn der Leader ausfällt, wird der Follower mit der höchsten Priorität zum Leader. HAProxy erkennt das und leitet die Anfragen an den neuen Leader weiter.

HAProxy ist als DaemonSet in Kubernetes deployed. Ein DaemonSet stellt sicher, dass auf jedem Node im Cluster ein Pod läuft, somit ist HAProxy hochverfügbar und es gibt keine Single Point of Failure bei einem Node. Unsere Applikation greift auf den Service mit DNS-Namen `haproxy.haproxy.svc.cluster.local` zu. Cilium leitet Anfragen an diesen Service an einen HAProxy Pod weiter, welcher die Anfrage dann an den derzeitigen Patroni Leader weiterleitet.