
Buongiorno
Abbiamo diversi cluster cloud con un gran numero di macchine virtuali in ciascuno. Tutto questo è ospitato su Hetzner. In ogni cluster abbiamo una macchina master da cui viene creato uno snapshot e distribuito automaticamente a tutte le VM all'interno del cluster.
Questo schema non ci consente di utilizzare correttamente i gitlab-runner, poiché sorgono molti problemi con la presenza di molti runner registrati identici, il che ci ha spinti a trovare una soluzione alternativa e a scrivere questo articolo/manuale.
Probabilmente non è la best practice, ma questa soluzione ci è sembrata la più comoda e semplice.
Per il tutorial vi chiedo di proseguire a questo link.
Pacchetti necessari sulla macchina master:
- python
- git
- file con le chiavi ssh
Il principio generale di implementazione di un git pull automatico su tutte le macchine virtuali è che è necessaria una macchina su cui sarà installato Ansible. Da questa macchina, Ansible invierà comandi git pull e riavvierà il servizio aggiornato. Abbiamo creato per questo scopo una macchina virtuale separata al di fuori dei cluster e abbiamo installato su di essa:
- python
- ansible
- gitlab-runner
Per motivi organizzativi, è necessario registrare il gitlab-runner, creare ssh-keygen e aggiungere la chiave pubblica ssh di questa macchina nel .ssh/authorized_keys sulla macchina master, aprire la porta 22 sulla macchina master per Ansible.
Ora configuriamo Ansible
Poiché il nostro obiettivo è automatizzare tutto ciò che è possibile. Nel file /etc/ansible/ansible.cfg decommenteremo la riga host_key_checking = False, in modo che Ansible non richieda conferma per le nuove macchine.
Successivamente, è necessario generare automaticamente un file di inventario per Ansible, da cui estrarrà gli indirizzi IP delle macchine su cui eseguire il git pull.
Generiamo questo file utilizzando l'API di Hetzner, oppure potete ottenere l'elenco degli host dalla vostra AWS, Azure, DB (avete un'API per elencare le vostre macchine in esecuzione, giusto?).
Per Ansible, è molto importante la struttura del file di inventario, deve avere il seguente aspetto:
[gruppo]
ip-indirizzo
ip-indirizzo
[gruppo2]
ip-indirizzo
ip-indirizzoPer generare un file di questo tipo, creiamo uno script semplice (lo chiameremo vm_list):
#!/bin/bash
echo [group] > /etc/ansible/cloud_ip &&
"ваш CLI запрос на получение IP запущенных машин в кластере" >> /etc/ansible/cloud_ip
echo " " >> /etc/ansible/cloud_ip
echo [group2] > /etc/ansible/cloud_ip &&
"ваш CLI запрос на получение IP запущенных машин в другом кластере" >> /etc/ansible/cloud_ipÈ giunto il momento di verificare se Ansible funziona e si collega correttamente per ricevere gli indirizzi IP:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group
Nell'output dovremmo ottenere i nomi host delle macchine su cui è stato eseguito il comando.
Due parole sulla sintassi:
- /etc/ansible/./vm_list — генерируем список машин
- -i — percorso assoluto al file di inventario
- -m — diciamo ad Ansible di utilizzare il modulo shell
- -a — argomento. Qui puoi inserire qualsiasi comando
- group — nome del tuo cluster. Se bisogna farlo su tutti i cluster, cambiamo group in all
Andiamo avanti — proviamo a fare git pull sui nostri macchine virtuali:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group Se nell'output vediamo already up to date o un'estrazione dal repository, significa che tutto funziona.
Ora ciò per cui tutto questo è stato pensato
Insegneremo al nostro script di eseguirsi automaticamente al commit nel branch master su gitlab
Prima renderemo il nostro script più elegante e lo metteremo in un file eseguibile (lo chiameremo exec_pull) —
#!/bin/bash
/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@" Andiamo su gitlab e nel progetto creiamo un file .gitlab-ci.yml
Inseriamo il seguente contenuto:
variables:
GIT_STRATEGY: none
VM_GROUP: group
stages:
- pull
- restart
run_exec_pull:
stage: pull
script:
- /etc/ansible/exec_pull 'cd /path/to/project/'$CI_PROJECT_NAME' && git pull' $VM_GROUP
only:
- master
run_service_restart:
stage: restart
script:
- /etc/ansible/exec_pull 'your_app_stop && your_app_start' $VM_GROUP
only:
- master Tutto è pronto. Ora —
- effettuiamo il commit
- speriamo che tutto funzioni
Quando si trasferisce .yml in altri progetti, è sufficiente cambiare solo il nome del servizio per il riavvio e il nome del cluster su cui verranno eseguiti i comandi ansible.
Fonte: habr.com
