Notre chien de garde a redémarré les services que nous avions arrêtés volontairement
Opérations
L'un de nos chiens de garde démarre tout service activé mais non exécuté. Deux fois en octobre, il a démarré des services que nous avions arrêtés volontairement. La deuxième fois, les visiteurs de l'un de nos sites ont reçu des erreurs pendant environ 45 minutes.
Pourquoi ce chien de garde existe
Un service qui se termine proprement lorsqu'il reçoit SIGTERM, par exemple parce qu'un processus l'a tué par son nom, n'est pas considéré comme « failed » par systemd. Restart=on-failure ne le relance pas, et systemctl --failed ne le liste pas. Il reste arrêté jusqu'à ce que quelqu'un s'en aperçoive. Le chien de garde recherche donc les services activés mais non exécutés, et les démarre.
Le problème est qu'un service arrêté manuellement semble exactement identique.
La première fois
Le 7 octobre, nous avons arrêté un worker vidéo avec systemctl stop à 12:47 pour modifier sa file d'attente de tâches. À 12:55, il tournait de nouveau : le chien de garde l'avait démarré.
La deuxième fois
Le 21 octobre, nous avions besoin de la mémoire de la machine qui sert aussi deux de nos sites pour un test de modèle. Un script a arrêté les applications web des sites, un job de synchronisation et un conteneur de base de données, encore une fois avec systemctl stop. Environ cinq minutes plus tard, un minuteur qui surveille les sites, puis le chien de garde à 19:14, ont relancé le tunnel et les applications web.
Le tunnel a de nouveau reçu du trafic, mais les applications web ne pouvaient pas répondre : le modèle testé occupait 114 GiB de la mémoire de la machine. De 19:14 à 20:00 environ, certains visiteurs ont reçu des erreurs 502. À 20:00, nous avons désactivé le tunnel, les applications web et le job de synchronisation, et arrêté le minuteur de surveillance.
La règle que nous utilisons désormais
- Mettez un service en pause en le désactivant :
sudo systemctl disable --now <unit>. Remettez-le en service avecsudo systemctl enable --now <unit>. Notre chien de garde ne regarde que les services activés, donc un service désactivé est laissé tranquille. - Mettez en pause tout ce qui peut le relancer : le tunnel devant lui et tout minuteur qui le surveille.
- Un arrêt court est une course contre la montre. Si vous utilisez seulement
stop, terminez avant la prochaine vérification, qui sur nos machines intervient en quelques minutes.
Deux autres pièges systemd des mêmes mois
systemctl mask --runtimene fait rien pour un fichier d'unité dans /etc/systemd/system. Les unités dans /etc ont la priorité sur le masque d'exécution dans /run, donc la commande réussit et le service démarre quand même. Pour maintenir un service, nous utilisons un drop-in avecConditionPathExists=!/etc/<name>.hold: tant que ce fichier existe, le service ne démarre pas, ni au démarrage ni manuellement.systemctl is-activeconsidère un service oneshot en cours d'exécution comme inactif. Pendant qu'un serviceType=oneshots'exécute, son état est « activating », doncis-activeaffiche cela et renvoie 3. Une boucle commewhile systemctl is-active --quiet job.service; do sleep 60; done, prévue pour attendre une tâche nocturne, se termine immédiatement. Lisez plutôt l'état : active, activating, reloading ou deactivating signifient tous qu'il est encore en cours.
Factory Floor surveille les services activés qui ne tournent pas. Par défaut, il les signale seulement, et ne les démarre que si vous activez cette option. Depuis la version 1.0.3, son alerte indique aussi comment mettre un service en pause volontairement, et son runbook dit la même chose.