Добрага дня
У нас ёсць некалькі хмарных кластараў з вялікай колькасцю віртуальных машын у кожным. Уся гэтая справа ў нас хосціцца ў Hetzner'e. У кожным кластары ў нас ёсць па адной майстар-машыне, з яе робіцца снэпшот і аўтаматычна разносіцца па ўсіх віртуалках ўнутры кластара.
Гэтая схема не дазваляе нам нармальна выкарыстоўваць gitlab-runner'ы, бо ўзнікае вельмі шмат праблем пры з'яўленні мноства аднолькавых зарэгістраваных раннераў, што і заахвоціла да знаходжання абыходнага шляху і да напісання гэтага артыкула/мануала.
Верагодна, гэта не best practice, але гэтае рашэнне падалося максімальна зручным і простым.
За тутарыялам прашу пад кат.
Неабходныя пакеты на майстар-машыне:
- пітон
- мярзотнік
- файл з ssh ключамі
Агульны прынцып рэалізацыі аўтаматычнага gut pull'a на ўсіх віртуалках складаецца ў тым, што неабходна машына, на якой будзе ўсталяваны Ansible. З гэтай машыны ansible будзе адпраўляць каманды git pull і рэстарт сэрвісу, які заапдзейціўся. Мы стварылі для гэтых мэт гатэльную віртуальную машыну па-за кластарамі, паставілі на яе:
- пітон
- адказны
- 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