
Добър ден
Имаме няколко облачни клъстера с много виртуални машини във всеки от тях. Всичко това е хоствано в Hetzner. Във всеки клъстер имаме по една мастер машина, от която се прави снимка и автоматично се разпределя на всички виртуалки в клъстера.
Тази схема не позволява нормалното използване на gitlab-runner-и, тъй като възникват много проблеми при появата на множество идентични регистрирани ранери, което ни накара да се опитаме да намерим обходен път и да напишем тази статия/мануал.
Вероятно, това не е най-добрата практика, но това решение ни се струва най-удобно и просто.
За туториала моля за подкат.
Необходимите пакети на мастер машината:
- python
- git
- файл с ssh ключове
Общият принцип за реализиране на автоматичен git pull на всички виртуалки е, че ни е нужна машина, на която да бъде инсталиран Ansible. От тази машина ansible ще изпраща команди git pull и рестарт на услугата, която е обновена. Създадохме за тези цели отделна виртуална машина извън клъстерите и инсталирахме на нея:
- python
- ansible
- gitlab-runner
От организационни въпроси – необходимо е да регистрирате gitlab-runner, да направите ssh-keygen и да качите публичния ssh ключ на тази машина в .ssh/authorized_keys на мастер машината, да отворите 22 порта на мастер машината за ansible.
Сега настройваме ansible
Тъй като целта ни е да автоматизираме всичко, което е възможно. В файла /etc/ansible/ansible.cfg ще разкоментираме реда host_key_checking = False, за да не иска ansible потвърждение от нови машини.
След това, е необходимо автоматично да генерираме инвентарен файл за ansible, от който той ще взима ip адресите на машините, на които трябва да се прави git pull.
Генерираме този файл с помощта на API на Hetzner, можете да вземете списък с хостове от вашата AWS, Azure, база данни (вие имате API за извеждане на вашите активни машини, нали?).
За Ansible структурата на инвентарния файл е много важна, нейният вид трябва да бъде следният:
[група]
ip-адрес
ip-адрес
[група2]
ip-адрес
ip-адресЗа генериране на такъв файл ще направим простичък скрипт (да го наречем 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Сега е време да проверим дали ansible работи и комуникира с получаването на ip адреси:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group
В изхода трябва да получим хостнеймове на машините, на които е изпълнена командата.
Няколко думи за синтаксиса:
- /etc/ansible/./vm_list — генерируем список машин
- -i — абсолютен път до инвентарния файл
- -m — казваме на ansible да използва модула shell
- -a — аргумент. Тук може да впишете всяка команда
- group — името на вашия клъстер. Ако искате да го направите на всички клъстери, сменете group на all
Продължаваме — ще опитаме да направим git pull на нашите виртуални машини:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group Ако в изхода видим already up to date или изтегляне от репозитория, значи всичко работи.
Сега това, за което всичко беше замислено
Ще научим нашия скрипт да се изпълнява автоматично при комит в мастер клон в gitlab
Първо ще направим нашия скрипт по-добър и ще го сложим в изпълняем файл (да го наречем exec_pull) —
#!/bin/bash
/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@" Отиваме в нашия gitlab и в проекта създаваме файл .gitlab-ci.yml
Слагаме вътре следното:
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 Всичко е готово. Сега —
- правим комит
- надяваме се всичко да работи
При прехвърляне на .yml в други проекти е достатъчно само да смените името на услугата за рестарт и името на клъстера, на който ще се изпълняват командите ansible.
Източник: habr.com
