Zeven korte troubleshootverhalen
Niet elke storing is een artikel waard, maar de lessen wel.
1. Een stale NFS-mount, opgelost zonder reboot
df -h en mount -a bleven hangen. Een NFS-server was even weg geweest, en drie processen (een virusscanner, een configuratieagent en updatedb) hingen in D-state op de stale mounts.
Opgelost zonder reboot: eerst de processen met kill -9 (in *_wait_bit_killable zijn ze wel te stoppen), dan umount -f of -l, opnieuw mounten en de diensten herstarten. Daarna een runbook geschreven, zodat de volgende keer niemand naar de herstartknop grijpt.
2. Een flag die geaccepteerd leek
Om te testen of een Kubernetes-operator een bepaalde flag kende, draaide ik docker run <image> /manager --onzin-flag. Geen foutmelding. Maar de ENTRYPOINT was al /manager, dus het werd /manager /manager --onzin-flag. De flag-parser van Go stopt bij het eerste argument dat geen flag is en negeert de rest. Geef flags dus direct mee: docker run <image> --onzin-flag. Toen kwam wel netjes flag provided but not defined.
3. Flux doet niets, en zegt niets
Een HelmRelease reageerde niet meer op wijzigingen; flux reconcile, suspend en resume deden zichtbaar niets. De oorzaak: een release die als pending-upgrade in de Helm-storage stond, na een eerdere upgrade die halverwege was gestopt. Diagnose: vergelijk de laatst geprobeerde config-digest met de digest in de geschiedenis. Oplossing: helm rollback naar de laatste goede versie.
4. Een volume vol door een verwijderd bestand
Een persistent volume liep vol, terwijl du veel minder liet zien. Na de dagelijkse logrotatie hield een sidecar het oude, onverpakte logbestand nog open. Het bestand was verwijderd, maar de ruimte kwam pas vrij toen het proces stopte. ls -l /proc/<pid>/fd | grep deleted laat dat direct zien.
5. Verbindingen die ss niet laat zien
Om te bewijzen dat een server niet meer gebruikt werd, keek ik met ss naar binnenkomende verbindingen. Niets. Maar de diensten draaiden in Docker, en verbindingen via Docker-DNAT zie je niet in de netwerknamespace van de host. Gebruik nsenter -t <pid> -n ss per container, of de tellers van de DOCKER-chain in iptables.
6. Een beveiligingsmaatregel die geheugendumps onmogelijk maakte
dotnet-dump collect faalde op een .NET-applicatie met open(/proc/<pid>/mem) Permission denied, ook via sudo. De oorzaak: een centraal uitgerolde mitigatie voor een kernel-CVE zette kernel.yama.ptrace_scope op 2. De dump-tool laat het doelproces zelf een kindproces starten dat zijn geheugen leest, en bij scope 2 mag dat niet meer.
Het wrange: de kernel op die servers was voor die CVE niet eens kwetsbaar, want de exploit gebruikt een systemcall die pas in een latere kernel kwam. De oplossing is geen lokale aanpassing (configuratiebeheer zet hem terug), maar een uitzondering in het centrale beheer. Tijdens een incident kan root de waarde tijdelijk op 1 zetten en daarna terug.
7. Een logschijf vol met ongecomprimeerde auditlogs
/var/log op een databaseserver liep vol: honderden gigabytes aan auditlogs die na rotatie niet werden gecomprimeerd. In place gecomprimeerd met nice en ionice, zodat de database er niets van merkte, en daarna logrotate, een alert op vulgraad en een bewaartermijn op de lijst gezet. Les: logrotate draait niet vanzelf goed voor elke nieuwe logbron. Controleer dat bij het aanzetten van iets dat veel logt.