Files
Artista-Filmcamp/k8s/README.md
T
Nick SzaunigandClaude Opus 5.5 f2b548cb98
Docker-Images bauen und veroeffentlichen / build-and-push (push) Successful in 5m51s
chore(k8s): Images auf CI-Build pinnen statt :latest
App, Migration und Worker zeigen auf sha-<commit> mit
imagePullPolicy IfNotPresent. Damit gibt es ein Rollback per
rollout undo, und ein Neustart zieht nicht mehr ungeprueft das
neueste Image (oder scheitert, wenn Gitea gerade nicht laeuft).
README beschreibt das Ausrollen mit kubectl set image.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-12 05:27:47 +02:00

94 lines
4.9 KiB
Markdown
Raw 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.
# ARTISTA Modelcamp in Kubernetes (RKE2)
Rohe Manifeste wie bei Wabenhain, Nummerierung = Reihenfolge. Voraussetzungen im Cluster (wie bei Wabenhain):
- **Traefik** als Ingress-Controller (IngressClass `traefik`)
- **cert-manager** mit dem ClusterIssuer `letsencrypt-prod`
- **csi-driver-smb** für die SMB-Volumes
Prüfen:
```bash
kubectl get ingressclass
kubectl get clusterissuer letsencrypt-prod
kubectl get csidrivers | grep smb
```
## Einmalige Vorbereitung
1. **Images:** `.gitea/workflows/docker-build.yml` baut bei jedem Push auf `main` die Images `git.encry.de/nick.rosenloecher/artista-modelcamp:latest` und `…-tools:latest`. Voraussetzung ist das Repo-Secret `REGISTRY_TOKEN` (Personal Access Token mit `package`-Scope), wie bei Wabenhain.
2. **csi-driver-smb** (falls noch nicht vorhanden):
```bash
helm repo add csi-driver-smb https://raw.githubusercontent.com/kubernetes-csi/csi-driver-smb/master/charts
helm install csi-driver-smb csi-driver-smb/csi-driver-smb -n kube-system
```
3. **NAS:** Die Ordner `artista/modelcamp-postgres` (leer) und `artista/modelcamp-media` anlegen und SMB-Verschlüsselung erlauben. `nas.example.lan` in `03-storage.yaml` anpassen.
4. **Domain:** `modelcamp.example.org` in `01-configmap.yaml` (APP_URL) und `06-ingress.yaml` (2×) ersetzen. Der DNS-Eintrag muss auf den Cluster zeigen, sonst stellt cert-manager kein Zertifikat aus.
5. **Secrets:** `cp k8s/02-secret.yaml.example k8s/02-secret.yaml` und ausfüllen. Die Datei steht in `.gitignore`, bitte **nie** mit echten Werten committen.
## Deployment (auch für einen kompletten Neuaufbau)
```bash
kubectl apply -f k8s/00-namespace.yaml
kubectl apply -f k8s/01-configmap.yaml
kubectl apply -f k8s/02-secret.yaml
kubectl apply -f k8s/03-storage.yaml
kubectl apply -f k8s/04-postgres.yaml
kubectl wait --for=condition=ready pod -l app=artista-modelcamp-postgres -n artista --timeout=180s
kubectl apply -f k8s/05-app-deployment.yaml
kubectl apply -f k8s/06-ingress.yaml
kubectl apply -f k8s/07-worker-cronjob.yaml
kubectl apply -f k8s/08-networkpolicy.yaml
```
Die Migration läuft automatisch als initContainer vor dem App-Start. Den Stand zeigen:
```bash
kubectl rollout status deployment/artista-modelcamp-app -n artista
kubectl get certificate -n artista # READY muss True werden (meist < 2 Minuten)
```
**Neuaufbau mit `kubectl delete namespace artista`:** Die PersistentVolumes (`artista-modelcamp-postgres`, `artista-modelcamp-media`) gehören keinem Namespace und bleiben auf `Released` stehen. Die Daten auf dem NAS bleiben erhalten (`Retain`). Damit die neuen Claims sie wieder binden können, vor dem erneuten Anlegen:
```bash
kubectl patch pv artista-modelcamp-postgres -p '{"spec":{"claimRef":null}}'
kubectl patch pv artista-modelcamp-media -p '{"spec":{"claimRef":null}}'
```
Soll die Datenbank wirklich leer neu starten, den Ordner `modelcamp-postgres` auf dem NAS vorher leeren.
## Erstes Admin-Konto
E-Mail und Name ersetzen. Das einmalige Passwort wird ausgegeben, die 2FA richtest du bei der ersten Anmeldung unter `/admin` ein.
```bash
kubectl -n artista run admin-create --rm -i --restart=Never \
--image=git.encry.de/nick.rosenloecher/artista-modelcamp-tools:latest --labels=db-client=true \
--overrides='{"spec":{"securityContext":{"runAsNonRoot":true,"runAsUser":1001,"seccompProfile":{"type":"RuntimeDefault"}},"containers":[{"name":"admin-create","image":"git.encry.de/nick.rosenloecher/artista-modelcamp-tools:latest","command":["tsx","scripts/create-admin.ts","--email","[email protected]","--name","Dein Name"],"envFrom":[{"configMapRef":{"name":"artista-modelcamp-config"}},{"secretRef":{"name":"artista-modelcamp-secrets"}}],"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]}}}]}}'
```
## Bei einem neuen Image (Redeploy)
Die Manifeste sind auf einen Build gepinnt, nicht auf `:latest`. Den Tag `sha-<commit>` (7 Zeichen) zeigt der CI-Lauf in der Zusammenfassung. App und Werkzeuge immer mit demselben Tag ausrollen:
```bash
TAG=sha-<commit>
kubectl -n artista set image deployment/artista-modelcamp-app \
migrate=git.encry.de/nick.rosenloecher/artista-modelcamp-tools:$TAG \
app=git.encry.de/nick.rosenloecher/artista-modelcamp:$TAG
kubectl -n artista set image cronjob/artista-modelcamp-worker \
worker=git.encry.de/nick.rosenloecher/artista-modelcamp-tools:$TAG
kubectl -n artista rollout status deployment/artista-modelcamp-app
```
Zurueck auf den vorherigen Stand: `kubectl -n artista rollout undo deployment/artista-modelcamp-app` (den CronJob dann wieder auf den alten Tag setzen).
## Fehlersuche
```bash
kubectl -n artista get certificate,certificaterequest,order,challenge # Zertifikat
kubectl -n artista describe challenge
kubectl -n artista logs deploy/artista-modelcamp-app -c migrate # Migration
kubectl -n artista logs deploy/artista-modelcamp-app -c app # App
kubectl -n artista get events --sort-by=.lastTimestamp | tail -20
```