Ansible + auto git pull într-un cluster de mașini virtuale în cloud

Ansible + auto git pull într-un cluster de mașini virtuale în cloud

O zi buna

Avem mai multe clustere cloud cu un număr mare de mașini virtuale în fiecare. Găzduim toată această afacere la Hetzner. În fiecare cluster avem o mașină master, un instantaneu este luat din ea și distribuit automat tuturor mașinilor virtuale din cluster.

Această schemă nu ne permite să folosim gitlab-runners în mod normal, deoarece apar multe probleme atunci când apar mulți alergători identici înregistrați, ceea ce ne-a determinat să găsim o soluție și să scriem acest articol/manual.

Aceasta nu este probabil cea mai bună practică, dar această soluție părea cât se poate de convenabilă și simplă.

Pentru tutorial, consultați cat.

Pachete necesare pe mașina principală:

  • piton
  • merge
  • fișier cu chei ssh

Principiul general al implementării gut pull-ului automat pe toate mașinile virtuale este că aveți nevoie de o mașină pe care va fi instalat Ansible. De pe această mașină, ansible va trimite comenzi git pull și va reporni serviciul care a fost actualizat. În aceste scopuri, am creat o mașină virtuală separată în afara clusterelor și am instalat pe ea:

  • piton
  • ansible
  • gitlab-runner

Din probleme de organizare - trebuie să înregistrați gitlab-runner, să faceți ssh-keygen, să încărcați cheia publică ssh a acestei mașini la .ssh/authorized_keys pe mașina principală, deschideți portul 22 pentru ansible pe mașina principală.

Acum să configuram ansible

Deoarece scopul nostru este să automatizăm tot ceea ce este posibil. În dosar /etc/ansible/ansible.cfg vom decomenta linia host_key_checking = Falseastfel încât ansible să nu solicite confirmarea mașinilor noi.

Apoi, trebuie să generați automat un fișier de inventar pentru ansible, de unde va lua ip-ul mașinilor pe care trebuie să faceți git pull.

Generăm acest fișier folosind API-ul Hetzner, puteți lua lista de gazde din baza de date AWS, Asure (aveți un API undeva pentru a vă afișa mașinile care rulează, nu?).

Structura fișierului de inventar este foarte importantă pentru Ansible; ar trebui să arate astfel:

[группа]
ip-адрес
ip-адрес

[группа2]
ip-адрес
ip-адрес

Pentru a genera un astfel de fișier, vom face un script simplu (să-l numim 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

Este timpul să verificați dacă Ansible funcționează și este prietenos cu primirea adreselor IP:

/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group

Ieșirea ar trebui să conțină numele de gazdă ale mașinilor pe care a fost executată comanda.
Câteva cuvinte despre sintaxă:

  • /etc/ansible/./vm_list - generează o listă de mașini
  • -i - calea absolută către fișierul de inventar
  • -m - spune ansible să folosească modulul shell
  • -a este argumentul. Orice comandă poate fi introdusă aici
  • grup — numele clusterului dvs. Dacă trebuie să faceți acest lucru pe toate clusterele, schimbați grupul la toate

Să mergem mai departe - să încercăm să facem git pull pe mașinile noastre virtuale:

/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group 

Dacă în ieșire vedem deja actualizat sau descărcare din depozit, atunci totul funcționează.

Acum, pentru asta a fost menit totul

Să învățăm scriptul nostru să ruleze automat atunci când ne comitem în ramura principală din gitlab

Mai întâi, să facem scriptul nostru mai frumos și să-l punem într-un fișier executabil (să-i spunem exec_pull) -

#!/bin/bash

/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@"

Să mergem la gitlab-ul nostru și să creăm un fișier în proiect .gitlab-ci.yml
Am pus următoarele înăuntru:

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 

Totul este gata. Acum -

  • face un commit
  • Mă bucur că totul funcționează

Când transferați .yml către alte proiecte, trebuie doar să schimbați numele serviciului pentru a reporni și numele cluster-ului pe care vor fi executate comenzile ansible.

Sursa: www.habr.com

Adauga un comentariu