
Guten Tag
Wir haben mehrere Cloud-Cluster mit einer großen Anzahl virtueller Maschinen in jedem. Alle diese Geräte werden bei Hetzner gehostet. In jedem Cluster haben wir eine Master-Maschine, von der ein Snapshot erstellt und automatisch auf alle virtuellen Maschinen im Cluster verteilt wird.
Dieses Schema erlaubt uns nicht, gitlab-runner normal zu verwenden, da viele Probleme entstehen, wenn es viele identische registrierte Runner gibt. Das hat uns zu einem Umweg und zum Schreiben dieses Artikels/Manuels veranlasst.
Wahrscheinlich ist das nicht die beste Praxis, aber diese Lösung erscheint uns als die praktischste und einfachste.
Für das Tutorial bitte unter den Cut.
Erforderliche Pakete auf der Master-Maschine:
- python
- git
- Datei mit SSH-Schlüsseln
Das grundlegende Prinzip der Implementierung eines automatischen git pull auf allen virtuellen Maschinen besteht darin, dass eine Maschine erforderlich ist, auf der Ansible installiert ist. Von dieser Maschine wird Ansible die Befehle git pull und den Neustart des aktualisierten Dienstes senden. Wir haben dafür eine separate virtuelle Maschine außerhalb der Cluster erstellt und darauf installiert:
- python
- ansible
- gitlab-runner
Bezüglich organisatorischer Fragen – es ist notwendig, einen gitlab-runner zu registrieren, ssh-keygen auszuführen und den öffentlichen SSH-Schlüssel dieser Maschine in .ssh/authorized_keys auf der Master-Maschine zu speichern, und den Port 22 auf der Master-Maschine für Ansible zu öffnen.
Jetzt konfigurieren wir Ansible
Da unser Ziel ist, alles zu automatisieren, was möglich ist. In der Datei /etc/ansible/ansible.cfg werden wir die Zeile host_key_checking = False, auskommentieren, damit Ansible keine Bestätigung neuer Maschinen anfordert.
Als Nächstes ist es notwendig, automatisch eine Inventardatei für Ansible zu generieren, aus der es die IP-Adressen der Maschinen abruft, auf denen ein git pull durchgeführt werden soll.
Wir generieren diese Datei mit Hilfe der Hetzner-API, Sie können die Liste der Hosts auch aus Ihrem AWS, Azure, DB entnehmen (Sie haben doch irgendwo eine API, um Ihre laufenden Maschinen anzuzeigen, oder?).
Für Ansible ist die Struktur der Inventardatei von großer Bedeutung, sie sollte wie folgt aussehen:
[Gruppe]
ip-Adresse
ip-Adresse
[Gruppe2]
ip-Adresse
ip-AdresseUm eine solche Datei zu generieren, erstellen wir ein einfaches Skript (nennen wir es 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_ipEs ist Zeit zu überprüfen, ob Ansible funktioniert und mit der Abholung der IP-Adressen kompatibel ist:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group
Im Output sollten die Hostnamen der Maschinen angezeigt werden, auf denen der Befehl ausgeführt wurde.
Ein paar Worte zur Syntax:
- /etc/ansible/./vm_list — генерируем список машин
- -i — absoluter Pfad zur Inventardatei
- -m — Wir verwenden das shell-Modul in Ansible
- -a — Argument. Hier kann ein beliebiger Befehl eingegeben werden
- group — der Name Ihres Clusters. Wenn Sie dies für alle Cluster tun möchten, ändern Sie group in all
Weiter geht's — wir versuchen, git pull auf unseren zu machen virtuellen Maschinen:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group Wenn wir in der Ausgabe bereits auf dem neuesten Stand oder die Entladung aus dem Repository sehen, funktioniert alles.
Jetzt zu dem, wofür das alles gedacht war
Wir werden unser Skript so einrichten, dass es automatisch bei einem Commit im Master-Branch in GitLab ausgeführt wird
Zuerst machen wir unser Skript schöner und stecken es in eine ausführbare Datei (wir nennen sie exec_pull) —
#!/bin/bash
/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@" Wir gehen zu unserem GitLab und erstellen die Datei im Projekt .gitlab-ci.yml
Wir fügen folgendes ein:
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 bereit. Jetzt —
- machen wir einen Commit
- wir glauben, dass alles funktioniert
Wenn man die .yml in andere Projekte überträgt, reicht es aus, nur den Namen des Dienstes für den Neustart und den Namen des Clusters zu ändern, auf dem die Ansible-Befehle ausgeführt werden.
Quelle: habr.com
