refactor(k8s): schlanker Umfang, Postgres und Medien auf SMB
Docker-Images bauen und veroeffentlichen / build-and-push (push) Successful in 2m17s
Docker-Images bauen und veroeffentlichen / build-and-push (push) Successful in 2m17s
Auf Wunsch des Betreibers auf das Noetige reduziert: StatefulSet PostgreSQL, Services, Ingress, App-Deployment, zwei SMB-PersistentVolumes (Postgres-Daten, Medien). Beibehalten nach Absprache: Worker-CronJob (Folgeraten, Reservierungsfreigabe, Mail-Wiederholung), ConfigMap und die NetworkPolicies (Sicherheitsbefund Rate-Limit-Umgehung). - Migration als initContainer im App-Deployment statt eigenem Job - Entfernt: Backup-CronJob/-Volume (NAS sichert die Freigabe), Migrations-CronJob, PodDisruptionBudget, HTTP-Redirect-Ingress und Middleware, Namespace-Objekt (einmalig von Hand anzulegen) - PostgreSQL auf SMB als bewusste, dokumentierte Ausnahme mit hard, cache=strict, SMB 3.1.1 + seal, uid 70 / 0700 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
974c403a8b
commit
c84eb1e740
12 files changed
+200
-327
No files matched your search
@@ -1,6 +1,8 @@
|
||||
# Ingress fuer Traefik mit cert-manager.
|
||||
# Anpassen: Host (auch in APP_URL, kustomization.yaml), ingressClassName
|
||||
# Anpassen: Host (auch APP_URL in kustomization.yaml), ingressClassName
|
||||
# ("kubectl get ingressclass"), ClusterIssuer, TLS-Secret-Name.
|
||||
# HTTP->HTTPS-Umleitung erwartet dieses Manifest EntryPoint-weit in Traefik
|
||||
# (Helm: ports.web.redirections.entryPoint.to=websecure).
|
||||
#
|
||||
# X-Forwarded-For/X-Real-Ip: Rate Limits verlassen sich darauf, dass Traefik
|
||||
# vom Client mitgeschickte Werte verwirft. Dafuer im Traefik-EntryPoint
|
||||
@@ -30,35 +32,3 @@ spec:
|
||||
name: artista-modelcamp-app
|
||||
port:
|
||||
name: http
|
||||
---
|
||||
# HTTP -> HTTPS. Entfaellt, wenn Traefik das bereits EntryPoint-weit tut
|
||||
# (Helm: ports.web.redirections.entryPoint.to=websecure).
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: artista-modelcamp-http-redirect
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
traefik.ingress.kubernetes.io/router.middlewares: artista-artista-modelcamp-redirect-https@kubernetescrd
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- host: modelcamp.example.org
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: artista-modelcamp-app
|
||||
port:
|
||||
name: http
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: artista-modelcamp-redirect-https
|
||||
spec:
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: true
|
||||
@@ -7,7 +7,7 @@ namespace: artista
|
||||
resources:
|
||||
- ../../base
|
||||
- ingress.yaml
|
||||
# Medien und Sicherungen auf SMB (PostgreSQL bewusst nicht, siehe Datei).
|
||||
# PostgreSQL-Daten und Medien auf SMB.
|
||||
# Ohne SMB: diese Zeile und die beiden PVC-Patches unten entfernen.
|
||||
- smb-volumes.yaml
|
||||
|
||||
@@ -32,14 +32,14 @@ patches:
|
||||
- op: add
|
||||
path: /spec/volumeName
|
||||
value: artista-modelcamp-media-smb
|
||||
- target: { kind: PersistentVolumeClaim, name: artista-modelcamp-db-backup }
|
||||
- target: { kind: PersistentVolumeClaim, name: artista-modelcamp-postgres-data }
|
||||
patch: |-
|
||||
- op: add
|
||||
path: /spec/storageClassName
|
||||
value: ""
|
||||
- op: add
|
||||
path: /spec/volumeName
|
||||
value: artista-modelcamp-db-backup-smb
|
||||
value: artista-modelcamp-postgres-smb
|
||||
- target: { kind: ConfigMap, name: artista-modelcamp-config }
|
||||
patch: |-
|
||||
- op: replace
|
||||
|
||||
@@ -6,22 +6,60 @@
|
||||
# und das Zugangs-Secret "artista-modelcamp-smb" (k8s/secret.example.yaml).
|
||||
#
|
||||
# ANZUPASSEN: "source" (//<nas>/<freigabe>/<ordner>) je Volume. Die Ordner
|
||||
# muessen auf der Freigabe bereits existieren.
|
||||
# muessen auf der Freigabe bereits existieren; der Postgres-Ordner leer.
|
||||
#
|
||||
# BEWUSST NICHT AUF SMB: das PostgreSQL-Datenverzeichnis. SMB bildet
|
||||
# POSIX-Sperren, fsync-Garantien und Dateirechte nicht so ab, wie PostgreSQL
|
||||
# sie fuer Absturzsicherheit braucht (Briefing §13). Die Datenbank bleibt auf
|
||||
# Blockspeicher und wird taeglich per pg_dump auf das Backup-Volume unten
|
||||
# gesichert — damit liegen die Geschaeftsdaten trotzdem auf dem NAS.
|
||||
#
|
||||
# Rechte: fsGroup wirkt auf SMB nicht. Besitz und Rechte setzen deshalb
|
||||
# uid/gid/dir_mode/file_mode in den mountOptions (Muster aus Wabenhain).
|
||||
# Aenderungen an mountOptions greifen erst beim naechsten Einhaengen.
|
||||
# reclaimPolicy Retain: Loeschen von PVC/PV laesst die Dateien auf dem NAS.
|
||||
# Beide Verbindungen verschluesselt (SMB 3.1.1 + seal); das NAS muss
|
||||
# SMB-Verschluesselung erlauben. fsGroup wirkt auf SMB nicht: Besitz und
|
||||
# Rechte setzen uid/gid/dir_mode/file_mode. reclaimPolicy Retain: Loeschen
|
||||
# von PVC/PV laesst die Dateien auf dem NAS.
|
||||
# Keine eigene Sicherung im Cluster: die Freigabe wird auf dem NAS gesichert.
|
||||
|
||||
# --- Medien (Bilder/Videos) ----------------------------------------------------
|
||||
# Die App liest nur (readOnly-Mount). Neue Bilder legst du direkt ueber die
|
||||
# SMB-Freigabe ab, z. B. vom Windows-Explorer aus.
|
||||
# --- PostgreSQL-Datenverzeichnis ------------------------------------------------
|
||||
# BEWUSSTE AUSNAHME (Entscheidung des Betreibers): Datenbank auf SMB.
|
||||
# Risiko: SMB garantiert Sperren/fsync nicht in jedem Fall wie ein lokales
|
||||
# Dateisystem; bei Netzwerk- oder NAS-Ausfall waehrend Schreibvorgaengen kann
|
||||
# die Datenbank beschaedigt werden. Die Optionen unten minimieren das:
|
||||
# hard E/A wartet bei Netzstoerung statt Fehler an PostgreSQL zu
|
||||
# melden (kein "soft"-Abbruch mitten im Schreiben)
|
||||
# cache=strict strikte Cache-Kohaerenz, fsync geht bis zum Server
|
||||
# nobrl keine Byte-Range-Locks (PostgreSQL braucht sie nicht)
|
||||
# uid/gid 70, 0700/0600 PostgreSQL verlangt ein privates Datenverzeichnis
|
||||
# Sicherung: nur NAS-Snapshots, die atomar sind (Btrfs/ZFS-Snapshot der ganzen
|
||||
# Freigabe), sind fuer ein laufendes Datenverzeichnis konsistent. Einfaches
|
||||
# Dateikopieren waehrend des Betriebs ergibt KEINE brauchbare Sicherung.
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: artista-modelcamp-postgres-smb
|
||||
spec:
|
||||
capacity:
|
||||
storage: 10Gi
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
storageClassName: ""
|
||||
mountOptions:
|
||||
- vers=3.1.1
|
||||
- seal
|
||||
- hard
|
||||
- cache=strict
|
||||
- uid=70
|
||||
- gid=70
|
||||
- dir_mode=0700
|
||||
- file_mode=0600
|
||||
- mfsymlinks
|
||||
- nobrl
|
||||
csi:
|
||||
driver: smb.csi.k8s.io
|
||||
volumeHandle: artista-modelcamp-postgres-smb
|
||||
volumeAttributes:
|
||||
source: //nas.example.lan/artista/modelcamp-postgres
|
||||
nodeStageSecretRef:
|
||||
name: artista-modelcamp-smb
|
||||
namespace: artista
|
||||
---
|
||||
# --- Medien (Bilder/Videos) ------------------------------------------------------
|
||||
# Die App liest nur. Neue Bilder legst du direkt ueber die SMB-Freigabe ab,
|
||||
# z. B. vom Windows-Explorer aus.
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
@@ -34,7 +72,7 @@ spec:
|
||||
storageClassName: ""
|
||||
mountOptions:
|
||||
- vers=3.1.1
|
||||
- seal # SMB3-Verschluesselung: keine Klartextdaten im Netz
|
||||
- seal
|
||||
- uid=1001 # Containerbenutzer "nextjs" (Dockerfile)
|
||||
- gid=1001
|
||||
- dir_mode=0550 # App liest nur; Schreiben ausschliesslich ueber das NAS
|
||||
@@ -43,40 +81,9 @@ spec:
|
||||
- nobrl
|
||||
csi:
|
||||
driver: smb.csi.k8s.io
|
||||
# Muss im Cluster eindeutig sein.
|
||||
volumeHandle: artista-modelcamp-media-smb
|
||||
volumeAttributes:
|
||||
source: //nas.example.lan/artista/modelcamp-media
|
||||
nodeStageSecretRef:
|
||||
name: artista-modelcamp-smb
|
||||
namespace: artista
|
||||
---
|
||||
# --- Datenbank-Sicherungen ------------------------------------------------------
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: artista-modelcamp-db-backup-smb
|
||||
spec:
|
||||
capacity:
|
||||
storage: 10Gi
|
||||
# ReadWriteOnce: nur der Backup-Job haengt dieses Volume ein.
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
storageClassName: ""
|
||||
mountOptions:
|
||||
- vers=3.1.1
|
||||
- seal # SMB3-Verschluesselung: keine Klartextdaten im Netz
|
||||
- uid=70 # Benutzer "postgres" im pg_dump-Job (postgres:18-alpine)
|
||||
- gid=70
|
||||
- dir_mode=0700 # Sicherungen enthalten personenbezogene Daten
|
||||
- file_mode=0600
|
||||
- mfsymlinks
|
||||
- nobrl
|
||||
csi:
|
||||
driver: smb.csi.k8s.io
|
||||
volumeHandle: artista-modelcamp-db-backup-smb
|
||||
volumeAttributes:
|
||||
source: //nas.example.lan/artista/modelcamp-backup
|
||||
nodeStageSecretRef:
|
||||
name: artista-modelcamp-smb
|
||||
namespace: artista
|
||||
Reference in new issue
Block a user