Files
2026-10-03 13:22:51 +02:00

146 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Wartung, drain und Container-Lebenszyklus
Was Besucher sehen, wenn an einem Backend gearbeitet wird, und welcher Befehl wofür gedacht ist.
## Das Grundprinzip
Der Agent meldet dem Server immer den **vollständigen** Stand seines Hosts. Wie ein Dienst dabei erscheint, hängt davon ab, ob sein Container noch existiert:
| Zustand des Containers | Was der Agent meldet | Besucher sehen |
|---|---|---|
| läuft | Dienst normal | die Seite |
| **gestoppt** (`docker stop`, `docker compose stop`, Absturz, `restarting`, `paused`) | Dienst vorhanden, aber *down* | **Wartungsseite** (503, „Gleich wieder da“) |
| **entfernt** (`docker rm`, `docker compose down`) | Dienst gibt es nicht mehr | **404**, die Route ist weg |
| Host/Agent weg (Reboot, Netzausfall) | nichts – Verbindung getrennt | **Wartungsseite**, solange die Lease gilt (Community 14 Tage, kommerziell 7) |
**Das ist Absicht:** Ein verteilter Dienst bestimmt sein Routing selbst. `docker compose down` heißt „diesen Dienst gibt es hier nicht mehr“, also verschwindet seine Route, so wie bei Traefiks Docker-Provider. `stop` heißt „kommt wieder“, also bleibt die Route und zeigt die Wartungsseite.
Merkregel: **Für Wartung `stop`, nie `down`.**
Auch eine angemeldete Wartung (siehe unten) rettet einen *entfernten* Container nicht. Sie gilt für die Routen, die der Server vom Knoten kennt, und ein entfernter Container meldet keine mehr.
## Die Werkzeuge
| | **maintenance** – „bin gleich wieder da“ | **drain** – „gebe meine Arbeit ab“ |
|---|---|---|
| Routen bei Traefik | bleiben, zeigen die Wartungsseite (503) | werden entfernt (404, sofern kein anderer Knoten die Domain bedient) |
| Dauer | befristet (Default 4 h, `--for`), endet von selbst | bis `resume` |
| Anlass | Patchen, Reboot, Migration | Abbau, Umzug |
| Wer darf | Admin am Server **oder** der Knoten selbst | nur Admin |
| Geltungsbereich | ganzer Knoten **oder** einzelner Dienst | ganzer Knoten |
Eine Knoten-Wartung gilt für **alle** Dienste, die der Agent dieses Hosts meldet, also für alle Container mit `traefik.enable=true` und alle Dienste aus `/etc/sultan.d`.
### Knoten-Wartung am Server (Admin)
```bash
cd /docker/sultan-server
docker compose exec sultan-server sultan token node maintenance --id dockweb11 \
--for 2h --reason "Kernel-Update" --public-reason "Geplante Wartung, gleich wieder da"
docker compose exec sultan-server sultan token node resume --id dockweb11
```
- `--for`: Dauer, z. B. `30m`, `2h`, `1d`; `0` = unbefristet. Das Ende steht auf der Wartungsseite und im `Retry-After`.
- `--reason`: intern (Log, `node list`).
- `--public-reason`: ersetzt den Standardtext der Wartungsseite (max. 300 Zeichen; noch nicht getrennt nach Sprache).
- `node resume` beendet Wartung **und** drain.
**Verzögerung:** Der Server wertet einmal pro Minute neu aus (`--refresh`). Wartung und `resume` greifen also nach **bis zu einer Minute**. Vor Beginn der Arbeiten prüfen, ob die Wartung aktiv ist:
```bash
docker compose exec sultan-server sultan token node list # Spalte Wartung: "bis …"
curl -sI https://www.example.de # HTTP 503
```
### Knoten-Wartung vom Backend aus (Kunde/Betreiber des Hosts)
Ohne Zugriff auf den Server, direkt auf dem Docker-Host:
```bash
cd /docker/sultan-agent
docker compose exec sultan-agent sultan agent maintenance on --for 2h --public-reason "Update läuft"
docker compose exec sultan-agent sultan agent maintenance off
```
Die Anfrage ist mit dem Schlüssel des Knotens signiert. Ein Knoten kann so nur sich selbst in Wartung setzen.
### Wartung für einen einzelnen Dienst
Per Label am Container. Die anderen Dienste des Hosts laufen normal weiter:
```yaml
labels:
- "sultan.maintenance=true"
- "sultan.maintenance.public_reason=Wir ziehen um – heute Abend wieder da"
```
```bash
docker compose up -d # Labels ändern = Container neu erzeugen; die Wartungsseite greift sofort
```
Zurück: Labels entfernen (oder `=false`), dann erneut `docker compose up -d`.
Für `/etc/sultan.d`-Dienste: `maintenance: true` bzw. `maintenance_public_reason` in der YAML-Datei.
### drain (Admin)
```bash
docker compose exec sultan-server sultan token node drain --id dockweb11
docker compose exec sultan-server sultan token node resume --id dockweb11
```
Die Routen verschwinden **sofort** (404). Sinnvoll vor dem Abbau eines Hosts oder wenn ein anderer Knoten die Domains übernimmt. Für eine Seite mit nur einem Backend ist **maintenance** die richtige Wahl.
## Abläufe
### Container aktualisieren (neues Image)
```bash
docker compose pull
docker compose up -d
```
`up -d` erzeugt den Container neu: alt entfernen, neu starten. Dazwischen kann für ein bis zwei Sekunden 404 kommen. Wer das nicht will, setzt vorher eine Wartung für den Knoten oder den Dienst und beendet sie danach.
### Host patchen und neu starten
```bash
# 1. Server: Wartung setzen und abwarten, bis sie aktiv ist (≤ 1 min)
docker compose exec sultan-server sultan token node maintenance --id dockweb11 --for 1h \
--public-reason "Geplante Wartung, gleich wieder da"
curl -sI https://www.example.de # 503?
# 2. Backend-Host
cd /docker/app && docker compose pull # Images vorab holen
docker compose stop # NICHT down
apt upgrade && reboot
# 3. nach dem Reboot
cd /docker/app && docker compose up -d # gestoppte Dienste starten nach dem Reboot nicht von selbst
docker compose -f /docker/sultan-agent/compose.yaml logs --tail 5 # "Mit Server verbunden"
curl -sI http://127.0.0.1:9080 # Dienst lokal ok?
# 4. Server: Wartung beenden (greift nach ≤ 1 min)
docker compose exec sultan-server sultan token node resume --id dockweb11
```
Den Agent nie mit `docker compose stop` anhalten: `restart: unless-stopped` startet ihn sonst nach dem Reboot nicht wieder. Ein Reboot ohne vorheriges `stop` ist für den Agent in Ordnung.
### Ungeplanter Ausfall
Nichts zu tun. Stürzt ein Container ab, zeigt Sultan die Wartungsseite, bis er wieder läuft. Ist der ganze Host weg, gilt das, bis die Lease abläuft. Ist ein Knoten länger als 15 Minuten getrennt (`--offline-alert-after`), alarmiert der Server über Slack/ntfy, sofern konfiguriert, und meldet sich wieder, sobald der Knoten zurück ist.
### Host abbauen
```bash
docker compose exec sultan-server sultan token node drain --id dockweb11 # Routen sofort weg
# Agent und Dienste auf dem Host stoppen, suldata/ löschen
docker compose exec sultan-server sultan token node delete --id dockweb11
```
## Grenzen (Stand heute)
- `public_reason` ist ein Text für beide Sprachen der Wartungsseite (zweisprachig geplant).
- Wartung/`resume` per CLI greifen erst beim nächsten Refresh (≤ 1 min).
- Echte Lastverteilung einer Domain über mehrere Knoten gibt es noch nicht. drain verschiebt also keine Last, sondern nimmt die Seite vom Netz.