Docker-Images bauen und veroeffentlichen / build-and-push (push) Successful in 5m51s
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]>
94 lines
4.9 KiB
Markdown
94 lines
4.9 KiB
Markdown
# 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
|
||
```
|