Perché un container in esecuzione mantiene il vecchio limite di memoria dopo la modifica del file Compose?

Eva Wong è la Technical Writer e smanettatrice residente di ZimaSpace. Una geek da sempre con una passione per homelab e software open-source, si specializza nel tradurre concetti tecnici complessi in guide accessibili e pratiche. Eva crede che l'auto-ospitare debba essere divertente, non intimidatorio. Attraverso i suoi tutorial, dà potere alla comunità di demistificare le configurazioni hardware, dalla costruzione del loro primo NAS al dominio dei container Docker.

Un container in esecuzione mantiene il vecchio limite di memoria quando la configurazione Compose modificata non è mai stata applicata al cgroup attivo di quel container.

La modifica dello YAML non cambia automaticamente un container esistente e un normale riavvio avvia lo stesso container con la stessa configurazione definita al momento della creazione. La confusione nasce anche dal confronto tra un limite di memoria rigido e una riserva, una quota di swap, lo scope systemd del sistema padre o un’impostazione dell’heap dell’applicazione. Diagnostica il valore effettivo del cgroup e l’ID del container prima di concludere che Docker abbia ignorato la modifica.

Leggi il limite del cgroup attivo invece di fidarti dello YAML

Registra l’ID del container, l’ora di creazione, l’output dell’ispezione Docker, la versione del cgroup e i file di controllo della memoria utilizzati dal processo in esecuzione.

Il kernel Linux definisce memory.max come limite rigido del cgroup, mentre memory.high applica pressione per il recupero senza fungere da stesso tetto assoluto.

Se il cgroup attivo contiene ancora il vecchio valore, la configurazione non è stata applicata. Se contiene il nuovo valore ma il monitoraggio mostra qualcosa di diverso, controlla le unità, la contabilizzazione della cache, lo swap e le metriche a livello di applicazione.

Distingui tra riavvio e ricreazione del container

Confronta l’ID del container prima e dopo il comando utilizzato per distribuire la modifica. Registra se il comando era restart, up, create, un’azione dell’interfaccia NAS o un aggiornamento Docker diretto.

Docker dichiara che Compose restart non applica le modifiche alla configurazione, perché riavvia i container di servizio esistenti.

Utilizza un aggiornamento Compose controllato che ricrei il servizio oppure, quando appropriato, un aggiornamento live delle risorse supportato. Conserva il precedente output dell’ispezione per poter verificare il campo modificato.

Convalida il modello Compose finale e il campo della memoria

Genera la configurazione Compose effettiva dopo aver applicato tutti i file, i profili e le sostituzioni delle variabili d’ambiente. Controlla che il limite appartenga al servizio attivo.

La specifica Compose definisce mem_limit come limite di memoria del servizio e richiede coerenza quando sono dichiarati anche limiti deploy equivalenti.

Un valore in un file override inutilizzato, in un profilo inattivo, in un servizio con nome errato o in un’altra interfaccia Stack non modifica il modello distribuito. Confronta la configurazione generata con l’ispezione Docker.

Separa limite rigido, riserva e swap

Registra il limite rigido della memoria, la riserva o il limite morbido, il limite dello swap, l’utilizzo attuale, l’utilizzo massimo e gli eventi OOM. Non considerare ogni valore relativo alla memoria come un unico tetto.

La documentazione sul controllo delle risorse di systemd distingue MemoryHigh da MemoryMax e mostra che i cgroup padre possono imporre limiti aggiuntivi a servizi e container.

Un container può sembrare superare una riserva perché una riserva non equivale a un limite rigido. Può inoltre consumare swap o cache delle pagine che una dashboard esclude oppure segnala separatamente.

Controlla se l’heap del runtime utilizza un proprio limite

Per le applicazioni Java, registra il rilevamento della JVM compatibile con i container, l’heap massimo, la memoria diretta, la metaspace, gli stack dei thread e i flag passati dall’immagine o dalla configurazione dell’applicazione.

Oracle documenta che la JVM dimensiona il proprio heap in base ai vincoli di memoria disponibili e consente a MaxRAMPercentage di impostare la frazione dell’heap.

La modifica del limite del container potrebbe non produrre l’heap dell’applicazione previsto quando rimane un valore -Xmx esplicito o una percentuale. Inoltre, la memoria dell’heap non coincide con l’utilizzo totale della memoria del processo.

Controlla i limiti a livello di applicazione di Node.js e degli altri runtime

Esamina i flag del runtime, le variabili d’ambiente, il numero di worker, le cache e gli obiettivi interni di memoria. Confrontali con il limite del sistema operativo.

Node.js documenta max-old-space-size come limite dell’heap V8, che può rimanere invariato anche dopo che il container riceve una quota cgroup maggiore o minore.

Un limite del container protegge l’host; non configura automaticamente ogni applicazione. Imposta il runtime al di sotto del tetto del container, lasciando spazio per le allocazioni native e la cache del filesystem.

Applica una modifica e verifica con un carico controllato

Genera il modello Compose finale, ricrea solo il servizio interessato, conferma il nuovo ID del container e il cgroup attivo, quindi esegui un carico di lavoro limitato monitorando l’utilizzo e gli eventi OOM.

L’articolo di ZimaSpace Tech & AI Hub spiega cosa accade quando un container di un home server raggiunge il limite attivo; questo articolo si concentra sulla dimostrazione che il limite modificato sia stato effettivamente distribuito.

Il problema è risolto quando la configurazione generata, l’ispezione del container, i file del cgroup, l’heap del runtime e il limite di errore osservato corrispondono tutti alla policy prevista dopo il riavvio.

Domande frequenti

Il riavvio di un container applica un limite di memoria Compose modificato?

No. Un riavvio utilizza normalmente la stessa configurazione del container esistente. Ricrea il servizio oppure usa un aggiornamento live supportato.

Un container può superare temporaneamente il proprio limite rigido di memoria?

La contabilizzazione del kernel e il recupero possono mostrare brevemente valori vicini o leggermente superiori a una soglia, ma un utilizzo non recuperabile prolungato al limite rigido porta alla gestione OOM del cgroup.

Perché l’app continua a segnalare la vecchia dimensione dell’heap?

Il runtime dell’applicazione potrebbe avere un flag heap esplicito oppure calcolare una percentuale solo all’avvio. Ricrea o riavvia l’applicazione dopo aver convalidato il limite del container.

Supporto e consigli

Altro da leggere

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.