Een fijne dag verder
We hebben verschillende cloudclusters met elk een groot aantal virtuele machines. We hosten dit hele bedrijf bij Hetzner. In elk cluster hebben we één mastermachine, er wordt een momentopname van gemaakt en automatisch gedistribueerd naar alle virtuele machines binnen het cluster.
Dit schema staat ons niet toe om gitlab-runners normaal te gebruiken, omdat er veel problemen optreden als er veel identieke geregistreerde runners verschijnen, wat ons ertoe aanzette een oplossing te vinden en dit artikel/handleiding te schrijven.
Dit is waarschijnlijk niet de beste praktijk, maar deze oplossing leek zo handig en eenvoudig mogelijk.
Voor de tutorial, zie cat.
Vereiste pakketten op de mastermachine:
- python
- git
- bestand met ssh-sleutels
Het algemene principe van het implementeren van automatische gut pull op alle virtuele machines is dat je een machine nodig hebt waarop Ansible wordt geïnstalleerd. Vanaf deze machine zal ansible git pull-opdrachten verzenden en de bijgewerkte service opnieuw starten. Voor deze doeleinden hebben we buiten de clusters een aparte virtuele machine gemaakt en daarop geïnstalleerd:
- python
- Ansible
- gitlab-runner
Van organisatorische problemen: je moet gitlab-runner registreren, ssh-keygen maken, de openbare ssh-sleutel van deze machine uploaden naar .ssh/authorized_keys
op de mastermachine opent u poort 22 voor weerwort op de mastermachine.
Laten we nu anible configureren
Omdat het ons doel is om alles wat mogelijk is te automatiseren. In bestand /etc/ansible/ansible.cfg
we zullen de regel verwijderen host_key_checking = False
zodat Ansible niet om bevestiging van nieuwe machines vraagt.
Vervolgens moet je automatisch een inventarisbestand voor ansible genereren, vanwaar het het ip-adres zal halen van de machines waarop je git pull moet doen.
We genereren dit bestand met behulp van Dezner's API, u kunt de lijst met hosts uit uw AWS-, Asure-database halen (je hebt ergens een API om je actieve machines weer te geven, toch?).
De structuur van het inventarisbestand is erg belangrijk voor Ansible; het zou er als volgt uit moeten zien:
[группа]
ip-адрес
ip-адрес
[группа2]
ip-адрес
ip-адрес
Om zo’n bestand te genereren, maken we een eenvoudig script (laten we het noemen 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
Het is tijd om te controleren of Ansible werkt en vriendelijk is met het ontvangen van IP-adressen:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group
De uitvoer moet de hostnamen bevatten van de machines waarop de opdracht is uitgevoerd.
Een paar woorden over syntaxis:
- /etc/ansible/./vm_list - genereer een lijst met machines
- -i - absoluut pad naar het inventarisbestand
- -m - vertel ansible om de shell-module te gebruiken
- -a is het argument. Hier kan elk commando worden ingevoerd
- groep — de naam van uw cluster. Als u dit op alle clusters moet doen, wijzigt u de groep in alles
Laten we verder gaan - laten we proberen git pull uit te voeren op onze virtuele machines:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group
Als we in de uitvoer al up-to-date zien of uit de repository worden verwijderd, werkt alles.
Dit is nu waar het allemaal voor bedoeld was
Laten we ons script leren om automatisch uit te voeren bij het committen aan de master branch in gitlab
Laten we eerst ons script mooier maken en het in een uitvoerbaar bestand plaatsen (laten we het exec_pull noemen) -
#!/bin/bash
/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@"
Laten we naar ons gitlab gaan en een bestand in het project maken .gitlab-ci.yml
We hebben het volgende erin gezet:
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
Alles is klaar. Nu -
- een verbintenis aangaan
- Ik ben blij dat alles werkt
Wanneer u .yml naar andere projecten overzet, hoeft u alleen maar de naam van de service die opnieuw moet worden opgestart, en de naam van het cluster waarop de ansible-opdrachten worden uitgevoerd, te wijzigen.
Bron: www.habr.com