No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Michael Behnke a74de86d46 docs: add TimescaleDB zero-downtime prerequisite/config docs, section and config animation
- docs/timescaledb-zero-downtime.md: necessity, AKS node pool + deployment configs, flow, verification, rollback, checklist
- scripts/make_tsdb_config_gif.py + assets/timescaledb-config.gif: shows taint, PDB, probes, spread, ordered update
- fix: PodDisruptionBudget minAvailable 2 (was 1) in both TimescaleDB GIFs
2026-10-13 07:52:07 +02:00
assets docs: add TimescaleDB zero-downtime prerequisite/config docs, section and config animation 2026-10-13 07:52:07 +02:00
docs docs: add TimescaleDB zero-downtime prerequisite/config docs, section and config animation 2026-10-13 07:52:07 +02:00
scripts docs: add TimescaleDB zero-downtime prerequisite/config docs, section and config animation 2026-10-13 07:52:07 +02:00
.gitignore feat: add AKS/Jenkins/OpenTofu animation and shared gif helper 2026-10-11 20:42:57 +02:00
AGENTS.md docs: add test README and AGENTS.md 2026-10-11 20:21:27 +02:00
README.md docs: add TimescaleDB zero-downtime prerequisite/config docs, section and config animation 2026-10-13 07:52:07 +02:00
requirements.txt feat: add pillow gif generator with six software-project animations 2026-10-11 20:37:15 +02:00

test

Scratch-Repository zum Ausprobieren von Agent-Workflows, Tooling und Konventionen. Hier wird nichts Produktives gebaut — der Inhalt dient als Spielwiese.

Zweck

  • Testen von opencode-Agents, Skills und Tools
  • Verifizieren von Git-, Formatierungs- und Build-Workflows
  • Ablegen von Wegwerf-Dateien, die jederzeit gelöscht werden dürfen

Struktur

.
├── README.md          # diese Datei
├── AGENTS.md          # Instruktionen für Agents in diesem Repo
├── requirements.txt   # Python-Abhängigkeiten (Pillow)
├── assets/            # generierte GIFs
├── scripts/           # Generator-Skripte
└── ...                # freie Test-Artefakte

Nutzung

Es gibt kein Build- oder Test-Setup. Alles läuft ad hoc:

git status        # Zustand prüfen
git diff          # Änderungen ansehen

Mermaid-Diagramme

Forgejo rendert Code-Blöcke mit der Sprache mermaid direkt als Grafik. Unten stehen mehrere Beispiele zum Ausprobieren des Renderings.

Ablaufdiagramm (flowchart)

flowchart TD
    A([Start]) --> B{Eingeloggt?}
    B -- ja --> C[Dashboard]
    B -- nein --> D[Login]
    D --> C
    C --> E([Ende])

Sequenzdiagramm

sequenceDiagram
    participant U as Nutzer
    participant S as Server
    U->>S: GET /api/state
    S-->>U: 200 OK (JSON)
    U->>S: POST /api/action
    S-->>U: 202 Accepted

Zustandsdiagramm

stateDiagram-v2
    [*] --> Idle
    Idle --> Running: start
    Running --> Idle: stop
    Running --> [*]: abort

Klassendiagramm

classDiagram
    class Device {
        +String id
        +String name
        +turnOn()
        +turnOff()
    }
    class Light {
        +int brightness
    }
    Device <|-- Light

ER-Diagramm

erDiagram
    USER ||--o{ ORDER : places
    ORDER ||--|{ ITEM : contains
    ITEM }o--|| PRODUCT : references

Gantt

gantt
    title Umsetzung
    dateFormat YYYY-MM-DD
    section Planung
    Analyse   :a1, 2026-10-01, 5d
    Konzept   :after a1, 3d
    section Umsetzung
    Bau       :2026-10-09, 7d

Torten-/Kreisdiagramm

pie title Verteilung
    "A" : 40
    "B" : 35
    "C" : 25

Git-Graph

gitGraph
    commit
    branch feature
    commit
    checkout main
    merge feature
    commit

Architektur-Diagramme

Zusätzliche Beispiele für Architektur-Sichten. Hinweis: Alles unter „Benötigt Mermaid ≥ 11" rendert auf älteren Forgejo-Instanzen ggf. nicht.

Schichtenarchitektur (flowchart mit subgraph)

flowchart TB
    subgraph Client
        WEB[Web-App]
        MOB[Mobile-App]
    end
    subgraph Edge
        LB[Load Balancer]
        GW[API Gateway]
    end
    subgraph Services
        AUTH[Auth-Service]
        ORDER[Order-Service]
        CAT[Catalog-Service]
    end
    subgraph Data
        DB[(PostgreSQL)]
        CACHE[(Redis)]
        Q[[Message Queue]]
    end
    WEB --> LB
    MOB --> LB
    LB --> GW
    GW --> AUTH
    GW --> ORDER
    GW --> CAT
    AUTH --> CACHE
    ORDER --> DB
    ORDER --> Q
    CAT --> DB
    Q --> ORDER

C4 – Systemkontext

C4Context
    title Systemkontext
    Person(user, "Nutzer", "Verwaltet Geräte")
    System(app, "Device Plattform", "Steuert und überwacht Geräte")
    System_Ext(hub, "Geräte-Hub", "Lokaler Gateway")
    Rel(user, app, "nutzt", "HTTPS")
    Rel(app, hub, "steuert", "REST")

C4 – Container

C4Container
    title Container-Diagramm
    Person(user, "Nutzer")
    Container(spa, "Web-UI", "SPA", "Darstellung")
    Container(api, "API", "Go", "Geschäftslogik")
    ContainerDb(db, "Datenbank", "PostgreSQL", "Persistenz")
    Rel(user, spa, "benutzt")
    Rel(spa, api, "JSON/HTTPS")
    Rel(api, db, "liest/schreibt")

Blockdiagramm

block-beta
    columns 3
    UI["Frontend"]:3
    API["API Gateway"]:3
    svc1["Service A"] svc2["Service B"] svc3["Service C"]
    db[("DB")]:3

Architektur (benötigt Mermaid ≥ 11)

architecture-beta
    group cloud(cloud)[Cloud]
    service api(server)[API] in cloud
    service db(database)[DB] in cloud
    service user(internet)[User]
    user:R -- L:api
    api:R -- L:db

Mindmap

mindmap
    root((System))
        Frontend
            Web
            Mobile
        Backend
            Auth
            Orders
        Daten
            Postgres
            Redis

Weitere Diagrammtypen

C4 – Deployment

C4Deployment
    title Deployment
    Deployment_Node(browser, "Browser", "Chrome/Firefox") {
        Container(spa, "Web-UI", "SPA", "Oberfläche")
    }
    Deployment_Node(k8s, "Kubernetes", "Cluster") {
        Container(api, "API", "Go", "Logik")
        ContainerDb(db, "DB", "PostgreSQL", "Daten")
    }
    Rel(spa, api, "JSON/HTTPS")
    Rel(api, db, "SQL")

Sankey (Flüsse)

sankey-beta

Frontend,API,50
Mobile,API,30
API,Auth,20
API,Orders,60
Orders,DB,60
Auth,Cache,20

Quadranten-Chart (Priorisierung)

quadrantChart
    title Priorisierung
    x-axis Geringer Aufwand --> Hoher Aufwand
    y-axis Geringer Nutzen --> Hoher Nutzen
    quadrant-1 Schnell umsetzen
    quadrant-2 Planen
    quadrant-3 Verwerfen
    quadrant-4 Ggf. später
    Feature A: [0.3, 0.8]
    Feature B: [0.7, 0.7]
    Feature C: [0.8, 0.2]

XY-Chart (Balken + Linie)

xychart-beta
    title "Latenz pro Tag (ms)"
    x-axis [Mo, Di, Mi, Do, Fr]
    y-axis 0 --> 400
    bar [120, 200, 150, 320, 180]
    line [120, 200, 150, 320, 180]

Anforderungsdiagramm

requirementDiagram
    requirement test_req {
        id: 1
        text: System muss erreichbar sein
        risk: high
        verifymethod: test
    }
    element test_entity {
        type: simulation
    }
    test_entity - satisfies -> test_req

Zeitstrahl

timeline
    title Projektverlauf
    2026-09 : Analyse
    2026-10 : Konzept
    2026-11 : Umsetzung
    2026-12 : Test

User Journey

journey
    title Nutzerreise
    section Anmeldung
      Seite öffnen: 5: Nutzer
      Login: 3: Nutzer
    section Nutzung
      Dashboard: 4: Nutzer
      Aktion ausführen: 2: Nutzer

Kanban (benötigt Mermaid ≥ 11.1)

kanban
    todo[Todo]
        t1[Aufgabe 1]
        t2[Aufgabe 2]
    doing[In Arbeit]
        d1[Aufgabe 3]
    done[Erledigt]
        e1[Aufgabe 4]

Animierte GIFs (Python + Pillow)

Alle Animationen werden von scripts/make_gifs.py erzeugt — nur Pillow, kein Netz, keine externen Binaries, damit deterministisch und leicht reproduzierbar:

python3 -m pip install -r requirements.txt
python3 scripts/make_gifs.py

1. CI-Pipeline

Stufen Build → Test → Deploy laufen nacheinander durch.

CI-Pipeline

2. Datenfluss

Request/Response wandert durch Client → API → Service → DB.

Datenfluss

3. Rolling Deployment

Instanzen werden nacheinander auf die neue Version aktualisiert.

Rolling Deployment

4. Test-Coverage

Balken wachsen auf die Zielwerte pro Modul.

Test-Coverage

5. Ladeanzeige

Rotierender Loader mit Fortschritt in Prozent.

Ladeanzeige

6. Kanban-Board

Eine Karte wandert durch die Spalten.

Kanban

AKS-Cluster per Jenkins + OpenTofu

Eine Jenkins-Pipeline rollt per OpenTofu (azurerm-Provider) einen AKS-Cluster in Azure aus: Resource Group → Netzwerk → Control Plane → Node Pool → Nodes Ready → Pods laufen.

Jenkins + OpenTofu -> Azure AKS

Erzeugt wird das GIF von scripts/make_aks_gif.py; die gemeinsamen Zeichen-Helfer liegen in scripts/gifkit.py:

python3 scripts/make_aks_gif.py

AKS-Upgrade: Control Plane + Node-Image-Rollover

Visualisiert ein AKS-Upgrade: Preflight-Checks → Control-Plane-Upgrade (v1.30 → v1.31, Azure-managed) → rolling Node-Image-Upgrade je Node mit Surge-Node: cordon → drain → Image ersetzen → Pods neu planen → Surge-Node entfernen.

AKS Upgrade

Erzeugt von scripts/make_aks_upgrade_gif.py:

python3 scripts/make_aks_upgrade_gif.py

TimescaleDB Zero-Downtime-Upgrade (eigener Node Pool)

TimescaleDB läuft als StatefulSet in einem dedizierten Node Pool. Beim Upgrade werden zuerst die Replicas gerollt (restart → resync → streaming), dann per Switchover eine aktualisierte Replica zum PRIMARY befördert und zuletzt das alte Primary – nun Replica – aktualisiert. Ein PRIMARY ist dabei immer online; der Write-Traffic läuft durchgängig weiter (EKG-Leiste unten).

TimescaleDB Zero-Downtime Upgrade

Erzeugt von scripts/make_timescaledb_gif.py:

python3 scripts/make_timescaledb_gif.py

MQTT- und HTTPS-Traffic zum AKS (NSG, WAF, Envoy, Keycloak)

Zwei Traffic-Pfade zu einer Web-Applikation auf AKS:

  • MQTT: IoT-Gerät → NSG (allow 8883/tcp) → MQTT-Broker im Cluster
  • HTTPS: Browser → Front Door / AppGW v2 + WAF (TLS-Terminierung, OWASP-CRS) → Envoy Ingress → Web-App, Auth über Keycloak (OIDC/PKCE)

Ein Paket wandert animiert über die Pfade; NSG, WAF, Envoy, Web-App und Keycloak leuchten jeweils beim Passieren auf. Unten eine Statuslegende.

MQTT + HTTPS Traffic zum AKS

Erzeugt von scripts/make_traffic_gif.py:

python3 scripts/make_traffic_gif.py

TimescaleDB-Upgrade: Notwendigkeit & Konfigurationen

Warum überhaupt? TimescaleDB ist zustandsbehaftet: ein naiver Pod-Neustart oder ein Node-Drain ohne Schutz bricht den laufenden Write-Traffic ab bzw. macht die Replikation handlungsunfähig. Unterbrechungsfrei geht es nur mit Replikation + Failover, Platz zum Ausweichen (dedizierter Node Pool) und Schutz gegen gleichzeitige Störungen (PDB, Probes, Spread).

TimescaleDB Konfiguration

Wo wird was konfiguriert?

Konfiguration Zweck Ort
Node Pool tsdb, --zones 1 2 3 Isolation, Zonen-Verteilung AKS (az aks nodepool add)
node-taints workload=timescaledb:NoSchedule nur DB-Pods landen dort AKS + Deployment (tolerations)
--max-surge 1, Wartungsfenster Node-Updates kontrolliert AKS
PodDisruptionBudget minAvailable: 2 höchstens 1 Pod gleichzeitig weg Deployment
readinessProbe: pg_isready kein Traffic auf unfertige Pods Deployment
topologySpreadConstraints Pods über Zonen Deployment
podManagementPolicy: OrderedReady ein Pod pro Schritt Deployment
Streaming Replication + Switchover ein Primary bleibt immer online Deployment (Patroni / CloudNativePG)

Die wichtigsten Deployment-Snippets:

# PDB: bei 3 Replikas darf nur 1 Pod weg -> minAvailable: 2
apiVersion: policy/v1
kind: PodDisruptionBudget
spec:
  minAvailable: 2
---
# Toleration + Node-Bindung an den dedizierten Pool
tolerations:
  - key: workload
    operator: Equal
    value: timescaledb
    effect: NoSchedule
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
            - key: workload
              operator: In
              values: ["timescaledb"]
---
readinessProbe:
  exec: { command: ["/bin/sh", "-c", "pg_isready -U postgres -h 127.0.0.1"] }
  periodSeconds: 5

Vollständig (Node Pool per az/OpenTofu, StatefulSet, Probes, Spread, Patroni/CloudNativePG, Ablauf, Verifikation, Rollback, Checkliste): docs/timescaledb-zero-downtime.md

Erzeugt von scripts/make_tsdb_config_gif.py:

python3 scripts/make_tsdb_config_gif.py

Hinweise

  • Keine Secrets, PII oder arbeitsvertraulichen Daten ablegen.
  • Dateien in diesem Repo dürfen jederzeit ohne Rückfrage geändert oder gelöscht werden.
  • Für echte Projekte ein eigenes Repository anlegen.