Aktionen

Apache2 als Reverse Proxy und Loadbalancer Beispiel Proxmox

Aus znilwiki

Changelog:

  • 22.03.2025 erste Version

Vorwort

Ein Arbeitskollege hat vor seinen Proxmox-Cluster einen Loadbalancer geschaltet. Dadurch landet er immer auf einen aktiven Knoten, auch bei einem Ausfall.
Das fand ich eine prima Idee - und die Gelegenheit mal zu prüfen ob so etwas auch mit einem Apache Reverse Proxy geht - Jupp, kann dieser auch!
Wie immer läuft das ganze bei mir unter Ubuntu, in diesem Fall 24.04 LTS, es sollte aber mit allen Apache2 Installationen funktionieren.



Schritt 1: Verschlüsselte Webseite

Ich baue immer erst die Webseite inklusive SSL Zertifikat und Umleitung auf https. Erst wenn diese funktioniert baue ich das Reverse Proxy ein.
Ich nutze eine Apache .vhost Konfiguration bei der jede Webseite seine eigene Konfigurationsdatei hat; https://httpd.apache.org/docs/2.4/vhosts/examples.html
Da ich faul bin nutze ich einen Host mit installiertem ISPConfig: https://znil.net/index.php?title=IONOS_Mietserver_Ubuntu_24.04_-_Einrichtung_ISPConfig#ISPConfig_Installieren Über die GUI von ISPConfig kann ich leicht die Subdomain erstellen und auch gleich ein passendes Zertifikat anfordern lassen.
Das erneuern der Zertifikate funktioniert aber nicht mehr wenn der Reverse Proxy eingebaut ist, deshalb läuft dafür noch ein Cronjob: https://znil.net/index.php?title=IONOS_Mietserver_Ubuntu_24.04_-_Einrichtung_ISPConfig#CronJob_f%C3%BCr_Reverse-Proxy_Seiten Nach wenigen Minuten steht die Webseite:

ClipCapIt-250322-123150.PNG

Wenn eure Webseite so funktioniert, könnte Ihr die Proxy-Geschichte einbauen.


Apache 2 benötigte Module aktivieren

a2enmod proxy_http proxy_balancer lbmethod_byrequests proxy_wstunnel
systemctl restart apache2.service

Das aktiviert neben dem Proxy-Modul auch das für das Loadbalancing und für die Prüfung ob ein Host erreichbar ist.
Zusätzlich mit proxy_wstunnel auch das Modul für das Proxing von Websockets.



Proxy konfigurierten

Dazu bearbeite ich die entsprechende .vhost Datei auf meinem Webserver:

nano /etc/apache2/sites-available/proxmox.znil.net.vhost

Im Abschnitt für Port 443 füge ich folgendes hinzu:

<IfModule mod_proxy_balancer.c>
    <Proxy balancer://proxmox>
        BalancerMember https://192.168.0.231:8006
        BalancerMember https://192.168.0.229:8006 status=+H
        BalancerMember https://192.168.0.230:8006 status=+H
        BalancerMember https://192.168.0.228:8006 status=+H
        ProxySet lbmethod=byrequests
    </Proxy>
</IfModule>
<IfModule mod_proxy.c>
    ProxyPreserveHost On
    ProxyRequests Off
    ProxyErrorOverride On

    SSLProxyEngine On

    SetEnv force-proxy-request-1.0 1
    SetEnv proxy-nokeepalive 1

    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off

    ProxyPass "/" "balancer://proxmox/"
    ProxyPassReverse "/" "balancer://proxmox/"
</IfModule>


Erklärung der Parameter:

<Proxy balancer://proxmox>                               Erstellt eine Loadbalancing Gruppe
BalancerMember https://192.168.0.231:8006                Das erste Mitglied der Gruppe, wird per Default genommen
BalancerMember https://192.168.0.229:8006 status=+H      jedes weitere Mitglied bekommt status=+H = wird nur genommen wenn die anderen davor nicht erreichbar sind.
ProxySet lbmethod=byrequests                             Die Verfügbarkeitsprüfung erfolgt über den Aufruf der BalanceMember URL

SSLProxyVerify none                                      Keine Prüfung des internen Zertifikates, es kann also 
SSLProxyCheckPeerCN off                                  extern ein Zertifikat, z.B. von Lets Encrypt für alle
SSLProxyCheckPeerName off                                4 internen Server genommen werden.
SSLProxyCheckPeerExpire off

ProxyPass "/" "balancer://proxmox/"                      Reverse Proxy auf die Loadbalancergruppe "proxmox"
ProxyPassReverse "/" "balancer://proxmox/"


Das ganze ist dann eine Failover-Konfiguration, es wird der nächste Server aus der Liste genommen wenn der der davor nicht verfügbar ist.
Wenn Ihr das {{{1}}} weglasst, macht er ein echtes Loadbalancing was aber wegen der Anmeldung bei Proxmox blöd sein kann.


Falls Ihr wie ich ISPConfig einsetzt, könnt Ihr das auch einfach in die Einstellungen der Webseite kopieren:

ClipCapIt-250322-130237.PNG

Proxmox Cluster mit Loadbalancing und Websockets für VNC-Konsole

Ich musste das obige Beispiel - welches für viele normale Webseiten problemlos funktionieren würde - noch mal speziell für Proxmox anpassen damit auch die Remote-Console zu den VMs funktioniert.
Und zwar mussten die Websockets auch mit hinein, was mit dem Loadbalancing nicht ganz so einfach war.

<IfModule mod_proxy_balancer.c>
    <Proxy balancer://proxmox>
        BalancerMember https://192.168.0.231:8006
        BalancerMember https://192.168.0.229:8006 status=+H
        BalancerMember https://192.168.0.230:8006 status=+H
        BalancerMember https://192.168.0.228:8006 status=+H
        ProxySet lbmethod=byrequests
    </Proxy>
    <Proxy balancer://proxmoxwss>
        BalancerMember wss://192.168.0.231:8006/$1 retry=0
        BalancerMember wss://192.168.0.229:8006/$1 retry=0 status=+H
        BalancerMember wss://192.168.0.230:8006/$1 retry=0 status=+H
        BalancerMember wss://192.168.0.228:8006/$1 retry=0 status=+H
        ProxySet lbmethod=byrequests
    </Proxy>
    <Proxy balancer://proxmoxws>
        BalancerMember ws://192.168.0.231:8006
        BalancerMember ws://192.168.0.229:8006 status=+H
        BalancerMember ws://192.168.0.230:8006 status=+H
        BalancerMember ws://192.168.0.228:8006 status=+H
        ProxySet lbmethod=byrequests
    </Proxy>
</IfModule>
<IfModule mod_proxy.c>
    ProxyPreserveHost On
    ProxyRequests Off
    ProxyErrorOverride On

    SSLProxyEngine On

    SetEnv force-proxy-request-1.0 1
    SetEnv proxy-nokeepalive 1

    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off

    <Location />
        ProxyPass "/" "balancer://proxmox/"
        ProxyPassReverse "/" "balancer://proxmox/"
    </Location>
    <LocationMatch ^/(api2/json/nodes/[^\/]+/[^\/]+/[^\/]+/vncwebsocket.*)$>
        ProxyPass "balancer://proxmoxwss/"
    </LocationMatch>
    <Location /websockify>
        ProxyPass "balancer://proxmoxws/"
        ProxyPassReverse "balancer://proxmoxws/"
    </Location>


</IfModule>




Quellen




Kommentare

Loading comments...