docs: fsGroup wirkt bei SMB/NFS nicht — Rechte gehoeren in die mountOptions
Docker Image bauen und veroeffentlichen / build-and-push (push) Successful in 2m8s
Docker Image bauen und veroeffentlichen / build-and-push (push) Successful in 2m8s
Der Kommentar am fsGroup-Feld behauptete, Kubernetes ordne damit JEDES gemountete Volume der Gruppe 1001 zu. Das stimmt nur fuer blockbasierten Speicher. Bei SMB/CIFS und NFS wird fsGroup ignoriert: diese Protokolle kennen keinen per-Datei-Unix-Besitz, den der Knoten nachtraeglich aendern koennte. Ohne uid/gid in den mountOptions erscheint dort alles als root:root, und der als uid 1001 laufende Container scheitert bei jedem Upload mit EACCES — also genau die Meldung "Die Datei konnte nicht gespeichert werden", ohne dass am Deployment etwas falsch aussieht. k8s/README.md bekommt dafuer einen eigenen Abschnitt: Diagnose im laufenden Pod, die noetigen mountOptions (uid=1001, gid=1001 zusaetzlich zu dir_mode/file_mode) und der Hinweis, dass Aenderungen daran erst beim naechsten Einhaengen greifen, ein Rollout-Restart also dazugehoert. Ebenfalls vermerkt: noperm umgeht die Rechtepruefung, statt den Besitz richtigzustellen — es ersetzt uid/gid nicht. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
625b73a8c8
commit
425fd76bc1
2 files changed
+85
-1
No files matched your search
@@ -51,8 +51,25 @@ spec:
|
||||
# Image bereits per chown gesetzten Besitzer von /app/uploads
|
||||
# vollstaendig, und der nicht-root laufende Container koennte trotzdem
|
||||
# keine Datei dort anlegen (EACCES bei jedem Admin-Upload). fsGroup
|
||||
# sorgt dafuer, dass Kubernetes JEDES gemountete Volume zusaetzlich der
|
||||
# sorgt dafuer, dass Kubernetes das gemountete Volume zusaetzlich der
|
||||
# Gruppe 1001 zuordnet und gruppen-schreibbar macht.
|
||||
#
|
||||
# ACHTUNG, GILT NICHT FUER JEDES BACKEND: fsGroup wirkt nur dort, wo
|
||||
# Kubernetes den Besitz tatsaechlich setzen kann — also bei
|
||||
# blockbasiertem Speicher. Bei SMB/CIFS und NFS wird es IGNORIERT, weil
|
||||
# diese Protokolle keinen per-Datei-Unix-Besitz kennen, den der Knoten
|
||||
# nachtraeglich aendern koennte. Dort gehoert die Zuordnung in die
|
||||
# mountOptions des PersistentVolume:
|
||||
#
|
||||
# mountOptions:
|
||||
# - uid=1001
|
||||
# - gid=1001
|
||||
# - dir_mode=0770
|
||||
# - file_mode=0660
|
||||
#
|
||||
# Ohne uid/gid erscheint bei SMB ALLES als root:root, und der Container
|
||||
# scheitert trotz fsGroup mit EACCES. Siehe k8s/README.md, Abschnitt
|
||||
# "Uploads lassen sich nicht speichern".
|
||||
securityContext:
|
||||
fsGroup: 1001
|
||||
containers:
|
||||
|
||||
@@ -221,6 +221,73 @@ Speicher- und CPU-Bedarf nicht mehr von der Größe des Knotens abhängt — sie
|
||||
erfolgreicher Upload beim nächsten Neustart trotzdem weg. Siehe
|
||||
„Bilder/Videos verschwinden nach jedem Redeploy" oben.
|
||||
|
||||
## Uploads lassen sich nicht speichern
|
||||
|
||||
Symptom: Im Admin erscheint „Die Datei konnte nicht gespeichert werden. Bitte
|
||||
informiere die Technik." Im Pod-Log steht dahinter ein `EACCES`.
|
||||
|
||||
Ursache ist fast immer der Besitz des gemounteten Volumes. Der Container läuft
|
||||
als **`nextjs`, uid 1001, Gruppe `nodejs` gid 1001** (siehe `Dockerfile`). Das
|
||||
Image setzt zwar `chown nextjs:nodejs /app/uploads`, aber ein darübergelegtes
|
||||
Volume überschreibt das vollständig.
|
||||
|
||||
Zuerst feststellen, was der Container tatsächlich sieht:
|
||||
|
||||
```bash
|
||||
kubectl -n wabenhain exec deploy/wabenhain-app -- sh -c \
|
||||
'id; ls -ld /app/uploads /app/invoices; \
|
||||
touch /app/uploads/.probe && echo SCHREIBEN_OK || echo SCHREIBEN_FEHLT'
|
||||
```
|
||||
|
||||
Der Fix hängt am Speicher-Backend — die beiden Wege gelten für verschiedene
|
||||
Fälle, nicht alternativ:
|
||||
|
||||
### Blockspeicher (die meisten CSI-Treiber)
|
||||
|
||||
`securityContext.fsGroup: 1001` im Deployment. Kubernetes ordnet das Volume
|
||||
dann der Gruppe 1001 zu und macht es gruppenschreibbar. Steht bereits in
|
||||
`05-app-deployment.yaml`.
|
||||
|
||||
### SMB/CIFS und NFS
|
||||
|
||||
**Hier wird `fsGroup` ignoriert.** Diese Protokolle kennen keinen
|
||||
per-Datei-Unix-Besitz, den der Knoten nachträglich ändern könnte; ohne
|
||||
Zuordnung erscheint alles als `root:root`, und der Container scheitert trotz
|
||||
`fsGroup` mit `EACCES`. Die Zuordnung gehört in die `mountOptions` des
|
||||
PersistentVolume:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
mountOptions:
|
||||
- vers=3.0
|
||||
- uid=1001 # muss zum Containerbenutzer passen
|
||||
- gid=1001
|
||||
- dir_mode=0770
|
||||
- file_mode=0660
|
||||
- mfsymlinks
|
||||
- nobrl # keine Byte-Range-Locks über SMB
|
||||
```
|
||||
|
||||
`dir_mode`/`file_mode` allein genügen nicht: sie bestimmen nur, welche Rechte
|
||||
angezeigt werden — wem die Datei gehört, entscheiden `uid`/`gid`.
|
||||
|
||||
`noperm` (der Client prüft Rechte gar nicht erst) wirkt in vielen Aufbauten
|
||||
ebenfalls, ist aber die schwächere Zusicherung: es umgeht die Prüfung, statt
|
||||
den Besitz richtigzustellen. `uid`/`gid` also auch dann setzen, wenn `noperm`
|
||||
bereits gesetzt ist.
|
||||
|
||||
**Änderungen an `mountOptions` greifen erst beim nächsten Einhängen.** Nach dem
|
||||
Anpassen des PV den Pod neu starten:
|
||||
|
||||
```bash
|
||||
kubectl -n wabenhain rollout restart deploy/wabenhain-app
|
||||
```
|
||||
|
||||
Lässt sich das PV nicht mehr ändern (bei bereits gebundenen PVs je nach
|
||||
Kubernetes-Version), PVC und PV löschen und neu anlegen. Bei
|
||||
`persistentVolumeReclaimPolicy: Retain` bleiben die Daten auf der Freigabe
|
||||
erhalten.
|
||||
|
||||
## Sicherung und Wiederherstellung
|
||||
|
||||
`07-backup-cronjob.yaml` legt jede Nacht um 03:15 Uhr eine
|
||||
|
||||
Reference in new issue
Block a user