Diagnostiquer un serveur GNU/Linux
Introduction
Quels sont les outils pour comprendre ce qui se passe sur un serveur qui “semble” lent? Pour répondre, voici une liste des principaux outils en ligne de commande pour diagnostiquer un serveur GNU/Linux.
Cette liste est extraite d’un article écrit par Brendan D. Gregg paru sur le
blog technique de Netflix. Contrairement à l’article original je ne
présenterai pas uptime
(qui donne la charge moyenne pendant la dernière minute écoulée,
ainsi que celle des 5 et des 15 dernières minutes), top
, ou dmesg | tail
, pour me
concentrer uniquement sur des outils moins connus.
Liste des outils
vmstat 1
vmstat
affiche des informations sur l’état de la mémoire. vmstat 1
ajoute en plus une ligne de mise à jour de ces informations toutes les
secondes.
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 2 0 3504512 743984 1847300 4610056 3 10 1538 2221 20 20 31 17 51 1 0 0 0 3504512 736676 1847316 4616228 0 0 0 17 1884 4703 4 3 93 0 0 1 0 3504512 728116 1847320 4624320 2 0 2 90 1433 3385 3 2 94 0 0 0 0 3504512 734148 1847332 4616124 0 0 3 125 1451 3574 4 2 94 0 0 2 0 3504512 733700 1847336 4616124 0 0 0 5 1443 3480 4 2 94 0 0
Les colonnes à surveiller:
-
r
: nombre de processus en cours (running
) ou en attente; -
free
: mémoire disponible en kilobytes; -
si
etso
: swap in et swap out. -
us
,sy
,id
,wa
, etst
: moyenne sur l’ensemble des processeurs des valeurs suivantes- user time
- system time
- idle
- wait
- stolen time
À noter que la première ligne affiche les valeurs moyennes depuis le
démarrage de la machine. D’ailleurs vmstat
(sans le 1) n’affiche que cette
ligne.
Autres options:
-
-w
: affiche sur plus de largeur, ce qui améliore la visibilité des nombres dans les colonnes; - le nombre à la fin de la commande indique l’intervalle de rafraîchissement (ici
1
= toutes les secondes); - si deux nombre apparaissent, le deuxième indique le nombre de rafraîchissement à effectuer avant de s’arrêter.
mpstat -P ALL 1
mpstat -P ALL 1
affiche l’occupation des processeurs, toute les secondes.
18:01:48 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 18:01:49 all 8.08 0.00 4.04 0.00 0.00 1.01 0.00 0.00 0.00 86.87 18:01:49 0 8.08 0.00 4.04 0.00 0.00 1.01 0.00 0.00 0.00 86.87 ^C Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle Average: all 5.12 0.00 1.71 0.00 0.00 0.68 0.00 0.00 0.00 92.49 Average: 0 5.12 0.00 1.71 0.00 0.00 0.68 0.00 0.00 0.00 92.49
Si la charge reste haute et toujours sur le même processeur, on est en présence d’une application non threadée, qui bloque le processeur.
Comme vmstat
, cette commande prend deux nombres en arguments (période et nombre de rafraîchissements)
pidstat 1
Affichage par processeur (avant dernière colonne) les processus les plus
gourmands en détaillant la répartition user time
, system time
et wait
.
Linux 4.19.97-v7+ (thelibrary) 05/16/2020 _armv7l_ (4 CPU) 04:41:01 PM UID PID %usr %system %guest %wait %CPU CPU Command 04:41:02 PM 0 522 0.96 0.00 0.00 0.00 0.96 2 tmux: server 04:41:02 PM 0 29866 0.96 3.85 0.00 0.00 4.81 1 pidstat 04:41:02 PM UID PID %usr %system %guest %wait %CPU CPU Command 04:41:03 PM 0 9173 0.00 3.00 0.00 0.00 3.00 0 top 04:41:03 PM 0 29856 0.00 1.00 0.00 0.00 1.00 0 kworker/u8:0-events_unbound 04:41:03 PM 0 29858 1.00 0.00 0.00 0.00 1.00 2 kworker/2:2-events 04:41:03 PM 0 29866 3.00 2.00 0.00 0.00 5.00 1 pidstat ^C Average: UID PID %usr %system %guest %wait %CPU CPU Command Average: 0 522 0.49 0.00 0.00 0.00 0.49 - tmux: server Average: 0 9173 0.00 1.47 0.00 0.00 1.47 - top Average: 0 29856 0.00 0.49 0.00 0.00 0.49 - kworker/u8:0-events_unbound Average: 0 29858 0.49 0.00 0.00 0.00 0.49 - kworker/2:2-events Average: 0 29866 1.96 2.94 0.00 0.00 4.90 - pidstat
Cette commande se rapproche de la commande top
mais au lieu de rafraîchir
l’écran en effaçant les informations précédentes, elle affiche
continuellement des nouvelles données. Ce qui est le cas de la plupart des
commandes fournies ici.
pidstat
est aussi une commande qui prend deux nombres en arguments (période et nombre de rafraîchissements).
iostat -xz 1
Cette command affiche la charge sur les disques (sur les périphériques de
type block
plus exactement).
avg-cpu: %user %nice %system %iowait %steal %idle 1,00 0,00 2,25 0,00 0,00 96,75 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0,00 0,00 6,00 0,00 636,00 0,00 212,00 0,00 0,00 0,00 0,00 0,00 0,00 dm-0 0,00 0,00 6,00 0,00 636,00 0,00 212,00 0,00 0,00 0,00 0,00 0,00 0,00 dm-1 0,00 0,00 6,00 0,00 636,00 0,00 212,00 0,00 0,00 0,00 0,00 0,00 0,00 ^C
Les informations les plus importantes sont:
- r/s, w/s, rkB/s, wkB/s: les lectures/écrites, en nombre et en bande passante par seconde;
- await: l’attente moyenne en milli-seconde avant la réponse à une requête, ce qui est un bon indicateur de problème, si l’attente est trop longue;
- avgqusz: taille moyenne de la queue d’attente du périphérique;
- %util: l’utilisation du périphérique.
À noter que iostat -xy 1
affiche aussi des informations sur l’utilisation
moyenne de tous les processeurs.
Note sur les options:
- il est possible de spécifier un périphérique (exemple:
iostat -xz sda 1
) -
-x
: affiche plus de statistiques; -
-z
: n’affiche pas les périphériques inactifs pendant la période d’analyse; -
-h
: statistiques pour les humains; -
-t
: affiche l’heure; - encore une commande à deux nombres pour arguments.
free -m
(ou mieux free -m -h
)
Cette command affiche simplement l’état de la mémoire.
total used free shared buff/cache available Mem: 7.3Gi 2.2Gi 2.0Gi 468Mi 3.1Gi 4.3Gi Swap: 15Gi 1.0Mi 15Gi
sar -n DEV 1
Cette commande affiche la bande passante utilisée par chaque interface réseau.
^C 16:37:46 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil 16:37:47 lo 12.86 12.86 1.65 1.65 0.00 0.00 0.00 0.00 16:37:47 eth0 7.14 7.14 0.41 1.48 0.00 0.00 0.00 0.01 16:37:47 eth1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil Average: lo 6.68 6.68 1.07 1.07 0.00 0.00 0.00 0.00 Average: eth0 23.06 36.29 1.83 43.52 0.00 0.00 0.00 0.36 Average: eth1 33.11 19.87 42.08 2.10 0.00 0.00 0.00 0.03
La dernière colonne est particulièrement intéressante puisqu’elle affiche le taux d’usage, qui permet de voir si une interface est saturée.
Sar
est une commande à deux nombres pour arguments.
sar -n TCP,ETCP 1
Cette commande affiche un résumé des métriques TCP
et des erreurs réseaux.
^C 16:49:36 active/s passive/s iseg/s oseg/s 16:49:36 0.00 0.00 50.00 47.06 16:49:36 atmptf/s estres/s retrans/s isegerr/s orsts/s 16:49:36 0.00 0.00 0.00 0.00 0.00 Average: active/s passive/s iseg/s oseg/s Average: 0.00 0.00 13.98 13.74 Average: atmptf/s estres/s retrans/s isegerr/s orsts/s Average: 0.00 0.00 0.00 0.00 0.00
Les colonnes indiquent:
- active/s: le nombre de connexions ouvertes par la machine elle même par seconde;
- passive/s: le nombre de connexions entrantes par seconde;
- retrans/s: le nombre de retransmission.
Si ce dernier nombre est élevé, cela signifie qu’il y a certainement un problème réseau.
La commande sar
possède de nombreuses option pour analyser le réseau:
-
-n EDEV
: -
-n EIP
(ou-n EIP6
): les erreurs au niveau de la couche ip v4 (ou v6)
Les arguments à l’option -n
peuvent se combiner (par exemple: -n
EDEV,EIP,EIP6
) et surtout n’oublier l’argument 1
pour calculer et
afficher les résultats toutes les minutes.
Conclusion
Pour obtenir plus d’informations, la page manuelle (aka man
) de chaque
commande viendra compléter cet article qui ne fait qu’effleurer le sujet.
Aucun de ces outils ne s’appuient sur BPF, une technologie qui est en passe de devenir le passage obligé pour l’analyse de performance des machines en temps réel.
En attendant les outils basés sur BPF
, ceux présentés ici ont l’avantage
d’être disponibles sur toutes les machines, y compris celles ayant des
noyaux âgés.
Utiliser pihole en ligne de commmande
Un Pihole à usage multiple
Pihole est un logiciel fantastique pour supprimer la publicité, le traçage et bloquer l’accès à des sites indésirables. Il peut aussi être utilisé pour bloquer l’accès à certain site de façon temporaire.
Par exemple, pour ne pas être tenté d’aller surfer sur Twitter pendant les heures de travail, ou pour empêcher ses enfants de rester trop longtemps sur Youtube, il peut être utile de bloquer l’accès à ces sites uniquement à certaines heures.
L’interface web de pihole est peu pratique pour un tel usage. Il vaut
mieux utiliser la ligne de commande et cron
. Le programme pihole
permet
en effet d’ajouter et de supprimer des sites via la ligne de commande.
Le script
Voici donc un mini script pour ajouter ou supprimer des sites à la
blacklist
.
#!/bin/bash set -e readonly SCRIPTNAME=$(basename $0) readonly PIHOLE=/usr/local/bin/pihole readonly LIST='(^|\.)dailymotion\.com$ (^|\.)vimeocdn\.com$ (^|\.)vimeo\.com$ (^|\.)googlevideo\.com$ (^|\.)youtube\.(de|fr|be|com) ' action () { local action=$1 local del="" if [[ "${action}" == "allow" ]] then del='--delmode' fi $PIHOLE --regex $del -q "'"${LIST}"'" } readonly ARG1=$1 case "$ARG1" in block) action block ;; allow) action allow ;; *) echo "Usage: $SCRIPTNAME {block|allow}" >&2 exit 3 ;; esac
Example de crontab
Pour autoriser uniquement l’accès aux sites entre 17 heure et 18:30 le week-end:
0 17 * * 1,2,3,4,5 /usr/local/bin/dynamic-regex-list.sh allow > /dev/null 2>&1 30 18 * * 1,2,3,4,5 /usr/local/bin/dynamic-regex-list.sh block > /dev/null 2>&1
Dans cet exemple, le script a été nommé dynamic-regex-list.sh
et placé
dans le répertoire /usr/local/bin/
.
Construire ses propres images Raspbian
Le problème
Si, comme moi, la première chose que vous faites après le démarrage d’une Raspberry PI sur distribution Raspbian c’est de désinstaller tous les logiciels inutiles, alors j’ai trouvé le logiciel qu’il vous faut: pi-gen. Il s’agit ni plus ni moins du logiciel utilisé pour construire les images Raspbian.
Correctement configuré, il vous permettra de construire une distribution Raspbian aux petits oignons.
La solution
La première étape consiste à récupérer le contenu du dépôt git sur github.
git clone https://github.com/RPi-Distro/pi-gen
Il y a ensuite quelques éléments à modifier:
- le fichier
Dockerfile
afin de contourner un bug qui empêche les machines 64 Bits la construction des images; - le fichier
config
pour écraser quelques valeurs par défaut; - les «/stages/» qui sont les différentes étapes de constructions de l’image Raspbian.
Utiliser Docker
J’ai simplement remplacé la première ligne afin de construire les images avec des programmes 32 bits:
diff --git a/Dockerfile b/Dockerfile index 2e53149..d680d7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:buster +FROM i386/debian:buster ENV DEBIAN_FRONTEND noninteractive
Quelques paramètres de base
Le fichier config
contient quelques paramètres de base de l’installation:
- l’utilisateur par défaut et son mot de passe:
FIRST_USER_NAME
etFIRST_USER_PASS
; - si
ssh
est actif au démarrage (il ne l’est pas par défaut):ENABLE_SSH
; - les paramètres wifi:
WPA_ESSID
,WPA_PASSWORD
etWPA_COUNTRY
; - l’image à construire doit-elle être compressée ou pas:
DEPLOY_ZIP
; - la timezone, qui est située à Londres par défaut, et donc décalée d’une heure avec Paris et Berlin:
TIMEZONE_DEFAULT
; - la liste des stages à exécuter (cf. ci-après), configurée ainsi chez moi:
STAGE_LIST="stage0 stage1 stage2"
.
La liste complètes des paramètres est lisibles dans le fichier README
du projet.
Configuration des stages
Les stages sont les étapes successives de construction de l’image Raspbian. Il y a cinq étapes. L’image est bootable après l’étape 1. L’étape 2 contient la configuration de la timezone, l’installation et la configuration du client ntp, la création du premier utilisateur, etc.
Les stages 3, 4 et 5 installent des logiciels supplémentaires dont X11, un environnement bureautique, etc.
De mon côté j’ai construit le stage 2, mais en le modifiant pour y enlever des paquets que je n’utiliserai pas. Pour cela j’ai modifié les fichiers nommés XX-packages
présents dans les sous répertoires du répertoires stage2
.
Il est aussi de créer son propre stage sur mesure, et de l’inclure dans le paramètre STAGE_LIST
. Là encore le fichier README
est votre ami.
Construction des images
Construire l’image Raspbian est ensuite aussi simple que:
./build-docker.sh
L’image sera créée dans le répertoire deploy
. Ensuite, il suffit d’un cat /path-to/deploy/yourimage-name.img > /dev/sdX
où /dev/sdX
est votre carte SD, et vous voilà prêt à démarrer votre Raspberry avec votre distribution construite sur mesure!
Happy 2020
Notes en vrac de fin d’année
Encore un mini post avec une série de mini trucs. Rien d’extra ordinairement nouveau ici, mais c’est pratique de publier en vrac des notes prises au fil des jours pour pouvoir ensuite les retrouver facilement.
Git
git diff-tree --no-commit-id --name-only -r master..develop
pour lister les fichiers modifiés entre deux commits, ou deux branches (ici master
et develop
).
Ansible
J’ai eu du mal à trouver comment exécuter en local_action
une commande du
module shell. La solution: utiliser _raw_params
comme ci-dessous:
- name: Build frontend local_action: module: shell _raw_params: grunt build args: chdir: "{{ build_root_path }}/src/views/"
Mysql
Quelques commandes en vrac, suffisamment explicites pour ne pas avoir à les commenter, à garder sous le coude:
SHOW FULL PROCESSLIST; SET GLOBAL general_log = 1; SHOW TABLE LIKE 'prefix%';
Configuration
Je ne suis pas un fanatique de la configuration à outrance des logiciels utilisables dans un terminal. J’essaie généralement de me contenter de la configuration par défaut, afin de ne pas être pris au dépourvu ensuite lorsque je dois utiliser ces mêmes logiciels sur un serveur distant, où ces personnalisations seront absentes.
Dernièrement j’ai fait une exception pour tmux
. Dans 90% des cas, lorsque
je découpe une fenêtre, je souhaite rester dans le même répertoire duquel
j’ai lancé la découpe. En revanche, lorsque j’ouvre une nouvelle fenêtre, je
souhaite retourner dans mon HOME
, ce qui est le comportement par
défault. C’est très pratique sur mon ordinateur personnel, et si je n’ai pas
cette fonctionnalité sur un serveur, je peux m’en passer aisément. J’ai donc
créé un fichier ~/.tmux.conf
avec la configuration suivante:
bind '"' split-window -c "#{pane_current_path}" bind % split-window -h -c "#{pane_current_path}"
Je n’utilise emacs
que sur mon ordinateur personnel. Pour me me connecter
à une base de données mariadb
(ou mysql
) en utilisant un autre port que
le port standard, ce qui arrive systématiquement en utilisant des base de
données hébergé dans des containers, j’ai dû ajouter la ligne suivante: