
Bună ziua
Dispunem de mai multe clustere cloud cu un număr mare de mașini virtuale în fiecare. Toate acestea sunt găzduite la Hetzner. Fiecare cluster are câte o mașină master, de pe care se face un snapshot și se distribuie automat pe toate mașinile virtuale din cluster.
Această schemă nu ne permite să folosim corect gitlab-runner, deoarece apar foarte multe probleme din cauza diverselor runneri înregistrați identic, ceea ce ne-a determinat să căutăm o soluție alternativă și să scriem acest articol/manual.
Probabil că acesta nu este cel mai bun mod de a proceda, dar această soluție ne-a părut cea mai convenabilă și simplă.
Pentru tutorial, vă rog să faceți click pe continue.
Pachetele necesare pe mașina master:
- python
- git
- fișier cu chei ssh
Principiul de bază al implementării automatelor git pull pe toate mașinile virtuale este acela că avem 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. Am creat pentru aceste scopuri o mașină virtuală separată în afara clustrelor, pe care am instalat:
- python
- ansible
- gitlab-runner
Din întrebările organizatorice - trebuie să înregistrăm gitlab-runner, să facem ssh-keygen, să copiem cheia publică ssh a acestei mașini în .ssh/authorized_keys pe mașina master, să deschidem portul 22 pe mașina master pentru Ansible.
Acum să configurăm Ansible
Având în vedere că obiectivul nostru este să automatizăm tot ce se poate. În fișierul /etc/ansible/ansible.cfg vom decomenta linia host_key_checking = False, astfel încât Ansible să nu ceară confirmarea noilor mașini.
Apoi, trebuie să generăm automat un fișier de inventar pentru Ansible, din care el va lua ip-urile mașinilor pe care trebuie să facă git pull.
Generăm acest fișier cu ajutorul API-ului Hetzner, iar voi puteți lua lista de hosturi din AWS, Azure, Baza de date (sigur aveți un API pentru a obține mașinile voastre active, nu?).
Pentru Ansible, este foarte importantă structura fișierului de inventar, care trebuie să aibă următorul format:
[grupă]
ip-adresa
ip-adresa
[grupă2]
ip-adresa
ip-adresaPentru 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_ipEste momentul să verificăm dacă Ansible funcționează și colaborează cu obținerea ip-urilor:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group
În output ar trebui să primim numele hosturilor pe care s-a executat comanda.
Câteva cuvinte despre sintaxă:
- /etc/ansible/./vm_list — генерируем список машин
- -i — calea absolută către fișierul de inventar
- -m — spunem lui Ansible să folosească modulul shell
- -a — argument. Aici se poate scrie orice comandă
- group — numele cluster-ului tău. Dacă trebuie să aplicăm pe toate cluster-ele, schimbăm group pe all
Mergem mai departe — să încercăm să facem git pull pe al nostru virtuálne mašini:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group Dacă în output vedem already up to date sau descărcare din repository, atunci totul funcționează.
Acum, scopul pentru care s-a gândit tot acest lucru
Vom învăța scriptul nostru să se execute automat la commit în ramura principală în gitlab
Mai întâi să facem scriptul nostru mai frumos și să-l punem într-un fișier executabil (îl vom numi exec_pull) —
#!/bin/bash
/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@" Mergem în gitlab și în proiect creăm un fișier .gitlab-ci.yml
În interior punem următoarele:
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 —
- facem commit
- să ne bucurăm că totul funcționează
Atunci când transferăm .yml în alte proiecte, este suficient să schimbăm doar numele serviciului pentru restart și numele cluster-ului pe care se vor executa comenzile ansible.
Sursa: habr.com
