Cover Image

Und weiter gehst … Nach dem Relaunch der Wormatia Homepage am 11. Juli musste nun der alte Wormatia Server daran glauben. Die Linux-Distribution war in die Jahre gekommen und es musste dringend eine Aktualisierung her.

Die meisten Besucher der Webseite kennen nur die Webseite wormatia.de die den Verein nach Außen darstellt. Im Hintergrund ist die Wormatia Webseite allerdings um einiges vielfältiger als der eine oder andere glaubt. Es gibt z.B. ein spezielles Admin-Tool zur Pflege von Zeitungsartikel, Spielergebnissen, Vereins-Infos, Spieler-Statistiken usw.

Dazugekommen sind über die Jahre noch ein Mail-Server, ein Nextcloud Server und der Liveticker und ein Online-Shop. Das ist bisher alles direkt unter einem Debian-Linux auf der Host-Maschine direkt betrieben worden. Das bedeutet für uns, dass die genutzte Software immer untereinander kompatibel sein musste. Eine moderne Lösung für dieses Problem existiert inzwischen. Es ist inzwischen möglich jede dieser Anwendung in einem Container zu kapseln. Und das haben wir getan. Dank der unkomplizierten Bereitstellung eines zweiten Servers durch unseren Hoster Hosteurope konnten der Umzug in Ruhe stattfinden.

Vorbereitung

Als erstes mussten natürlich erstmal alle Applikationen in einen Container überführt werden. Wir haben uns hier für Docker als Container-Lösung entschieden. Wenn die Anwendung in einen Container geschoben wird entstehen allerdings auch noch andere Fragen wie

  • Wo kommt das SSL Zertifikat her?
  • Wie sieht es mit der Sicherheit aus?
  • Wir aktualisiere ich die Anwendungen?
  • Wie sichere ich die Anwendungen?
  • Wie überwache ich den Betrieb?

Gerade das HTTP-Routing ändert sich mit den Containern fundamental. Vorher hatten wir einen alten Apache Server genutzt. Alle Anwendungen wurden als Virtual-Host im Apache Server konfiguriert. Das muss mit Containern alles anders laufen. Wir haben uns für die Software Traefik als HTTP/TCP-Router entschieden da diese sehr flexibel ist und uns das leidige Thema Aktualisierung der SSL-Zertifikate komplett abnehmen kann. Und Traefik ist in golang geschrieben und dadurch super schnell und effizient. In der Sprach ist übrigens auch Docker programmiert worden.

Dazu kommt noch die netten Logos ?

Golang "Gopher"

Traefik Proxy

Docker "Moby"

Der grobe Plan war wie folgt:

  • Anwendung in Container portieren (größter Aufwand)
  • Neuen Server buchen
  • TTL DNS Einträge ändern
  • Webseiten einzeln auf neuen Server portieren
  • E-Mail Server umstellen

Herzlich Willkommen auf dem neuen Wormatia Server

Projekt-Docker Setup

Da wir bei einem Fussballverein mit dem Budget haushalten müssen, können wir nicht einfach etablierte Technologien wie Kubernetes nutzen die das skalieren und verteilen von Containern übernehmen können da dies erfordert, dass eine entsprechende Infrastruktur auch eine Stange Geld kostet. Es musste also alles auf gebuchten Maschine laufen. Ein grobes überschlagen der Ressourcen ergab aber, dass es möglich sein sollte was sich auch bestätigte.

Jede Anwendung wurde auf dem Server in ein einem eigenes Verzeichnis abgelegt und mittels docker-compose gestartet. In den jeweiligen Setups wurden sogenannte Bind-Mounts genutzt um den Zustand der Applikationen vorzuhalten. Das betraf überwiegend die Datenbanken. Wenn ein Container neu erstellt wird, möchte man natürlich seine gespeicherten Daten erhalten. Das gute an der jetzigen Lösung ist, dass die Konfiguration bequem versioniert werden kann. Wir legen nun die Konfigurationen der Anwendungen in einem GIT-Server ab. Dadurch lassen sich Änderungen leicht wieder rückgängig machen falls etwas mal doch nicht funktioniert. Inzwischen haben sich schon 25 Git-Projekte angesammelt.

Eine Menge "commits"

Ein einzelnes Projekte

Gitea Sever - Projekt-Übersicht

Die Grundinstallation von Docker und wirklich notwendigen Anwendsungen auf dem Server wurde über Ansible ebefalls versioniert und in einem Drone-CI Server automatisiert.

Drone-CI / Ansible

Routing Setup mit Traefik

Die Container der Anwendung sollen nicht direkt mit dem Internet verbunden sein. Das hat mehrere Vorteile. Über einen Reverse Proxy vor den Anwendungen kann man auf jede ankommende Anfrage und jede Rückmeldung Einfluss nehmen. Das ermöglicht flexibel Anfragen auf die Anwendungen umzuleiten. Das tolle am Traefik Server ist es, dass er Dinge wie Verschlüsselung übernehmen kann und die Logik aus den Anwendungen entfernt werden kann. Das reduziert die Komplexität im Setup enorm. Es ist zudem möglich über ein Middleware dazwischen zu klemmen. Wir machen das bei der Wormatia um Zugriff auf Applikationen zu beschränken. Zudem verändern wir Anfragen damit Anwendungen diese Verarbeiten können. Das ist unter anderem für das Monitoring wichtig da die Anwendung immer einen bestimmten Pfad erwartet den wir aus technischen Gründen aber nicht nach Außen freigeben können.

Das Schaubild gibt einen guten Eindruck wie umfangreich inzwischen eine Infrastruktur eines (noch) Amateur-Fussballverein aussehen kann (ok… Wormatia ist schon immer etwas anders gewesen).

Traefik als Reverse Proxy Router vor der gesamten Infrastruktur

Da der Traefik Proxy selbst als Docker-Container läuft und genau für solche Anwendungsfälle entwickelt wurde, lässt er sich wunderbar direkt im Docker-Setup der einzelnen Anwendungen konfigurieren. Dies erfolgt über Labels die an die Container gebunden werden. Diese stellen Meta-Daten (also Daten über Daten) dar und enthalten Informationen über das Routing, die genutzten TCP Ports und die Auswahl der genutzten Middleware Komponenten.

Hier als Beispiel ein Auszug aus der Konfiguration des Wormatia Livetickers:

version: '3'
services:
  liveticker_varnish:
    container_name: liveticker_varnish
    restart: always
    build: ./docker-varnish
    networks:
      - web
    expose:
      - 80
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.liveticker_secure.rule=Host(`liveticker.wormatia.de`)"
      - "traefik.http.routers.liveticker_secure.entrypoints=https"
      - "traefik.http.routers.liveticker_secure.tls=true"
      - "traefik.http.routers.liveticker_secure.tls.certresolver=letsencrypt"
      - "traefik.http.routers.liveticker_unsecure.rule=Host(`liveticker.wormatia.de`)"
      - "traefik.http.routers.liveticker_unsecure.entrypoints=http"
      - "traefik.http.routers.liveticker_unsecure.tls=false"
      - "traefik.http.services.liveticker.loadbalancer.server.port=80"

Spezialbehandlung IMAP

Bisher haben wir nur das routen von HTTP/HTTPS gesprochen. In der Infrastruktur wird allerdings auch ein E-Mail Server betrieben. Dieser nutzt IMAP als Protokoll. Zum Glück unterstüzt der Traefik Proxy seit der Version 2.0 auch das Routing von TCP Daten jeglicher Art. Damit muss nicht extra eine Software wie HAProxy installiert werden. Und es kann verhinder werden, dass der IMAP Server am Proxy vorbei einen TCP-Port direkt ins Internet freigibt.

Leider ist das Docker-Setup eines einzelnen IMAP-Server relativ unüblich, sodass ich ein neues Setup erst einmal komplett erarbeiten musste. Leider ist es nicht möglich, dass der Traefik-Server das SSL Zertifikat für den IMAP Server komplett ausliefern kann. Hier muss ein Direktzugriff der SSL Daten direkt auf den IMAP Server stattfinden. Der Traefik-Server kann allerdings das Zertifikat erneuern und bei Letsencrypt abrufen. Da das Zertifikat dann aber im Traefik Server liegt ist es dem IMAP Server nicht bekannt.

Zum Glück gibt es aber hier mit dem traefik-certs-dumper eine sehr gute Drittlösung die das Zertifikat aus dem Zertifikatsspeicher des Traefik-Servers extrahieren kann. Das habe ich dann auch gemacht und dem Dovecot IMAP Server per Bind-Mount der Dateien bekanntgemacht werden. Das klappt in der Praxis auch ganz gut.

Falls jemand das Setup für den Traefik Server sucht. Das folgende funktioniert bei mir gut.

traefik_certs_dumper:
    container_name: traefik_certs_dumper
    image: ldez/traefik-certs-dumper:v2.7.0
    restart: always
    depends_on:
      - traefik
    entrypoint: sh -c '
      apk add jq
      ; while ! [ -e /data/acme.json ]
        || ! [ `jq ".letsencrypt.Certificates | length" /data/acme.json` != 0 ]; do
          sleep 1
      ; done
      && traefik-certs-dumper file --version v2 --domain-subdir --crt-name=fullchain --key-name=privkey --watch
        --source /data/acme.json --dest /data/dumps'
    volumes:
      - ./volumes/letsencrypt:/data
    labels:
      - "traefik.enable=false"

Vor der Umstellung des Mail-Server hatte ich am meisten Bauchschmerzen da diese sehr wichtig für die Kommunikation des Vereins hängt gerade in der Corna-Zeit noch wichtiger ist.

Hier habe ich sehr früh die TTL der Domäne auf 5 Minuten heruntergestellt, sodass ich eine Umstellung (und im Notfall zurück) sehr schnell erfolgen konnte. Am Ende hat kein Benutzer etwas gemerkt und die Umstellung erfolgte ohne merkbare Ausfälle. Hier fiel mir ein Stein vom Herzen. Mit der Umstellung der Mails habe ich bis zum Ende gewartet. Damit war dann die Umstellung für den Verein abgeschlossen.

Datensicherung (Backup)

Wir haben bereits über unseren Provider ein Backup des Servers. Da ich aber hier etwas paranoid bin, habe ich ein zusätzliches Backup über die Software Borg eingerichtet. Dieses läuft jede Nacht un kann Daten deduplizieren.

Im Backup sind die Verzeichnisse der Docker-Bind-Mounts enthalten die einfache Dateien wie z.B. die Bilder der Wormatia Webseite enthalten. Datenbanken werden jeden Tag exportiert und dann ebenfalls in das Borg-Backup Archiv geschoben.

Die Daten werden in der Software dedupliziert. Damit können Daten für mehrere Monate rückwirkend vorgehalten werden.

Inzwischen kommen auch gut Datenmengen zusammen.

Backup Summary

Überwachung (Monitoring)

Für die Überwachung der Server nutzen wir bereits Prometheus als Lösung. Glücklicherweise ist Prometheus bestens für die Überwachung von Containern konzipiert worden. Es gibt sogenannte Node-Exporter die die Daten sammeln und an Prometheus übergeben können. Die Bereitstellung der Daten-Exporte erfolgt auch über den Traefik Server. Hier nutzen wir eine Middleware um eine ganze Liste von Node-Exportern bekanntzumachen. Das sieht man auch gut auf dem Diagramm. So hat jede MySQL Datenbank einen eigene Exporter. Wir sammeln aber auch andere Informationen wie CPU-Auslastung oder bemerken, wenn die Festplatt voll wird.

Ebenfalls werden HTTP- und IMAP-Ports von außen über einen Blackbox-Exporter überwacht der jede Minute auf den Server bei jeder Anwendung anfragt damit wir Ausfälle schnell erkennen können.

Aktualisierung

Es gibt immer etwas zu tun. Die gesamte Infrastruktur muss natürlich weiter betrieben und aktualisiert werden. Es wird aber versucht möglichst alles zu automatisieren. Das betrifft auch die Updates der Software. Hier nutzen wir Unattended Upgrades um wichtige Sicherheits-Aktualisierungen im Server automatisch vorzunehmen. Im Bedarfsfall wird sogar automatisch nachts der Server neugestartet, wenn ein neues Linux-Kernel auf dem Host-System eingespielt wurde.

Die Docker-Container und die Software darin muss ebenfalls auf dem neusten Stand gehalten werden. Das funktioniert jetzt aber deutlich einfacher. So konnte ich die Nextcloud Anwendung jetzt um drei Hauptversionen aktualisieren was vorher an den Abhängigkeiten zu anderen Anwendungen gescheitert war.

Was kommt als nächstes?

Die Infrastruktur passt bereits. Auf das bisher geleistete kann man glaube ich stolz sein. Die neue Infrastruktur ermöglicht jetzt, dass wir neue Wege gehen können. Es existieren noch einige alte PHP Anwendungen. Diese werden jetzt nach nun nach aktualisiert oder ersetzt. Konkret gibt es Pläne den Liveticker neu über Golang zu erstellen. Danach folgen die Wormatia-API und das alte Admin-Tool.

An diesen Plänen hängt eine menge Arbeit die schnell ein ganzes Jahr oder mehr füllen können. Aber es gibt jetzt auch nicht mehr so einen Zeitdruck.

Wenn ihr Fragen oder Anmerkungen habt… Gerne hier einen Kommentar hinterlassen.

In diesem Sinne - Alla Wormatia!

Update 29.07.2022

Für das automatische Aktualisieren von Docker Images bietet sich das Tool Watchtower an.