Pourquoi un conteneur en cours d’exécution conserve-t-il son ancienne limite de mémoire après la modification du fichier Compose ?

Eva Wong est la rédactrice technique et bricoleuse résidente chez ZimaSpace. Geek depuis toujours, passionnée par les homelabs et les logiciels open source, elle se spécialise dans la traduction de concepts techniques complexes en guides accessibles et pratiques. Eva croit que l’auto-hébergement doit être amusant, pas intimidant. À travers ses tutoriels, elle donne à la communauté les moyens de démystifier les configurations matérielles, depuis la construction de leur premier NAS jusqu’à la maîtrise des conteneurs Docker.

Un conteneur en cours d’exécution conserve son ancienne limite mémoire lorsque la configuration Compose modifiée n’a jamais été appliquée au cgroup actif de ce conteneur.

Modifier le fichier YAML ne change pas automatiquement un conteneur existant, et un redémarrage ordinaire relance le même conteneur avec la même configuration définie lors de sa création. La confusion vient également de la comparaison entre une limite mémoire stricte et une réservation, une autorisation de swap, le scope systemd parent ou un paramètre de tas de l’application. Diagnostiquez la valeur effective du cgroup et l’ID du conteneur avant de conclure que Docker a ignoré la modification.

Lisez la limite du cgroup actif plutôt que de vous fier au fichier YAML

Notez l’ID du conteneur, sa date de création, le résultat de l’inspection Docker, la version des cgroups et les fichiers de contrôle mémoire utilisés par le processus en cours d’exécution.

Le noyau Linux définit memory.max comme limite stricte du cgroup, tandis que memory.high déclenche une pression de récupération sans constituer le même plafond absolu.

Si le cgroup actif contient toujours l’ancienne valeur, la configuration n’a pas été appliquée. S’il contient la nouvelle valeur mais que la surveillance indique autre chose, vérifiez les unités, le suivi du cache, le swap et les métriques au niveau de l’application.

Distinguez redémarrage et recréation du conteneur

Comparez l’ID du conteneur avant et après la commande utilisée pour déployer la modification. Notez s’il s’agissait de restart, up, create, d’une action dans l’interface d’un NAS ou d’une mise à jour Docker directe.

Docker précise que Compose restart n’applique pas les modifications de configuration, car il redémarre les conteneurs de service existants.

Utilisez une mise à jour Compose contrôlée qui recrée le service, ou une mise à jour des ressources à chaud prise en charge lorsque cela est approprié. Conservez l’ancien résultat d’inspection afin de pouvoir vérifier le champ modifié.

Validez le modèle Compose final et le champ mémoire

Générez la configuration Compose effective après l’application de tous les fichiers, profils et substitutions d’environnement. Vérifiez que la limite appartient bien au service actif.

La spécification Compose définit mem_limit comme limite mémoire du service et exige une cohérence lorsque des limites équivalentes sont également déclarées dans deploy.

Une valeur présente dans un fichier de remplacement inutilisé, un profil inactif, un service mal orthographié ou une autre interface Stack ne modifie pas le modèle déployé. Comparez la configuration générée avec l’inspection Docker.

Distinguez limite stricte, réservation et swap

Notez la limite mémoire stricte, la réservation ou limite souple, la limite de swap, l’utilisation actuelle, le pic d’utilisation et les événements OOM. Ne considérez pas toutes les valeurs liées à la mémoire comme un seul plafond.

La documentation de contrôle des ressources de systemd distingue MemoryHigh de MemoryMax et montre que les cgroups parents peuvent imposer des limites supplémentaires aux services et aux conteneurs.

Un conteneur peut sembler dépasser une réservation, car une réservation n’est pas équivalente à un plafond strict. Il peut également utiliser du swap ou du cache de pages que certains tableaux de bord excluent ou affichent séparément.

Vérifiez si le tas du runtime utilise son propre plafond

Pour les applications Java, notez la détection des contraintes liées aux conteneurs par la JVM, la taille maximale du tas, la mémoire directe, la métaspace, les piles des threads et les options transmises par l’image ou la configuration de l’application.

Oracle précise que la JVM dimensionne son tas à partir des contraintes de mémoire disponibles et permet à MaxRAMPercentage de définir la fraction du tas.

Modifier la limite du conteneur peut ne pas produire la taille de tas attendue si une option -Xmx explicite ou un pourcentage reste défini. La mémoire du tas ne correspond pas non plus à l’utilisation totale de la mémoire du processus.

Vérifiez les limites définies au niveau de Node.js et des autres applications

Inspectez les options du runtime, les variables d’environnement, le nombre de workers, les caches et les objectifs mémoire internes. Comparez-les à la limite du système d’exploitation.

Node.js documente max-old-space-size comme limite du tas V8, qui peut rester inchangée même après l’attribution au conteneur d’une capacité cgroup plus grande ou plus petite.

Une limite de conteneur protège l’hôte ; elle ne configure pas automatiquement chaque application. Définissez le runtime en dessous du plafond du conteneur, en gardant une marge pour les allocations natives et le cache du système de fichiers.

Appliquez une seule modification et vérifiez-la sous une charge contrôlée

Générez le modèle Compose final, recréez uniquement le service concerné, confirmez le nouvel ID du conteneur et le cgroup actif, puis exécutez une charge de travail limitée tout en surveillant l’utilisation et les événements OOM.

L’article du ZimaSpace Tech & AI Hub explique ce qui se produit lorsqu’un conteneur atteint une limite active ; cet article se concentre sur la vérification du déploiement effectif d’une limite modifiée.

Le problème est résolu lorsque la configuration générée, l’inspection du conteneur, les fichiers du cgroup, le tas du runtime et le seuil de défaillance observé correspondent tous à la politique souhaitée après un redémarrage.

Questions fréquentes

Le redémarrage d’un conteneur applique-t-il une limite mémoire Compose modifiée ?

Non. Un redémarrage utilise normalement la même configuration du conteneur existant. Recréez le service ou utilisez une mise à jour à chaud prise en charge.

Un conteneur peut-il dépasser temporairement sa limite mémoire stricte ?

Le suivi par le noyau et la récupération peuvent brièvement afficher des valeurs proches de la limite, voire légèrement supérieures, mais une utilisation persistante et irrécupérable à la limite stricte entraîne la gestion OOM du cgroup.

Pourquoi l’application indique-t-elle toujours l’ancienne taille de tas ?

Le runtime de l’application peut utiliser une option de tas explicite ou ne calculer un pourcentage qu’au démarrage. Recréez ou redémarrez l’application après avoir validé la limite du conteneur.

Assistance et conseils

Plus à lire

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.