97 votes

Ansible bloqué sur la collecte des faits

J'ai quelques problèmes étranges avec ma boîte ansible (vagrant).

Tout a fonctionné hier et mon playbook fonctionnait bien.

Aujourd'hui, ansible s'accroche à la "collecte de faits" ?

Voici la sortie verbeuse :

<5.xxx.xxx.xxx> ESTABLISH CONNECTION FOR USER: deploy
<5.xxx.xxx.xxx> REMOTE_MODULE setup
<5.xxx.xxx.xxx> EXEC ['ssh', '-C', '-tt', '-vvv', '-o', 'ControlMaster=auto', '-
o', 'ControlPersist=60s', '-o', 'ControlPath=/home/vagrant/.ansible/cp/ansible-s
sh-%h-%p-%r', '-o', 'Port=2221', '-o', 'KbdInteractiveAuthentication=no', '-o',
'PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey', '-o
', 'PasswordAuthentication=no', '-o', 'User=deploy', '-o', 'ConnectTimeout=10',
'5.xxx.xxx.xxx', "/bin/sh -c 'mkdir -p $HOME/.ansible/tmp/ansible-tmp-1411372677
.18-251130781588968 && chmod a+rx $HOME/.ansible/tmp/ansible-tmp-1411372677.18-2
51130781588968 && echo $HOME/.ansible/tmp/ansible-tmp-1411372677.18-251130781588
968'"]

78voto

j2fly Points 11

J'avais un problème similaire avec le ping d'Ansible sur Vagrant, il s'est soudainement bloqué sans raison alors qu'il fonctionnait parfaitement auparavant. Contrairement à tout autre problème comme ssh ou problème de connexion, il est juste mort pour toujours sans délai d'attente.

Une chose que j'ai faite pour résoudre ce problème est de nettoyer ~/.ansible et ça fonctionne à nouveau. Je n'arrive pas à savoir pourquoi, mais le problème a été résolu.

Si vous avez de la monnaie pour l'avoir à nouveau, essayez de nettoyer le ~/.ansible avant de rafraîchir votre Vagrant.

31voto

toadjaune Points 361

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

30voto

Va As Points 111

Ansible peut se bloquer comme cela pour un certain nombre de raisons, généralement à cause d'un problème de connexion ou parce que le module de configuration se bloque. Voici comment circonscrire le problème pour pouvoir le résoudre.

Ansible ne peut pas se connecter à l'hôte de destination

Problèmes de clé d'hôte (known_hosts)

1) Sur les anciennes versions d'Ansible (2.1 ou antérieures), Ansible ne vous indiquait pas toujours si la clé d'hôte pour la destination n'existe pas sur la source, ou s'il y a un décalage.

Solution : essayez d'ouvrir une connexion SSH avec les mêmes paramètres vers cette destination. Vous trouverez peut-être des erreurs SSH à résoudre, et la commande fonctionnera alors.

2) Parfois, Ansible vous affiche un message de connexion SSH au milieu d'autres statuts, ce qui entraîne un "gel" d'Ansible sur cette tâche :

Warning: the ECDSA host key for 'myhost' differs from the key for the IP address '10.10.1.10'
Offending key for IP in /etc/ssh/ssh_known_hosts:246
Matching host key in /etc/ssh/ssh_known_hosts:477
Are you sure you want to continue connecting (yes/no)?

Dans ce cas, il suffit de taper "oui" à autant de questions SSH qu'il vous a été demandé pour que le jeu se poursuive. Ensuite, vous pouvez corriger les problèmes de known_hosts de la racine.

Problèmes d'authentification par clé privée

Si l'on utilise l'authentification par clé plutôt que par mot de passe, d'autres problèmes se posent :

  • La clé privée peut ne pas être configurée correctement sur la destination
  • La clé privée peut avoir des permissions incorrectes localement (elle ne doit être lisible que par l'utilisateur qui exécute le travail Ansible).

Solution : essayez d'exécuter ansible -m ping <destination> -k contre l'hôte qui pose problème - si cela ne fonctionne pas, essayez l'option Problèmes liés aux clés de l'hôte solutions ci-dessus.

Ansible ne peut pas rassembler rapidement les faits

El setup (lorsqu'il est exécuté automatiquement au début d'un projet de ansible-playbook ou lorsqu'il est exécuté manuellement en tant que ansible -m setup <host> ) peut souvent se bloquer lors de la collecte d'informations sur le matériel (par exemple, si l'on obtient des informations sur les disques d'hôtes ayant des entrées/sorties élevées, de mauvaises entrées de montage, etc.)

Solution : essayez d'exécuter ansible -m setup -a gather_subset=!all <destination> . Si cela fonctionne, vous devriez envisager de définir cette ligne dans votre ansible.cfg :

gather_subset=!hardware

27voto

Joshua Points 2622

Pour moi, le module d'installation était bloqué sur un montage NFS mort.

Si vous faites un "df" sur votre machine et que rien ne se passe, vous êtes peut-être dans le même cas.

PS : si vous n'arrivez pas à umount le partage/montage NFS, pensez à utiliser le mauvais "umount -l".

9voto

Tim Moses Points 91

J'ai eu un problème similaire avec Ansible qui s'accrochait à Gathering Facts. J'ai réduit mon script à une invite sans tâches ni rôles et il s'est toujours bloqué.

J'ai trouvé 12 processus ansible suspendus dans ma liste de processus qui s'étaient accumulés au cours de la journée.

/usr/bin/python /tmp/ansible_Jfv4PA/ansible_module_setup.py
/usr/bin/python /tmp/ansible_M2T10L/ansible_module_setup.py

Une fois que je les ai tués, ça a recommencé à fonctionner.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X