AccueilTechniqueMaintenance → Guide de maintenance

    Guide de maintenance

    Cette page répertorie quelques connaissances basiques à acquérir lors d’une intervention sur nos serveurs.

    La plupart des informations concernant nos serveurs est centralisée sur cette page.

    Compte et usage de Docker🔗

    Chaque utilisateur·ice dispose d’un compte UNIX basique avec une clé SSH lui appartenant dans le fichier ~/.ssh/authorized_keys de ce compte. Ce compte appartient au groupe Docker, donnant ainsi des privilèges élevés sur l’hôte et ses conteneurs.

    Tous les services et outils sont gérés à travers Docker, sauf quelques rares exceptions (WireGuard, Borg…).

    En cas de nécessité, chaque utilisateur·ice peut utiliser la commande sudo pour exécuter une commande avec les privilèges root.

    Le dépôt Core🔗

    Un dossier centralise la gestion de nos outils et de tous nos conteneurs : le dépôt Core, présent dans le dossier /srv de chaque machine. Ce dossier est paramétré avec des droits spécifiques pour permettre à toutes les personnes du groupe Docker de modifier les fichiers.

    Ce dépôt contient notamment le script manager.sh qui facilite la gestion des conteneurs.

    Shell et alias🔗

    Nous utilisons la shell Fish par défaut sur tous les comptes, à laquelle nous avons intégré des alias pour faciliter la gestion des conteneurs. Voici la liste de ces commandes, triées par fréquence d’utilisation.

    CommandeAliasDescription
    dsdocker stats –no-streamListe les conteneurs actifs et leur consommation en RAM/CPU/PID/réseau.
    dlt <conteneur>docker logs -f –tail 500 <conteneur>Affiche les 500 dernières lignes du journal d’un conteneur.
    de <conteneur> <programme>docker exec -it <conteneur> <programme>Exécute une shell dans un conteneur. (ex: de nextcloud-fpm bash)
    dpsdocker ps -aUne sorte de docker stats mais sans les stats. Liste les conteneurs Docker (dont ceux arrêtés).
    dcp <src> <dst>docker cp <src> <dst>Copie un fichier de l’hôte sur le conteneur ou inversement. Ex: dcp ./dump.sql postgres-db:/var/
    didocker imagesListe les images Docker.
    dipdocker images pruneNettoie les images Docker qui n’ont pas de tag.
    dstop <conteneur>docker stop <conteneur>Arrête un conteneur (plutôt utiliser le manager pour ça).
    drm <conteneur>docker rm <conteneur>Supprime un conteneur arrêté (plutôt utiliser le manager pour ça).
    drmidocker rmi <image>Supprime une image.
    dvdocker volume <create|rm> <volume>Crée ou supprime un volume.
    dpdocker pull <image:tag>Récupère une image sur DockerHub ou un dépôt distant.

    Que faire en cas de problème ?🔗

    Établir le diagnostic🔗

    Collecte d’informations🔗

    Il est nécessaire d’obtenir cinq types d’information lors d’une panne avant d’agir :

    1. L’étendue de la panne : concerne-t-elle un seul service ? Plusieurs services ? Tous les services ?
    2. La sévérité : est-ce une indisponibilité totale ou une dégradation de la qualité de service ?
    3. Les symptômes internes et externes : sous quelle forme la panne se manifeste-t-elle ? Comment se traduit-elle en interne ?
      • Symptômes externes : ralentissements, erreurs déclenchées avec une action précise, comportement inhabituel…
      • Symptômes internes : consommation excessive de ressources, problèmes de résolution DNS, disque plein, NFS injoignable…
    4. L’origine : vient-elle d’un serveur en particulier ? d’un ensemble de services qui dépendent d’un même service (NFS, PostgreSQL) ? De l’usage d’un protocole en particulier (SMTP, SSH, HTTP) ?
    5. La cause : à partir des symptômes et de l’origine de la panne, en déduire les causes possibles de problème.
      • Vérifier notamment si le problème ne vient pas de causes externes : panne du côté de nos hébergeurs ? pour Nitter : panne de Twitter ? panne d’un service tiers dont nous dépendons ?

    Outils de diagnostic🔗

    Plusieurs outils sont indispensables à la réalisation du diagnostic :

    1. La supervision externe (Uptime Kuma) : en règle générale, les pannes visibles de l’extérieur déclenchent une alerte sur Uptime Kuma.
    2. La supervision interne (Netdata) : ses alertes indiquent généralement de nombreuses anomalies (load average ou consommation de RAM élevée, disque plein…). Son interface web permet généralement d’identifier les serveurs ou conteneurs à l’origine d’un problème et de savoir précisément à partir de quel moment la panne a commencé.
    3. La commande htop permet d’avoir un œil sur les processus qui tournent sur la machine.
    4. La commande ds (ou docker stats --no-stream) indique la consommation de ressources de chaque conteneur. Naturellement, un service qui utilise 99% de sa RAM autorisée aura tendance à offrir une qualité de service dégradée.
    5. df -h affiche l’usage de l’espace disque. Si l’une des partitions est à 100% d’utilisation, c’est sans doute anormal.
    6. Les journaux d’accès des services (stockés dans le volume local-syslog sur Antigone) peuvent identifier de potentiels abus de ressources en corrélation avec les statistiques de supervision interne, ou des erreurs renvoyées par un service (codes HTTP 5XX, codes d’erreur 451 avec Postfix…).
    7. Les journaux du conteneur (dlt <conteneur> ou docker logs -f --tail 500 <conteneur>) peuvent également éclairer sur la nature de la panne.
    8. Les journaux système dans /var/log/syslog peuvent indiquer les OOM kills ou les pannes plus graves.

    Intervenir sur la panne🔗

    La solution identifiée dépend intrinsèquement du diagnostic établi. La « solution magique » du redémarrage du conteneur peut parfois aider, mais ne fonctionne pas à tous les coups. Le redémarrage d’un serveur entier est à éviter (voir plus bas).

    Attention :

    • Toute intervention sur la base de données PostgreSQL nécessite une formation préalable.
    • Intervenir sur un service implique d’avoir pris connaissance de la documentation correspondante.
    • De manière générale, toute intervention un peu spécifique sur un service qui sort de la maintenance de premier niveau (simple redémarrage / consultation des journaux) nécessite une formation sur le fonctionnement du service à travers une prise en main assistée par d’autres personnes.

    Cas de figure🔗

    Certains problèmes sont plus fréquents que d’autres. Attention toutefois à ne pas précipiter un diagnostic en pensant que la panne rencontrée est liée à un problème fréquent.

    Des instructions à suivre en cas de panne peuvent également être indiquées sur les pages de chaque service.

    Service Nitter🔗

    Notre service Nitter dépend entièrement de Twitter pour fonctionner, par nature. Il est également (et de très loin) notre service le plus utilisé. Il arrive qu’il tombe en panne assez fréquemment.

    1. Essayer de joindre le service de l’extérieur, par exemple en consultant le profil de La Contre-Voie.
      • S’il n’est pas possible de vérifier de l’extérieur si les deux instances redondées localement sont fonctionnelles, les journaux du conteneur du reverse-proxy peuvent donner des informations supplémentaires.
    2. Vérifier si les conteneurs de Nitter sont toujours fonctionnels. Si c’est le cas, vérifier que leur utilisation de RAM soit inférieure à 90%.
      • Vérifier également la RAM utilisée par l’instance Redis.
    3. Consulter le trafic en temps réel dans les journaux d’accès HTTP.
    4. Vérifier s’il n’y a pas de nouvelles mises à jour de Nitter, et consulter le canal dédié à Nitter pour voir si d’autres instances ont un problème similaire.
    5. Éventuellement redémarrer le conteneur Nitter, avec précution : Nitter demande de nouveaux tokens lors d’un redémarrage de l’instance, et peut se heurter à un rate limit qui causerait une indisponibilité de 30 minutes.

    Attention : lors du redémarrage du service, penser à démarrer également ses dépendances (nitter-redis par exemple), sans quoi le service ne pourra pas démarrer.

    Il arrive que Twitter soit indisponible, mettant à mal notre service Nitter. Le site Down Detector peut être utilisé pour vérifier cela.

    Serveur de stockage🔗

    Une panne du serveur NFS est généralement due à une anomalie du côté du serveur de stockage, Antigone. Un dysfonctionnement impactant NFS et le lien WireGuard pourrait indiquer une panne généralisée d’Antigone, ou un problème de réseau.

    Ce genre de panne impacte typiquement Nextcloud et Matrix, qui utilisent NFS comme espace de stockage. Un fort ralentissement de NFS (qui se caractérise souvent par une montée de l’iowait sur Antigone) permet généralement d’utiliser Matrix pour échanger du texte, mais les envois de fichiers peuvent échouer. Matrix devient toutefois totalement indisponible si le NFS est injoignable.

    En cas de dysfonctionnement d’Antigone, le service de journalisation syslog-ng peut également être indisponible. Notre reverse-proxy utilise UDP pour envoyer les journaux d’accès HTTP ; UDP ne nécessitant pas d’accusé de réception, les journaux sont simplement perdus sans impacter le fonctionnement du reverse-proxy.

    Le fonctionnement des serveurs qui dépendent de NFS sera toutefois perturbé, selon plusieurs symptômes : montée progressive du load average, parfois de l’iowait… Une panne du serveur NFS sur plusieurs heures pourrait entraîner d’autres pannes sur les autres serveurs.

    La solution dépend alors de la gravité de la panne sur Antigone :

    • si le lien WireGuard est lent ou saturé : trouver la source de la surconsommation de ressources.
    • si le lien WireGuard est perdu mais que la machine semble être encore connectée à Internet : diagnostiquer le réseau et renouveler la session WireGuard.
    • si le serveur NFS est perdu : un redémarrage du conteneur pourrait peut-être aider.
    • si Antigone ne répond pas via SSH : un redémarrage de la machine pourrait s’imposer.

    Saturation de l’espace disque🔗

    Le diagnostic de cette situation est rapide : df -h indique la partition root ou /home pleine. Si ce n’est pas le cas mais que les symptômes sont les mêmes, peut-être que le serveur de stockage est plein.

    Une première mesure d’urgence consiste à exécuter sudo journalctl --vacuum-size=50M && sudo apt clean pour libérer de l’espace occupé par les journaux de systemd et les paquets téléchargés pour les mises à jour.

    Ensuite, la commade ncdu permet d’identifier les dossiers les plus lourds. Il est préférable d’utiliser ncdu -x pour éviter d’explorer les partitions montées et notamment les shares NFS (ce qui ralentirait fortement le scan).

    Consommation excessive de ressources🔗

    Un conteneur qui consomme plus de 95% de sa RAM pourrait commencer à consommer de la mémoire swap (si disponible), ralentissant les accès en lecture et écriture sur le disque. Il pourrait également atteindre sa limite de RAM autorisée et subir un OOM kill immédiat.

    Dans ce cas, Docker est paramétré pour redémarrer le conteneur de lui-même jusqu’à cinq fois. Après 5 redémarrages, Docker laissera le conteneur s’arrêter.

    Un redémarrage manuel des conteneurs qui consomment trop de ressources peut aider à réduire temporairement sa consommation.

    Comme solution plus durable, il est possible d’augmenter la limite de RAM du conteneur de manière permanente, au cas par cas. Une solution similaire est envisageable lorsqu’un conteneur utilise trop de PIDs, à l’exception de Fail2ban qui a juste besoin d’un redémarrage (voir sa documentation).

    En cas de redémarrage d’un serveur🔗

    Redémarrer un serveur dans le cadre d’une maintenance non planifiée ne doit être utilisé qu’en dernier recours, c’est-à-dire lorsque toutes les autres solutions possibles ont été testées. En effet, un redémarrage entraîne nécessairement une interruption de tous les services fournis par le serveur.

    Il peut être envisagé lorsque la machine dont il est question n’est plus joignable via SSH, n’est plus connectée au réseau ou se comporte de manière complètement erratique (suite à un kernel oops ou une erreur critique au niveau du disque, par exemple).

    Le redémarrage du serveur et de tous ses conteneurs peut durer entre une et cinq minutes selon les circonstances.

    1. Avant de redémarrer la machine via sudo reboot, ouvrir un onglet vers l’interface de gestion de PulseHeberg (s’il s’agit d’un serveur hébergé chez eux). La procédure d’extinction du serveur a tendance à ne jamais se terminer à cause de Docker ou Systemd qui bloquent le redémarrage en raison d’un processus qui peine à s’arrêter : il faut donc préparer l’extinction par la force au préalable.
      • Il peut être utile d’ouvrir la console VNC sur l’interface de PulseHeberg pour voir le déroulement du reboot, puisque la connexion SSH sera rapidement coupée.
    2. Si ce n’est pas déjà fait, une annnonce de service sur Mastodon et Matrix (si disponible) s’impose, ne serait-ce que pour rendre compte de l’état de la résolution de la panne.
    3. Lancer la procédure de redémarrage.
    4. Compter une minute. Si le serveur ne parvient pas à s’éteindre passé ce délai, forcer l’extinction avec l’interface de PulseHeberg.
    5. Superviser la procédure de redémarrage depuis VNC. La connexion SSH devrait être rapidement accessible.
    6. Une fois connecté via SSH, utiliser htop et ds pour vérifier si tous les conteneurs sont bien en train de redémarrer.
      • Utiliser manager audit pour lister les conteneurs qui devraient être en fonctionnement sur la machine, avec leur état. Il en manque parfois.
      • Attention : il arrive que la commande liste des conteneurs qui ne devraient pas tourner sur la machine et qui ne doivent pas être démarrés, en raison d’une configuration obsolète. Il vous revient de savoir quels conteneurs sont à redémarrer ou non.
    7. Vérifier que les services fournis par le serveur sont bien joignables depuis l’extérieur.
    8. Vérifier que le problème ayant causé la panne soit résolu.