Доброго дня
У нас є кілька хмарних кластерів з великою кількістю віртуальних машин у кожному. Вся ця справа у нас хоститься у Hetzner'e. У кожному кластері у нас є по одній майстер-машині, з неї робиться снепшот і автоматично розноситься по всіх віртуалках усередині кластера.
Ця схема не дозволяє нам нормально використовувати gitlab-runner'и, тому що виникає дуже багато проблем при появі безлічі однакових зареєстрованих раннерів, що спонукало до знаходження обхідного шляху і до написання цієї статті/мануалу.
Ймовірно, це не best practice, але це рішення здалося максимально зручним та простим.
За туторіалом прошу під кат.
Необхідні пакети на майстер-машині:
- пітон
- мерзотник
- файл із ssh ключами
Загальний принцип реалізації автоматичного gut pull'a на всіх віртуалках полягає в тому, що потрібна машина, на якій буде встановлено Ansible. З цієї машини ansible буде відправляти команди git pull і ресторту сервісу, який заапдейтівся. Ми створили для цих цілей готельну віртуальну машину поза кластерами, поставили на неї:
- пітон
- 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'a, ви можете брати список хостів з вашої AWS, Asure, БД (у вас десь є 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 - говоримо ансиблу використовувати модуль 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'e
Спочатку зробимо наш скрипт красивішим і засунемо його у виконуваний файл (назвемо його 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