2013-07-30 10 views
9

Chciałbym użyć Ansible, aby wykonywać jednocześnie proste zadanie na kilku zdalnych węzłach. Rzeczywiste zadanie polega na przesuwaniu niektórych plików dziennika, a następnie przetwarzaniu wyników na moim lokalnym hoście (który ma oprogramowanie niedostępne w zdalnych węzłach).Jak prowadzić program Ansible programowo i współbieżnie?

Narzędzia ansible działające w wierszu poleceń nie wydają się dobrze pasować do tego przypadku użycia, ponieważ łączą formatowanie generowane ansibli z wyjściem zdalnie wykonanego polecenia. Wygląda na to, że API Pythona powinno być na to zdolne, ponieważ ujawnia niezmodyfikowane wyjście (poza potencjalnym wymieszaniem unicode, które nie powinno być tutaj istotne).

Uproszczona wersja programu Pythona Mam wymyślić wygląda następująco:

from sys import argv 
import ansible.runner 
runner = ansible.runner.Runner(
    pattern='*', forks=10, 
    module_name="command", 
    module_args=(
     """ 
     sleep 10 
     """), 
    inventory=ansible.inventory.Inventory(argv[1]), 
) 
results = runner.run() 

Tutaj sleep 10 stoi za rzeczywiste dzienniku polecenie grepping - chodzi o to, żeby zasymulować komendę, która nie jest natychmiast zakończyć.

Jednak po uruchomieniu tego obserwuję, że ilość czasu jest proporcjonalna do liczby hostów w moim ekwipunku. Oto wyniki czasowe przeciwko zapasów z 2, 5 i 9 zastępów odpowiednio:

[email protected]:/tmp$ time python howlong.py two-hosts.inventory 
real 0m24.285s 
user 0m0.216s 
sys  0m0.120s 
[email protected]:/tmp$ time python howlong.py five-hosts.inventory                     
real 0m55.120s 
user 0m0.224s 
sys  0m0.160s 
[email protected]:/tmp$ time python howlong.py nine-hosts.inventory 
real 1m57.272s 
user 0m0.360s 
sys  0m0.284s 
[email protected]:/tmp$ 

Niektóre inne przypadkowe obserwacje:

  • ansible all --forks=10 -i five-hosts.inventory -m command -a "sleep 10" wykazuje takie samo zachowanie
  • ansible all -c local --forks=10 -i five-hosts.inventory -m command -a "sleep 10" wydaje się wykonać rzeczy jednocześnie (ale działa tylko w przypadku połączeń tylko lokalnych, oczywiście)
  • wydaje się wykonywać rzeczy jednocześnie

Być może sugeruje to problem z transportem ssh i nie ma nic wspólnego z używaniem ansible za pośrednictwem interfejsu API Pythona, a nie z linii komand.

Co jest nie tak, co uniemożliwia korzystanie z domyślnego transportu przez około dziesięć sekund, niezależnie od liczby hostów w moim ekwipunku?

Odpowiedz

5

Niektóre dochodzenie ujawnia, że ​​ansible szuka hostów w moim ekwipunku w ~/.ssh/known_hosts. Moja konfiguracja ma włączone HashKnownHosts. ansible nie jest nigdy w stanie znaleźć szukanych pozycji hosta, ponieważ nie rozumie formatu hash hosts hosts.

Gdy transport SSH ansambla nie może znaleźć znanego wpisu hosta, uzyskuje globalną blokadę na czas trwania działania modułu. Rezultatem tego połączenia jest to, że wszystkie wykonania są skutecznie serializowane.

Tymczasowym obejściem jest zrezygnowanie z niektórych zabezpieczeń i wyłączenie sprawdzania kluczy hosta przez wprowadzenie host_key_checking = False do host_key_checking = False w . Innym rozwiązaniem jest użycie transportu paramiko (ale jest to niewiarygodnie powolne, być może dziesiątki lub setki razy wolniejsze niż transport ssh, z jakiegoś powodu). Kolejnym obejściem jest pozwolenie, aby niektóre nierozdzielone wpisy zostały dodane do pliku known_hosts w celu znalezienia ssh transportu ansshana.

3

Ponieważ masz włączone HashKnownHosts, powinieneś uaktualnić do najnowszej wersji Ansible. Wersja 1.3 dodano obsługę mieszania known_hosts, patrz the bug tracker i changelog.Powinno to rozwiązać Twój problem bez uszczerbku dla bezpieczeństwa (obejście przy użyciu host_key_checking=False) lub z poświęceniem prędkości (twoje obejście za pomocą paramiko).

+1

To jest mój raport o błędzie po odkryciu przyczyny problemu tutaj. :) –

+0

Och, nie wiedziałem, że to zostało przez ciebie zgłoszone (kwestia GH została otwarta przez mpdehaan i naprawiona przez jimi-c). Dziękujemy za zwrócenie uwagi twórców! :) –

0

Z ansibl 2.0 Python API, zgasiłem StrictHostKeyChecking z

import ansible.constants 

ansible.constants.HOST_KEY_CHECKING = False 

udało mi się przyspieszyć ansibl znacznie ustawiając następujące na zarządzanych komputerach. Nowsza wersja sshd ma domyślnie odwrotną stronę, więc może nie być potrzebna w twoim przypadku.

/etc/ssh/sshd_config 
---- 
UseDNS no