C'è un modo per eseguire i cicli with_items in parallelo in Ansible?


12

Sto eseguendo Ansible 2.2, ma posso aggiornare se aiuta.

Ho visto questo e sono stato abbastanza emozionato, ma non sembra essere in questo (o qualsiasi) versione di documentazione Ansible.

Il problema che sto cercando di risolvere è che ho 1000 utenti che devo gestire su un box Centos.

Ci vuole parecchio tempo per eseguire questo compito in serie. E ancora più fastidioso, tutto appare come cambiato perché il comando "scade" sul modulo utente contrassegna sempre la cosa come modificata.

anche questo sembrava promettente, ma ci è voluto lo stesso tempo per eseguire ciascun comando nel ciclo with_items e non è andato più veloce (non mi sono mai preso la briga di aspettare abbastanza per arrivare alla fine).

Saltare le attività ora è veloce (molto più veloce di Ansible 2.0), se non riesco a capire come farlo funzionare in parallelo, penso che tornerò indietro e scoprirò come saltare attività inutili e se tutto altrimenti fallirà, scriverò il mio modulo. Ma sembra che dovrei essere in grado di fare tutto questo più velocemente in Ansible.


Questo è ciò che voglio eseguire in parallelo, host_authorizationsè un elenco di nomi utente e altri dati.

  - name: Create/modify OS user accounts
    user: name={{ item.username }} group=sshusers shell=/bin/bash home="/home/selinux-modules/{{ item.username }}" state=present expires={{item.expiredate|default(omit)}}
    with_items: "{{ host_authorizations }}"
    tags: full_maintenance

Fornisci uno snippet di codice. Altrimenti è difficile aiutare.
030

@ 030 c'è uno snippet, immagino che aiuti un po 'per il contesto. Sono più interessato concettualmente se esiste davvero un modo per eseguire attività (in un ciclo) in parallelo sullo stesso host. So che potrei fare un sacco di cose individuali con asincrono, ma non tanto con with_items.
Peter Turner,

Quindi, in pratica, se devono essere creati 1000 utenti, è necessario completarli con la stessa velocità con cui si crea un solo utente. Interessante, perché non usare qualcosa come LDAP?
030

1
Scherzi a parte, stai andando verso un percorso doloroso, non penso che nessuno gestisca più di una dozzina di account con una base di account locale, non appena il numero di utenti cresce, presumo che tutti si spostino in un sistema contabile centralizzato, di solito un po 'di backend ldap (potrebbe essere la directory attiva) e quindi impostare il tempo di scadenza e la chiave pubblica come attributi di questa base centrale, quindi usare cose come sss_ssh_authorizedkeys per consentire al server ssh di ottenere le chiavi autorizzate da questa base centrale.
Tensibai,

2
Non sono d'accordo sul fatto che questo sia il motivo per cui (accenno che non fa la creazione / gestione di utenti in blocco). Sono d'accordo sul fatto che gli account non dovrebbero essere gestiti su basi di account locali a grande volume (il fatto che non siano account umani è comunque irrilevante per il problema)
Tensibai,

Risposte:


13

Come menzionato @webKnja questo è possibile con la asyncmodalità. L'ho scoperto di recente da solo e ho imparato che puoi usarlo in 3 modi diversi a seconda delle tue esigenze.

  1. Eseguire e eseguire il polling dei risultati, notare il poll:5, Ciò eseguirà il polling dei risultati ogni 5 secondi. Puoi risparmiare un po 'di tempo con questo metodo.

    - name: My long runing task
      some_module_name:
        ip: "{{item.fabric}}"
        username: "{{user}}"
        password: "{{password}}"
        secret: "{{secret}}"
      loop: "{{zoning_list}}"
      register: _alias_vc_0
      async: 60
      poll: 5
    
  2. Spara e dimentica poll: 0 , questa è un'opzione molto rapida poiché Ansible sta solo sparando a quei compiti. Il lato negativo è che non sappiamo quale sia stato il risultato dell'attività, ad es changed: True/False. Naturalmente è un aspetto negativo se ti interessa il feedback;).

    name: My long runing task
    some_module_name:
      ip: "{{item.fabric}}"
      username: "{{user}}"
      password: "{{password}}"
      secret: "{{secret}}"
    loop: "{{zoning_list}}"
    register: _alias_vc_0
    async: 60
    poll: 0
    
  3. Spara e dimentica conasync_status , la sintassi per l'attività è la stessa dell'esempio 2 per cui richiederà attività aggiuntiva async_status. Questo è il mio preferito in quanto è relativamente veloce (più veloce del normale looping o del execute and poll) e ti consente di acquisire il feedback, anche se dovrai occuparti di nuovo registerper il tuo async_task.

    retries: 20 - quanti tentativi prima di fallire.

    delay: 2 - quanti secondi attendere tra i sondaggi.

    - name: My long runing task
      some_module_name:
        ip: "{{item.fabric}}"
        username: "{{user}}"
        password: "{{password}}"
        secret: "{{secret}}"
      loop: "{{zoning_list}}"
      register: _alias_vc_0
      async: 60
      poll: 0
    
    
    - name: Wait for My long running task to finish
      async_status:
        id: "{{ item.ansible_job_id }}"
      register: _jobs_alias_vc_0
      retries: 20
      delay: 2
      until: _jobs_alias_vc_0.finished
      loop: "{{_alias_vc_0.results}}"
    

Un avvertimento , a seconda dell'attività che potresti non essere in grado di utilizzare l' asyncopzione. Ho avuto degli esempi in cui interagivo con il sistema che non era in grado di gestire più richieste per la stessa risorsa. Ho trovato l' asyncopzione che funziona meglio se devo svolgere la stessa attività su più host. È lì che sono stato in grado di "salvare" la maggior parte del tempo.

Dato che hai pubblicato il link alla documentazione di Ansible nella domanda non ho intenzione di farlo.


@chicks potresti voler cambiare il pollvalore a 0 nell'esempio 3. Questa è una spiegazione straordinaria !! Thnx.
Debanjan Basu,

@DebanjanBasu Chiunque può apportare modifiche suggerite. Potrei essere io a approvarlo nelle code di revisione, ma dovresti ottenere credito per la modifica stessa.
pulcini,

Le modifiche di un personaggio non sono consentite purtroppo! :(
Debanjan Basu

2
L'opzione 3 funziona alla grande, grazie! Un commento però: almeno da Ansible 2.8, async_statusrichiede di jidno id.
Edward, del

4

Per rispondere alla tua domanda: No, al momento Ansible non può eseguire cicli in parallelo.

Userei newusersinvece, che è fatto per la creazione di utenti in blocco. Creare un file con tutti gli utenti in esso, copiarlo verso l'ospite, ed eseguire newusers /path/to/user/listin un commandcompito.


3

È possibile ottenere questo utilizzando la asyncmodalità. Di seguito sono riportati alcuni riferimenti per come procedere.

refs:

---

- name: Run tasks in parallel
  hosts: localhost
  connection: local
  gather_facts: no
  tasks:
    - name: Pretend to create instances
      command: "sleep {{ item }}"  # Instead of calling a long running operation at a cloud provider, we just sleep.
      with_items:
        - 6
        - 8
        - 7
      register: _create_instances
      async: 600  # Maximum runtime in seconds. Adjust as needed.
      poll: 0  # Fire and continue (never poll)

    - name: Wait for creation to finish
      async_status:
        jid: "{{ item.ansible_job_id }}"
      register: _jobs
      until: _jobs.finished
      delay: 5  # Check every 5 seconds. Adjust as you like.
      retries: 10  # Retry up to 10 times. Adjust as needed.
      with_items: "{{ _create_instances.results }}"

Mentre quei collegamenti possono rispondere alla domanda se arrivano a rompersi, non c'è più niente nella tua risposta per i futuri lettori, per favore prova a mostrare come questo potrebbe aiutare a risolvere il problema con le tue parole / esempio e lasciare i collegamenti solo per informazioni più dettagliate.
Tensibai,

sì, non posso contrassegnare questo come risposta fino a quando A.) ​​lo collaudo e B.) il relativo codice viene inserito qui. Ma grazie per avermi indicato in questa direzione.
Peter Turner,

Scusa, ero di fretta :)
webKnjaZ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.