Il y a de nombreuses raisons pour lesquelles ansible peut se bloquer lors de la collecte de données, mais avant d'aller plus loin, voici le premier test que vous devriez faire dans une telle situation :
ansible -m ping <hostname>
Ce test se connecte simplement à l'hôte, et exécute suffisamment de code pour renvoyer :
<hostname> | SUCCESS => {
"changed": false,
"ping": "pong"
}
Si cela fonctionne, vous pouvez pratiquement exclure tout problème de configuration ou de connectivité, car cela prouve que vous avez pu résoudre le nom d'hôte cible, ouvrir une connexion, vous authentifier et exécuter un module ansible avec l'interpréteur Python distant.
Voici une liste (non exhaustive) de ce qui peut mal se passer au début d'un livre de jeu :
La commande exécutée par ansible attend une entrée interactive.
Je me souviens que cela se produisait sur d'anciennes versions d'ansible, où une commande attendait une entrée interactive qui n'arrivait jamais, comme un mot de passe sudo (lorsque vous avez oublié un mot de passe sudo). -K
), ou l'acceptation d'une nouvelle empreinte d'hôte ssh (pour un nouvel hôte cible).
Les versions modernes d'ansible gèrent ces deux cas avec élégance et lèvent immédiatement une erreur pour les cas d'utilisation normaux, donc à moins que vous ne fassiez des choses comme appeler ssh ou sudo vous-même, vous ne devriez pas avoir ce genre de problème. Et même si c'était le cas, ce serait après la collecte des faits.
Connexion maître ssh morte
Il y a quelques options très intéressantes passées au client ssh, dans le journal de débogage donné ici :
ControlMaster=auto
ControlPersist=60s
ControlPath=/home/vagrant/.ansible/cp/ansible-ssh-%h-%p-%r
Ces options sont documentées dans man ssh_config .
Par défaut, ansible essaiera d'être intelligent en ce qui concerne l'utilisation de sa connexion ssh. Pour un hôte donné, au lieu de créer une nouvelle connexion pour chaque tâche du playbook, il l'ouvrira une fois, et la gardera ouverte pour tout le playbook (et même entre les playbooks).
C'est une bonne chose, car l'établissement d'une nouvelle connexion est beaucoup plus lent et exige beaucoup de calculs que l'utilisation d'une connexion existante.
En pratique, chaque connexion ssh vérifiera l'existence d'une socket à l'adresse ~/.ansible/cp/some-host-specific-path
. La première connexion ne la trouve pas, elle se connecte donc normalement, puis la crée. Toutes les connexions suivantes utiliseront alors simplement cette socket pour passer par la connexion déjà établie.
Même si la connexion établie finit par s'épuiser et se ferme après avoir été inutilisée pendant suffisamment longtemps, la prise est également fermée, et nous sommes de retour à la case départ.
Jusqu'à présent, tout va bien.
Parfois, cependant, la connexion meurt, mais le client ssh la considère toujours comme établie. Cela se produit généralement lorsque vous exécutez le playbook depuis votre ordinateur portable et que vous perdez votre connexion WiFi (ou que vous passez du WiFi à l'Ethernet, etc.).
Ce dernier exemple est une situation terrible : vous kann ssh à la machine cible avec une configuration ssh par défaut, mais tant que votre connexion précédente est toujours considérée comme active, ansible n'essaiera même pas d'en établir une nouvelle.
À ce stade, nous voulons simplement nous débarrasser de cette ancienne prise, et la façon la plus simple de le faire est de la supprimer :
# Delete all the current sockets (may disrupt currently running playbooks)
rm -r ~/.ansible/cp
# Delete only the affected socket (requires to know which one it is)
rm ~/.ansible/cp/<replace-by-your-socket>
C'est parfait pour une solution ponctuelle, mais si cela se produit trop souvent, vous devrez peut-être chercher une solution à plus long terme. Voici quelques conseils qui pourraient vous aider à atteindre cet objectif :
- Lancez les playbooks à partir d'un serveur (avec une connexion réseau bien plus stable que celle de votre ordinateur portable).
- Utilice configuration ansible ou directement Configuration du client ssh pour désactiver le partage de la connexion
- Utilisez les mêmes ressources, mais pour régler avec précision les délais d'attente, de sorte qu'en cas de défaillance de la connexion principale, le délai d'attente soit plus court.
Veuillez noter qu'au moment de la rédaction de ce document, quelques options ont été modifiées (par exemple, ma dernière exécution m'a donné les résultats suivants ControlPath=/home/toadjaune/.ansible/cp/871b533295
), mais l'idée générale reste valable.
La collecte des faits prend en fait trop de temps
Au début de chaque jeu, ansible collecte un grand nombre d'informations sur le système cible, et les place dans le fichier Faits et chiffres . Ce sont des variables que vous pouvez ensuite utiliser dans votre playbook, et qui sont généralement très pratiques, mais parfois, obtenir ces informations peut être très long (mauvais points de montage, disques avec des entrées/sorties élevées, charge élevée ).
Ceci étant dit, vous n'avez pas strictement n'ont pas besoin de faits pour exécuter un playbook, et presque certainement pas tous, donc essayons de désactiver ce dont nous n'avons pas besoin. Plusieurs options pour cela :
À des fins de débogage, il est très pratique d'invoquer le module de configuration directement à partir de la ligne de commande :
ansible -m setup <hostname>
Cette dernière commande devrait se bloquer ainsi que votre playbook, et finalement passer le temps (ou réussir). Maintenant, exécutons à nouveau le module, en désactivant tout ce que nous pouvons :
ansible -m setup -a gather_subset='!all' <hostname>
Si le problème persiste, vous pouvez toujours essayer de désactiver totalement le module dans votre jeu, mais il est fort probable que votre problème se situe ailleurs.
Si, en revanche, il fonctionne bien (et rapidement), jetez un coup d'œil à l'adresse suivante documentation des modules . Vous avez deux options :
- Limiter la collecte de faits à un sous-ensemble, en excluant ce dont vous n'avez pas besoin (voir les valeurs possibles pour le paramètre
gather_subset
)
-
gather_timeout
peut également vous aider à résoudre votre problème, en vous accordant plus de temps (bien que ce soit pour résoudre une erreur de délai d'attente, pas un blocage).
Autres questions
Évidemment, d'autres choses peuvent mal tourner. Quelques conseils pour faciliter le débogage :
- Utiliser le niveau de verbosité maximal d'ansible (
-vvvv
), car il vous montrera chaque commande exécutée
- Utilice
ping
y setup
directement à partir de la ligne de commande comme expliqué ci-dessus
- Essayez de vous connecter manuellement si
ansible -m ping
ne fonctionne pas