Dacă LXC-ul tău neprivilegiat a început să afișeze „Status 30” după un upgrade la Proxmox 9.x, iar containerul folosește MergerFS, NFS sau alt bind mount non-nativ, problema nu este de obicei în interiorul containerului. Este aproape întotdeauna la nivelul mount-ului. Pe sistemele afectate, containerul eșuează la pornire pentru că Proxmox încearcă să păstreze sau să propage informațiile de ownership peste un bind mount pe care filesystem-ul sau stack-ul de storage de dedesubt nu îl gestionează așa cum se așteaptă Proxmox. Rezultatul este urât și înșelător: LXC-ul poate să nu mai pornească deloc sau poate părea montat, dar să se comporte ca read-only.

Din experiența noastră administrând medii Proxmox, acesta este exact genul de incident care consumă timp pentru că simptomul vizibil indică în direcția greșită. Jellyfin, Plex, aplicațiile Arr, joburile de backup sau importurile media încep să se plângă de storage read-only, „os error 30” sau mount points stricate, iar administratorii încep să caute probleme de permisiuni în aplicație, în interiorul containerului. De cele mai multe ori, asta este muncă pierdută. Dacă host-ul nu poate pregăti mount-ul corect pentru LXC-ul neprivilegiat, containerul nu a avut niciodată o cale de storage curată de la început.

Acest runbook este pentru modelul din lumea reală pe care oamenii chiar îl folosesc: LXC-uri neprivilegiate cu pool-uri MergerFS, share-uri NFS sau storage mixt montat pe host și expus apoi în container. Nu este un articol generic despre containere versus mașini virtuale. Dacă ai nevoie ulterior de contextul mai larg, ServerSpan îl acoperă deja în Când să rulezi un workload în Proxmox LXC vs KVM în 2026. Acest articol este calea practică de incident response pentru proxmox status 30 unprivileged lxc.

Ce înseamnă de obicei „Status 30” în acest scenariu Proxmox 9.x

„Status 30” nu este o eroare frumoasă și auto-explicativă. În contextul acesta înseamnă de obicei că LXC-ul a lovit o problemă de mount sau de filesystem suficient de devreme încât pornirea sau accesul ulterior la scriere au eșuat, dar simptomul pe care îl vezi în față este generic. Pe sistemele Proxmox 9.1.5 afectate, indiciile utile sunt în logurile LXC și ale host-ului, nu în eroarea scurtă din GUI.

Indiciile tipice includ:

  • failed to propagate uid and gid to mountpoint: Operation not permitted
  • failed to propagate uid and gid to mountpoint: Read-only file system
  • startup for container 'CTID' failed
  • Aplicații din container care raportează erori de filesystem read-only, chiar dacă mount-ul de pe host pare în regulă

Interpretarea practică este simplă. Host-ul încă poate vedea, în multe cazuri, calea NFS sau MergerFS. Containerul nu o mai poate consuma corect prin vechiul drum de bind mount pe care îl foloseai. De aceea, eliminarea mount point-ului lasă adesea containerul să pornească imediat din nou.

Pasul 1: confirmă dacă lovești regresia de bind mounts din 9.1.5 sau o problemă de configurare apărută după

Nu începe să rescrii configuri până nu știi exact pe ce versiuni de pachete rulezi. Rapoartele din forumul Proxmox au arătat regresia după 9.1.5, iar rapoartele ulterioare au arătat că pve-container 6.1.1 a rezolvat regresia de bind mounts pentru mulți utilizatori NFS. Așa că prima întrebare nu este „cum remapez UID-uri?”. Prima întrebare este „sunt încă pe versiunea de pachet care este stricată?”.

pveversion -v | egrep 'pve-manager|pve-container|pve-kernel'
apt policy pve-container

Dacă ești încă pe drumul pachetelor afectate din zona 6.1.0, actualizează mai întâi înainte să faci chirurgie pe configurația containerului.

apt update
apt install pve-container
pveversion -v | grep pve-container

Dacă ești încă în outage și ai nevoie de un rollback de urgență în timp ce pregătești remedierea reală, calea temporară de downgrade documentată în forum a fost:

apt install pve-container=6.0.18

Asta nu este o strategie pe termen lung. Să rămâi blocat pe o versiune veche de pve-container este o măsură temporară, nu o soluție. Ținta reală este să ajungi pe versiunea reparată a pachetului și apoi să verifici dacă designul tău de bind mounts pentru MergerFS sau NFS mai are nevoie de o abordare manuală bazată pe lxc.mount.entry.

Pasul 2: capturează configurația care eșuează și logurile reale

După ce ai clarificat nivelul pachetului, capturează configurația exactă înainte să o atingi. În Proxmox, asta înseamnă atât configurația CT-ului, cât și diagnosticul live al mount-ului.

CTID=108
cp /etc/pve/lxc/${CTID}.conf /root/${CTID}.conf.bak.$(date +%F-%H%M%S)

pct config ${CTID}
grep -E '^(mp[0-9]+:|lxc.mount.entry:|lxc.idmap:|unprivileged:|features:)' /etc/pve/lxc/${CTID}.conf

Apoi pornește containerul în foreground cu debug logging activ, ca să vezi direct eșecul de mount:

lxc-start -n ${CTID} -F -l DEBUG -o /tmp/${CTID}-lxc-debug.log

Și într-un alt shell:

journalctl -b | egrep -i "lxc|pct|mount|idmap|read-only|status 30"
mount | egrep 'mergerfs|nfs|\.pve-staged-mounts'
findmnt -T /mnt/media
stat -f -c %T /mnt/media

Aceste comenzi dovedesc lucruri diferite:

  • lxc-start ... DEBUG arată eșecul real din pre-start.
  • journalctl te ajută să corelezi pornirea containerului cu refuzul mount-ului la nivel de kernel.
  • mount și findmnt confirmă ce a montat de fapt host-ul.
  • stat -f -c %T te ajută să vezi dacă ești pe un filesystem FUSE sau network-backed, nu pe unul local nativ.

Dacă LXC-ul merge fără mount, dar eșuează cu el, iar logurile indică propagare UID/GID sau comportament read-only, oprește-te din a da vina pe stack-ul de aplicație. Ești clar în teritoriu de mount-layer acum.

Pasul 3: identifică capcana vechiului mpX

Aici se lovesc cei mai mulți oameni. Configurația containerului are un mount point old-style, de genul:

mp0: /mnt/media,mp=/media,ro=1

Asta a fost suficient de bun pentru multe setup-uri reale o perioadă lungă. Apoi Proxmox a înăsprit drumul de bind-mount handling. Storage-ul local nativ a supraviețuit de obicei. MergerFS, NFS și alte layout-uri non-native nu prea au supraviețuit.

Dacă storage-ul tău este:

  • MergerFS
  • NFS montat pe host și apoi bind-mounted în LXC
  • Alt storage bazat pe FUSE sau stratificat

atunci mount-urile vechi de tip mpX sunt primul lucru pe care trebuie să-l suspectezi.

Tocmai de aceea containerele fără bind mounts continuă adesea să pornească normal după același update Proxmox. Problema nu este containerul în sine. Problema este interacțiunea dintre mount-uri într-un LXC neprivilegiat, bind-mount handling și backend-ul tău de storage.

Pasul 4: înlocuiește mpX cu lxc.mount.entry acolo unde trebuie

Dacă încă vezi eșecuri după update la o versiune reparată de pve-container, sau dacă rulezi MergerFS ori alt stack bazat pe FUSE care rămâne fragil pe vechiul drum, oprește-te din a folosi mpX pentru acel mount și treci la linii directe lxc.mount.entry.

Mai întâi elimină sau comentează vechea linie de mount point din /etc/pve/lxc/CTID.conf.

# vechi
# mp0: /mnt/media,mp=/media,ro=1

Apoi adaugă un raw mount entry. Exemplu pentru o cale media read-only:

lxc.mount.entry: /mnt/media media none bind,create=dir,ro 0 0

Exemplu pentru o cale writable:

lxc.mount.entry: /mnt/downloads downloads none bind,create=dir 0 0

Două detalii contează aici:

  • Calea sursă este calea de pe host.
  • Calea țintă este relativă la rootfs-ul containerului, deci folosește media sau downloads, nu /media cu slash la început în sintaxa asta.

Abordarea asta pasează mount-ul mai direct către LXC și evită exact drumul de bind-mount handling care a provocat atât de multe probleme în 9.1.5. Nu este elegantă. Este practică.

Pasul 5: repară maparea UID și GID pentru LXC neprivilegiat în loc să trișezi cu un container privilegiat

Aici încearcă mulți să scape ieftin prin a transforma containerul în privilegiat. Este workaround-ul leneș și este greșit. Un LXC privilegiat nu doar face permisiunile mai ușoare. Înlătură una dintre principalele granițe de securitate dintre container și host.

Proxmox documentează explicit că LXC-urile neprivilegiate folosesc intervale UID și GID remapate și suportă mapare custom prin lxc.idmap plus intervalele delegate din /etc/subuid și /etc/subgid. Dacă vrei ca un container neprivilegiat să poată accesa fișiere de pe host deținute de un user sau group real de media, mapează acea identitate explicit în loc să renunți și să rulezi privilegiat.

Să presupunem că utilizatorul media de pe host este UID 1000 și GID 1000. Un exemplu curat de mapare pentru un container neprivilegiat arată așa:

unprivileged: 1
lxc.idmap: u 0 100000 1000
lxc.idmap: g 0 100000 1000
lxc.idmap: u 1000 1000 1
lxc.idmap: g 1000 1000 1
lxc.idmap: u 1001 101001 64535
lxc.idmap: g 1001 101001 64535

Apoi permiți lui root pe host să folosească acele intervale în /etc/subuid și /etc/subgid:

# /etc/subuid
root:100000:1000
root:1000:1
root:101001:64535

# /etc/subgid
root:100000:1000
root:1000:1
root:101001:64535

Logica este simplă:

  • Mapezi ID-urile 0 până la 999 din container în intervalul normal neprivilegiat de pe host.
  • Mapezi ID-ul 1000 din container direct pe ID-ul 1000 de pe host.
  • Mapezi restul intervalului containerului înapoi în intervalul shiftat al host-ului.

Totalul trebuie să rămână 65536. Dacă ai nevoie de mai mult de un UID sau GID passthrough, harta se complică repede. Dacă mai ai și grupuri GPU precum render sau rulezi Docker în interiorul LXC-ului, oprește improvizațiile și documentează matematica atent înainte să restartezi ceva.

Verifică ID-urile reale de pe host înainte să scrii mapa:

id mediauser
getent group render
getent group media

Dacă mapezi UID-ul sau GID-ul greșit, containerul poate porni și totuși permisiunile să rămână un nonsens.

Pasul 6: curăță staged mounts rămase în urmă înainte să retestezi

Un efect secundar al acestui drum de startup stricat este că poate lăsa staged mounts vechi sub zona temporară de mount a LXC-urilor din Proxmox. Dacă nu le cureți, următorul test te poate minți.

mount | grep ".pve-staged-mounts"
find /var/lib/lxc/.pve-staged-mounts -maxdepth 2 -type d -ls

Dacă acel container care a eșuat a lăsat un staged mount în urmă, demontează doar calea afectată:

umount -l /var/lib/lxc/.pve-staged-mounts/mp0

Nu demonta la întâmplare căi pe care nu le înțelegi. Potrivește staged mount-ul exact cu containerul și mount point-ul pe care le testai.

Pasul 7: retestează ca un operator, nu ca cineva care speră că merge

Acum restartază containerul curat și verifică atât pornirea, cât și comportamentul mount-ului.

pct stop ${CTID}
pct start ${CTID}
pct exec ${CTID} -- mount | egrep 'media|downloads|nfs|mergerfs'
pct exec ${CTID} -- sh -c 'id && ls -ld /media /downloads 2>/dev/null'

Dacă acea cale ar trebui să fie writable, demonstrează că este writable:

pct exec ${CTID} -- sh -c 'touch /downloads/.pve-write-test && rm /downloads/.pve-write-test'

Dacă mount-ul este intenționat read-only, nu da write test și apoi nu te mira că eșuează. În schimb, confirmă că read-urile merg și că aplicația vede datele pe care trebuie să le vadă.

În acest punct, erorile de storage read-only din aplicație încetează să mai fie vagi. Acum poți ști dacă este:

  • un mount ro deliberat
  • o nepotrivire de permisiuni pe host
  • o mapare UID sau GID greșită
  • o presupunere mai profundă în aplicație despre ownership

Ce merge de obicei prost în acest runbook

  • Ești încă pe versiunea de pachet stricată. Actualizează înainte de toate.
  • Ai schimbat sintaxa de mount, dar ai păstrat maparea UID și GID greșită.
  • Ai mapat un UID de media, dar ai uitat group-ul de care aplicația chiar are nevoie.
  • Ai modificat configul, dar ai lăsat staged mounts rămase în urmă.
  • Ai testat permisiunile din container fără să verifici mai întâi ownership-ul de pe host.
  • Ai trecut containerul pe privilegiat pentru că era mai rapid. Fixul acela schimbă o problemă de mount într-o problemă de securitate.

Un insight de producție aici: cea mai rea versiune a incidentului nu este containerul care nu pornește. Este containerul care pornește, montează ceva pe jumătate greșit și apoi îți produce erori întârziate de scriere sau corupție în aplicație. Un eșec dur la pornire este enervant. Un storage mount care pare că a mers, dar a mers prost, este mai periculos.

Când trebuie să te oprești din patchuit și să muți workload-ul sau modelul operațional

Dacă workload-ul tău depinde de storage stratificat, mai multe passthrough IDs, grupuri GPU, Docker în interior de LXC sau network shares fragile, trebuie să decizi dacă acel workload mai aparține cu adevărat într-un LXC neprivilegiat. Uneori răspunsul corect este „da, dar curăță maparea și designul mount-urilor”. Alteori răspunsul corect este „acest workload vrea KVM, nu LXC”.

Aici ajută contextul Proxmox existent de la ServerSpan. Dacă încă decizi dacă workload-ul ar trebui să rămână în LXC sau să fie mutat în KVM, citește ghidul de decizie LXC vs KVM. Dacă problema mai mare este că stack-ul tău de virtualizare a depășit stilul de mentenanță de home lab, exact aici administrarea Proxmox devine rațională, nu opțională.

Pentru echipele care au nevoie de infrastructură curată fără să supravegheze manual fiecare edge case de storage la nivel de host, un mediu de servere virtuale planificat corect este adesea calea mai stabilă decât să transformi fiecare ciudățenie de mount într-o excepție permanentă la nivel de container. Iar dacă vrei și contextul mai larg despre poziționarea Proxmox, ServerSpan are deja și acel articol la De ce să alegem Proxmox pentru infrastructura noastră de virtualizare.

Runbook-ul scurt

  1. Verifică versiunile de pachete și confirmă dacă ești încă pe drumul containerelor afectate din zona 9.1.5.
  2. Capturează configurația containerului care eșuează și logurile de startup în mod debug.
  3. Dacă ești încă pe versiunea de pachet problematică, actualizează la pve-container 6.1.1 sau mai nou.
  4. Identifică mount-urile vechi de tip mpX folosite peste MergerFS, NFS sau storage bazat pe FUSE.
  5. Înlocuiește bind mounts fragile de tip mpX cu lxc.mount.entry acolo unde este cazul.
  6. Repară explicit maparea UID și GID pentru containerul neprivilegiat folosind lxc.idmap, /etc/subuid și /etc/subgid.
  7. Curăță staged mounts rămase în urmă înainte de retestare.
  8. Retestează pornirea, vizibilitatea mount-ului și comportamentul la scriere în mod intenționat, nu superficial.

Dacă parcurgi problema în ordinea aceasta, „Status 30” încetează să mai fie o iritare vagă din Proxmox și devine ceea ce este în realitate: un eșec pe drumul de mount și de identity mapping, cu o cale de remediere foarte specifică.

Sursă și Atribuire

Aceast articol se bazează pe date originale ale serverspan.com. Pentru metodologia completă și pentru a asigura integritatea datelor, articolul original trebuie citat. Sursa canonică este disponibilă la: Proxmox 9.1.5 Status 30 în LXC neprivilegiat: runbook pentru storage MergerFS și NFS.