Há muitas razões pelas quais o ansible pode travar na coleta de fatos, mas antes de prosseguir, aqui está o primeiro teste que você deve fazer em uma situação dessas:
ansible -m ping <hostname>
Este teste apenas se conecta ao host e executa código suficiente para retornar:
<hostname> | SUCCESS => {
"changed": false,
"ping": "pong"
}
Se isso funcionar, você poderá excluir qualquer problema de configuração ou conectividade, pois isso prova que você pode resolver o nome do host de destino, abrir uma conexão, autenticar e executar um módulo ansible com o interpretador python remoto.
Agora, aqui está uma lista (não exaustiva) de coisas que podem dar errado no início de um manual:
O comando executado pelo ansible está aguardando uma entrada interativa
Lembro-me disso em versões mais antigas, em que um comando aguardaria uma entrada interativa que nunca chegaria, como uma senha sudo (quando você esqueceu uma -K
opção) ou a aceitação de uma nova impressão digital do host ssh (para um novo destino). hospedeiro).
As versões modernas do ansible lidam com esses dois casos normalmente e geram um erro imediatamente para casos de uso normais; portanto, a menos que você esteja fazendo coisas como chamar ssh ou sudo, você não deve ter esse tipo de problema. E mesmo se você o fizesse, seria após a coleta de fatos.
Conexão mestre ssh morto
Existem algumas opções muito interessantes passadas para o cliente ssh, no log de depuração fornecido aqui:
ControlMaster=auto
ControlPersist=60s
ControlPath=/home/vagrant/.ansible/cp/ansible-ssh-%h-%p-%r
Essas opções estão documentadas no man ssh_config .
Por padrão, o ansible tentará ser inteligente em relação ao uso da conexão ssh. Para um determinado host, em vez de criar uma nova conexão para todas as tarefas do jogo, ele será aberto uma vez e será mantido por todo o manual (e mesmo entre os manuais).
Isso é bom, pois o estabelecimento de uma nova conexão é muito mais lento e exige mais computação do que usar uma já existente.
Na prática, toda conexão ssh verificará a existência de um soquete em ~/.ansible/cp/some-host-specific-path
. A primeira conexão não pode encontrá-lo; portanto, ele se conecta normalmente e depois o cria. Toda conexão subsequente usará esse soquete para passar pela conexão já estabelecida.
Mesmo que a conexão estabelecida finalmente atinja o tempo limite e feche depois de não ser usada por tempo suficiente, o soquete também está fechado e voltamos à estaca zero.
Por enquanto, tudo bem.
Às vezes, no entanto, a conexão realmente morre, mas o cliente ssh ainda a considera estabelecida. Isso normalmente acontece quando você executa o manual do laptop e perde a conexão Wi-Fi (ou muda de Wi-Fi para Ethernet, etc.)
Este último exemplo é uma situação terrível: você pode ssh na máquina de destino com uma configuração ssh padrão, mas enquanto sua conexão anterior ainda for considerada ativa, o ansible nem tentará estabelecer uma nova.
Neste ponto, apenas queremos nos livrar desse soquete antigo, e a maneira mais simples de fazer isso é removê-lo:
# 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>
Isso é perfeito para uma correção de uma só vez, mas se isso acontecer com muita freqüência, talvez você precise procurar uma correção de longo prazo. Aqui estão alguns indicadores que podem ajudar a alcançar esse objetivo:
- Inicie playbooks a partir de um servidor (com uma conexão de rede muito mais estável que a do seu laptop)
- Use a configuração ansible ou diretamente a configuração do cliente ssh para desativar o compartilhamento de conexão
- Use os mesmos recursos, mas para ajustar o tempo limite, para que uma falha na conexão principal se esgote mais rapidamente
Observe que, no momento da redação deste artigo, algumas opções foram alteradas (por exemplo, minha última execução ControlPath=/home/toadjaune/.ansible/cp/871b533295
), mas a ideia geral ainda é válida.
Coleta de fatos, na verdade, leva muito tempo
No início de cada jogada, o ansible coleta muitas informações no sistema de destino e as coloca em Fatos . Essas são as variáveis que você pode usar em seu manual e geralmente são realmente úteis, mas às vezes a obtenção dessas informações pode ser muito longa (pontos de montagem ruins, discos com alto I / O, alta carga ...)
Dito isto, você não precisa estritamente de fatos para executar um manual, e quase certamente nem todos, então vamos tentar desativar o que não precisamos. Várias opções para isso:
Para propósitos de depuração, é realmente conveniente chamar o módulo de instalação diretamente da linha de comando:
ansible -m setup <hostname>
Este último comando deve travar, assim como o seu manual, e eventualmente expirar (ou obter êxito). Agora, vamos executar o módulo novamente, desativando tudo o que podemos:
ansible -m setup -a gather_subset='!all' <hostname>
Se isso ainda travar, você sempre pode tentar desativar totalmente o módulo no seu jogo, mas é realmente provável que o seu problema esteja em outro lugar.
Se, no entanto, funcionar bem (e rapidamente), consulte a documentação do módulo . Você tem duas opções:
- Limite a coleta de fatos a um subconjunto, excluindo o que você não precisa (consulte os possíveis valores para
gather_subset
)
gather_timeout
também pode ajudar a corrigir o problema, permitindo mais tempo (embora isso seja para corrigir um erro de tempo limite, não um travamento)
Outros problemas
Obviamente, outras coisas podem dar errado. Alguns ponteiros para ajudar na depuração:
- Use o nível de verbosidade máximo ansible (
-vvvv
), pois ele mostrará todos os comandos executados
- Use
ping
e setup
módulos diretamente da linha de comando, conforme explicado acima
- Tente ssh manualmente se
ansible -m ping
não funcionar
vagrant ssh
investigar durante o travamento para ver se há algo útil nops
enetstat
? Além disso, um dos primeiros suspeitos em travamentos é o DNS - verifique se o DNS está resolvendo de dentro da máquina virtual.