Diagnostiquer un fort usage du CPU
Parfois, le démon Docker lui-même (dockerd
) prend énormément de CPU tandis que les conteneurs sous-jacents sont plutôt calmes.
Une manière de diagnostiquer le souci est de demander au démon Docker un profil d’utilisation du CPU, par exemple avec la commande suivante :
- snippet.bash
curl --unix-socket /var/run/docker.sock http://./debug/pprof/profile --output /tmp/profile
Note:
Docker utilise pprof, un outil permettant de générer et d’analyser des profils de performance.
Pour analyser le profil, il faut installer Golang :
- snippet.bash
sudo apt install golang
On peut alors lancer la commande suivante pour voir les fonctions ayant le plus mobilisé le CPU sur le temps d’analyse :
- snippet.sh
qduchemi@monitoring:/DATA/docker/services/monitoring$ go tool pprof -top /tmp/profile File: dockerd Build ID: f6c42727f6e1033edb4342311e954f4788899cd2 Type: cpu Time: Mar 22, 2023 at 3:01pm (CET) Duration: 30.14s, Total samples = 33.04s (109.61%) Showing nodes accounting for 28.44s, 86.08% of 33.04s total Dropped 354 nodes (cum <= 0.17s) flat flat% sum% cum cum% 5.37s 16.25% 16.25% 10.18s 30.81% encoding/json.(*Decoder).readValue 3.50s 10.59% 26.85% 4.12s 12.47% encoding/json.unquoteBytes 2.94s 8.90% 35.74% 3.04s 9.20% encoding/json.stateInString 1.83s 5.54% 41.28% 2.14s 6.48% encoding/json.(*decodeState).rescanLiteral [...]
A Savoir:
Plein d’autres profils de performance et façon d’analyser sont imaginables. Voir la documentation Golang pour un point de départ).
Dans notre exemple, ce sont des fonction d’encodage/décodage d’objet JSON. Ce sont les logs de Docker qui sont en JSON, il y a donc un souci avec les logs. C’est cohérent avec ce thread sur le sujet.
Dans ce cas spécifique, c’est parce que Promtail lit très souvent les logs en JSON. Docker recommande d'utiliser le module de log local plutôt que JSON, qui a une rotation automatique et utilise un format de fichier plus efficient.
Note:
Seuls les nouveaux conteneurs sont pris en compte pour le changement de driver de log. On peut les recréer depuis /DATA/docker/services
avec :
- snippet.bash
find . -maxdepth 1 -mindepth 1 -type d -exec docker compose --project-directory {} up -d --force-recreate \;