Traefik: der moderne Reverse Proxy

Der Beitrag Container mit Docker in der Praxis hat die Grundlagen von Docker erklärt. Der Zugriff auf die Anwendungen in den Containern ist über veröffentlichte Ports erfolgt. Port 8080 des Hosts wurde auf Port 80 von Container 1 umgeleitet, Port 8081 auf Port 80 von Container 2 etc.

Das funktioniert, ist für den Produktivbetrieb aber nicht praktikabel. Dies hauptsächlich aus zwei Gründen:

  1. Man will extern keine Links in der Form "http://hostname:8080" haben. In vielen Firmen sind nur wenige Ports ausgehend geöffnet, so dass Benutzer von dort nicht auf den Dienst zugreifen könnten.
  2. Will man die Dienste verschlüsselt über HTTPS anbieten. Zwar könnte man den Webserver in jedem Container entsprechend konfigurieren, aber das würde der Container-Philosophie widersprechen.

Die Lösung ist in solchen Fällen ein Reverse Proxy. Nur dieser ist von extern erreichbar. Er nimmt die Anfragen von aussen entgegen und leitet sie an die zuständigen Dienste weiter. Zusätzlich kümmert er sich um Sachen wie Logging und Verschlüsselung. In komplexeren Umgebungen verteilt er die Anfragen auf mehrere Server, die den gleichen Dienst anbieten, und prüft diese auf Erreichbarkeit. Einige Proxies können Inhalte zwischenspeichern, so dass sie nachfolgende Anfragen für den gleichen Inhalt selbst beantworten können und so die Backend-Server entlasten.

Prinzip eines Reverse Proxy: eine HTTPS-Anfrage von extern wird per HTTP an einen internen Server weitergereicht

Reverse Proxies gibt es viele bzw. jeder bessere Webserver kann als Reverse Proxy eingesetzt werden. Häufig eingesetzt werden HAProxy, nginx, Apache, aber auch IIS mit dem Application-Request-Routing-Modul.

Kürzlich bin ich auf Traefik aufmerksam geworden, welchen ich kurz vorstellen möchte. Die Spezialität von Traefik ist, dass er seine Konfiguration dynamisch aktualisiert. Unter anderem kann er auf Docker zugreifen. Das heisst: wenn man Docker verwendet und einen neuen Container über Traefik veröffentlichen will, passt man nicht die Konfiguration von Traefik an, sondern startet den Container mit einem Label. Traefik aktualisiert dann sofort seine Konfiguration.

Traefik lässt sich natürlich auch mit Docker betreiben. Hier eine docker-compose.yaml als Beispiel:

version: '3'

services:
  reverse-proxy:
    # The official v2.0 Traefik docker image
    image: traefik:v2.0
    # Enables the web UI and tells Traefik to listen to docker
    command: --api.insecure=true --providers.docker --providers.docker.exposedbydefault=false
    ports:
      # The HTTP port
      - "80:80"
      # The Web UI (enabled by --api.insecure=true)
      - "8082:8080"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
    network_mode: bridge

"--providers.docker" aktiviert die Konfiguration über Docker und "--providers.docker.exposedbydefault=false" deaktiviert die automatische Veröffentlichung aller Dienste. Stattdessen gibt man per Label vor, welche Dienste über Traefik erreichbar sein sollen.

Ein Beispiel für einen Container mit veröffentlichtem Port 80:

labels:
    - traefik.http.routers.xy.rule=Host("xy.domain.ch")
    - traefik.http.services.xy.loadbalancer.server.port=80
    - traefik.enable=true

Die Container müssen sich im gleichen Docker-Netzwerk befinden, damit Traefik auf sie zugreifen kann. Ihre aktuelle IP-Adresse ermittelt er automatisch. Mittels Routen und Middlewares können Pfade entfernt werden. Wenn der Zugriff von extern über "/pfad" erfolgen soll, die Anwendung im Container aber unter "/" verfügbar ist, wäre die Konfiguration wie folgt:

- traefik.http.routers.xy.middlewares=xy_middleware@docker
- traefik.http.middlewares.xy_middleware.stripprefix.prefixes=/pfad

Leider ist das in der Theorie oft einfacher als in der Praxis: Traefik kann die Antworten des Backend-Servers nicht verändern. Wenn dieser absolute Links in der Form "/datei" ausgibt, werden diese nicht zu "/pfad/datei" angepasst. Andere Proxies können das, aber es sollte unter anderem aus Performance-Gründen vermieden werden. Lieber verwendet man pro Dienst einen Hostnamen.

Traefik beherrscht nicht nur HTTPS, sondern auch TCP. Er kann eine Authentifizierung verlangen, und -ganz praktisch-: er kann Zertifikate per Let's Encrypt erstellen. Eine Anleitung dazu ist unter https://docs.traefik.io/https/acme/ zu finden.

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.