Skip to content

Swap & Optimisation OOM (systemd-oomd)

Cette documentation détaille la mise en œuvre de la gestion du swap et de l'OOM killer via Ansible. L'architecture repose sur deux piliers : une allocation intelligente de l'espace d'échange et une surveillance proactive via systemd-oomd.

1. Gestion Automatisée du Swapfile

Le playbook s'assure que chaque machine dispose d'au moins 10 Go de swap. Si ce n'est pas le cas, il crée un fichier /swapfile de 12 Go.

Extrait : Création du swap

- name: Créer le swapfile (fallocate)
  command: fallocate -l {{ swapfile_size_gb }}G {{ swapfile_path }}
  when: not swapfile_stat.stat.exists

- name: Sécuriser les permissions du swapfile
  file:
    path: "{{ swapfile_path }}"
    owner: root
    group: root
    mode: '0600'

Choix techniques

  • fallocate : Nous utilisons fallocate au lieu de dd car il alloue l'espace instantanément sans écrire de zéros sur le disque, ce qui est beaucoup plus rapide.
  • Permissions 0600 : Le swap peut contenir des données sensibles en RAM. Il est impératif que seul l'utilisateur root puisse le lire.
  • Seuil de 10 Go : Ce seuil permet d'éviter de recréer un swapfile si un swap suffisant (ex: partition dédiée) est déjà présent.

2. Configuration de systemd-oomd

systemd-oomd remplace l'ancien OOM killer du noyau par une approche basée sur la "pression" (PSI - Pressure Stall Information).

Extrait : Politique de kill

- name: Configurer la politique oomd pour user.slice
  copy:
    content: |
      [Slice]
      ManagedOOMSwap=kill
    dest: /etc/systemd/system/user.slice.d/10-oomd-limits.conf

Pourquoi user.slice ?

En configurant le "kill" sur user.slice, nous protégeons les services critiques du système. Si la mémoire sature, systemd-oomd ciblera en priorité les processus dans la session utilisateur (applications, conteneurs) plutôt que de risquer de tuer des démons système essentiels au fonctionnement de l'OS.

3. Calcul Dynamique du Seuil de Swap

C'est l'aspect le plus critique : un pourcentage fixe (ex: 80%) est inadapté si la taille du swap varie fortement entre les machines.

Algorithme de calcul (Bash)

Le script /usr/local/lib/oomd-update-swap-limit.sh implémente la logique suivante :

# Petit/moyen swap (<= 18G) : garder 2G de marge de sécurité
if [[ "${SWAP_TOTAL_KB}" -le "${THRESHOLD_BIG_KB}" ]]; then
  KILL_AT_KB=$(( SWAP_TOTAL_KB - SAFETY_MARGIN_KB ))
else
  # Grand swap (> 18G) : plafonner à 16G utilisés
  KILL_AT_KB=${MAX_KILL_AT_KB}
fi

Justification des seuils

  • Marge de 2 Go : Sur les systèmes avec peu de swap, il est vital de déclencher le kill avant que le swap ne soit plein à 100%. Une marge de 2 Go évite que le système ne tombe dans un état de "thrashing" (écritures incessantes sur disque) où il devient totalement non-répondant.
  • Plafond de 16 Go : Sur les serveurs avec beaucoup de swap, il n'est pas nécessaire de laisser 10% ou 20% de libre (ce qui représenterait beaucoup de Go perdus). On considère qu'au-delà de 16 Go de swap utilisé, une application a probablement une fuite mémoire et doit être arrêtée.

4. Persistance et Stabilisation au Boot

Le calcul du swap doit se faire après que tous les périphériques de swap soient montés.

Extrait : Service Post-Boot

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 120
ExecStartPre=/usr/local/lib/oomd-update-swap-limit.sh
ExecStart=/bin/systemctl restart systemd-oomd.service

Pourquoi attendre 120 secondes ?

  • Stabilisation : Au démarrage, l'utilisation mémoire est instable. Attendre 2 minutes permet de s'assurer que le système a fini ses tâches de boot.
  • Détection complète : Cela garantit que toutes les partitions swap (éventuellement sur des disques externes ou réseau) sont bien actives avant de lancer le calcul du script, évitant ainsi un SwapUsedLimit erroné.

5. Gestion des Erreurs (Rescue)

Le playbook inclut un bloc rescue pour notifier l'administrateur par mail en cas d'échec d'une tâche, assurant qu'aucune machine ne reste sans protection OOM à cause d'une erreur silencieuse.

ref : https://www.freedesktop.org/software/systemd/man/latest/systemd-oomd.service.html , https://man.archlinux.org/man/systemd-oomd.8