Salut à tous, ça fait longtemps qu’on a pas parlé de docker, non. ? Et je vous avais promis de parler du Monitoring des performances docker avec Splunk. Ça fait quelques mois que j’ai mis en place un truc sur le serveur mais que je n’ai pas eu le temps de vous mettre sur le blog.
Rappel des articles de la série « Docker et Portainer » :
- Docker et Portainer part 1 – Les conteneurs pour les nuls ;
- Docker et Portainer part 2 – Stack vsftpd mono-image ;
- Docker et Portainer part 3 – Docker Guacamole via une Stack multi-images ;
- Docker et Portainer part 4 – OpenVPN, Network et Splunk ;
- Docker et Portainer part 5 – Customiser un conteneur PHP-FPM ;
- Docker et Portainer part 6 – NextCloud avec Docker, Déployer un « Cloud » personnel ;
- Docker et Portainer part 7 – Mettre à jour Portainer ;
- Docker et Portainer part 8 – Déployer un jitsi meet avec docker ;
- Docker et Portainer part 9 – Monitoring des performances docker avec Splunk.
- Docker et Portainer part 10 – The Hive & Cortex et installation Docker….
V1, dans le doute : script…
Ma première tentative a été d’écrire le petit script docker-performance.sh, ci dessous. C’est simple, compact, ça tient en quelques lignes et ça fait le taf sans générer 100mo de log par conteneur par jour.
#!/bin/bash
TMP=$(date -Iseconds)
docker stats --no-stream --format "{\"container\":\"{{ .Name }}\",\"memory\":{\"raw\":\"{{ .MemUsage }}\",\"percent\":\"{{ .MemPerc }}\"},\"cpu\":\"{{ .CPUPerc }}\"}" > /var/log/dockermetrics-tmp.log
sed -i "s/\"container\":/\"date\":$TMP,\"container\":/g" /var/log/dockermetrics-tmp.log
cat /var/log/dockermetrics-tmp.log >> /var/log/dockermetrics.log
Pour que ça fonctionne, il faut quand même mettre en place un petit log rotate pour ne pas éclater votre /var dans quelques mois. Voici un exemple de conf à mettre dans /etc/logrotate.d/docker-perfs
/var/log/dockermetrics.log
{
rotate 7
daily
missingok
notifempty
delaycompress
compress
create 650 root splunk
}
Enfin un petit cou de Crontab -e pour ajuster la fréquence pour les performances demandées, et en fonction de la durée de la commande. Par exemple, toutes les 20s :
** * * * /opt/docker-performance.sh >/dev/null 2>&1 * * * * sleep 20; /opt/docker-performance.sh >/dev/null 2>&1 * * * * sleep 40; /opt/docker-performance.sh >/dev/null 2>&1
Ca vous sortira des stats dans ce format là :
{"date":"2022-01-19T15:36:21+01:00","container":"systemsec_db","memory":{"raw":"80.21MiB / 15.65GiB","percent":"0.50%"},"cpu":"0.08%"}
Simple à exploiter, ca fonctionne bien et ça ne coûte pas de performances au serveur pour les sortir : idéal !
V2 – api in PowerShell
Alors docker stats c’est très bien pour les logs de base mais si vous voulez du bien précis, il va falloir augmenter la cadence et accéder à de la donnée un peu plus détaillée. Et ça tombe bien pour ça on a une api qui permet monitorer avec CURL (en suivant par exemple sur ces docs) :
https://www.datadoghq.com/blog/how-to-collect-docker-metrics/
https://docs.docker.com/engine/api/sdk/examples/
et on sort le bout de code suivant :
curl -s --unix-socket /var/run/docker.sock http://localhost/containers/0699644cb23f1283473b011c6bf119fb9ebc2128d1111d13f064a68025daf79b/stats
A partir là on peut jouer en PowerShell (oui, oui, ça existe sous Linux maintenant), si vous acceptez de faire tourner votre API docker sur une IP/port plutôt que la socket unix (pas compatible encore) .
$DockerJSON = Invoke-Expression "curl -s --unix-socket /var/run/docker.sock http://localhost/containers/json"
$Containers = $DockerJSON | ConvertFrom-Json
$results = @()
ForEach ($Container in $Containers) {
Write-Host $Container.Names
$ContainerID = $Container.ID
$ContainerStats = Invoke-Expression "curl -s --unix-socket $DockerJSON = Invoke-Expression "curl -s --unix-socket /var/run/docker.sock http://localhost/containers/json"
$Containers = $DockerJSON | ConvertFrom-Json
$results = @()
ForEach ($Container in $Containers) {
Write-Host $Container.Names
$ContainerID = $Container.ID
$ContainerStats = Invoke-Expression "curl -s --unix-socket /var/run/docker.sock http://localhost/containers/$ContainerID/stats?stream=false"
$results += "$ContainerStats"
}
$f = New-Object IO.StreamWriter("/var/log/dockermetrics.log",$true)
foreach($r in $results){
$f.WriteLine($r)
}
$f.Close()
A partir de là vous êtes en PowerShell, donc à vous d’ajuster si vous voulez paralléliser avec des jobs ou écrire dans des fichiers différents.
Dans ces 2 cas, il ne nous reste plus qu’a monitorer le fichier dans Splunk et faire un jolie dashboard. Par contre vous verrez que les logs sont beaucoup moins évident à calculer. En effet, au lieu de sortir des statistiques en pourcentage, vous avez ici les valeurs brut à exploiter comme ci-dessous (et ça pique):
{"read":"2022-01-19T10:59:31.920860324Z","preread":"2022-01-19T10:59:30.916627863Z","pids_stats":{"current":32},"blkio_stats":{"io_service_bytes_recursive":[{"major":8,"minor":0,"op":"Read","value":88653824},{"major":8,"minor":0,"op":"Write","value":4408246272},{"major":8,"minor":0,"op":"Sync","value":4496900096},{"major":8,"minor":0,"op":"Async","value":0},{"major":8,"minor":0,"op":"Discard","value":0},{"major":8,"minor":0,"op":"Total","value":4496900096}],"io_serviced_recursive":[{"major":8,"minor":0,"op":"Read","value":17484},{"major":8,"minor":0,"op":"Write","value":161406},{"major":8,"minor":0,"op":"Sync","value":178890},{"major":8,"minor":0,"op":"Async","value":0},{"major":8,"minor":0,"op":"Discard","value":0},{"major":8,"minor":0,"op":"Total","value":178890}],"io_queue_recursive":[],"io_service_time_recursive":[],"io_wait_time_recursive":[],"io_merged_recursive":[],"io_time_recursive":[],"sectors_recursive":[]},"num_procs":0,"storage_stats":{},"cpu_stats":{"cpu_usage":{"total_usage":1171070053283,"percpu_usage":[156337442367,153383568888,152536252426,153603709578,147661569268,150100834620,129486709385,127959966751],"usage_in_kernelmode":575870000000,"usage_in_usermode":517340000000},"system_cpu_usage":140367933822904483,"online_cpus":8,"throttling_data":{"periods":0,"throttled_periods":0,"throttled_time":0}},"precpu_stats":{"cpu_usage":{"total_usage":1171069527263,"percpu_usage":[156337413407,153383568888,152536220216,153603469788,147661569268,150100769150,129486549795,127959966751],"usage_in_kernelmode":575870000000,"usage_in_usermode":517340000000},"system_cpu_usage":140367925782904483,"online_cpus":8,"throttling_data":{"periods":0,"throttled_periods":0,"throttled_time":0}},"memory_stats":{"usage":92696576,"max_usage":261038080,"stats":{"active_anon":35483648,"active_file":2973696,"cache":10928128,"dirty":0,"hierarchical_memory_limit":9223372036854771712,"hierarchical_memsw_limit":0,"inactive_anon":39387136,"inactive_file":8597504,"mapped_file":5001216,"pgfault":71610,"pgmajfault":5775,"pgpgin":135597,"pgpgout":169232,"rss":74653696,"rss_huge":50331648,"total_active_anon":35483648,"total_active_file":2973696,"total_cache":10928128,"total_dirty":0,"total_inactive_anon":39387136,"total_inactive_file":8597504,"total_mapped_file":5001216,"total_pgfault":71610,"total_pgmajfault":5775,"total_pgpgin":135597,"total_pgpgout":169232,"total_rss":74653696,"total_rss_huge":50331648,"total_unevictable":0,"total_writeback":540672,"unevictable":0,"writeback":540672},"limit":16807350272},"name":"/systemsec_db","id":"2afd5a2b041793ccb10b5396eb27d53675f82d6bb72daa4e0d616630b57a9cee","networks":{"eth0":{"rx_bytes":192019693,"rx_packets":1308736,"rx_errors":0,"rx_dropped":0,"tx_bytes":4840042122,"tx_packets":1253874,"tx_errors":0,"tx_dropped":0}}}
Bilan du monitoring des performances docker avec Splunk
Bon, la, je vous ai montré comment faire du monitoring des performances docker avec Splunk. Mais vous vous doutez bien que vu la popularité de docker ces dernières années. Il existe une palanquée de solutions open source (ou non) pour suivre les perfs de vos conteneurs. De mon côté, j’ai pu me faire un jolie dashboard comme ça dans mon Splunk :
Et si vous avez un peu plus de bestioles à suivre que moi ! Je vous propose d’utiliser le logiciel Zabbix qui est un des leader du domaine du monitoring de performance. Et… qui se déploit dans du Docker ! mais c’est pour une prochaine fois ! Geekez bien !
Merci pour cette belle série d’articles.
Très instructif.
Hâte d’être à la prochaine fois.
Merci, ça me fait toujours plaisir ce genre de retour ! J’avoue être un peu sous l’eau ces derniers temps et pas publier autant que j’aimerai sur le blog, ça devrait s’améliorer en 2022 « le gros projet » est presque terminé là.