
Dobrý den
Máme několik cloudových clusterů s velkým počtem virtuálních strojů v každém. Všechny tyto služby hostujeme v Hetzner. V každém clustru máme jednu hlavní stroj, ze které se vytváří snímek a automaticky se rozšiřuje na všechny virtuální stroje v rámci clusteru.
Tato schéma nám neumožňuje normálně používat gitlab-runner, protože se objevuje mnoho problémů s opakovaně registrovanými runnery, což nás přimělo hledat alternativní řešení a napsat tento článek / manuál.
Pravděpodobně to není nejlepší praxe, ale tato řešení se zdá být maximálně pohodlné a jednoduché.
Pro postup se prosím podívejte pod kat.
Potřebné balíčky na hlavním stroji:
- python
- git
- soubor se ssh klíči
Obecný princip implementace automatického git pull na všech virtuálních strojích spočívá v tom, že potřebujeme stroj, na kterém bude nainstalován Ansible. Z tohoto stroje bude Ansible odesílat příkazy git pull a restartovat aktualizovanou službu. Pro tyto účely jsme vytvořili oddělený virtuální stroj mimo clustery a nainstalovali jsme na něj:
- python
- ansible
- gitlab-runner
Z organizačních záležitostí — je třeba registrovat gitlab-runner, provést ssh-keygen a vložit veřejný ssh klíč tohoto stroje do .ssh/authorized_keys na hlavním stroji, otevřít port 22 na hlavním stroji pro ansible.
Nyní nastavíme Ansible
Naším cílem je automatizovat vše, co je možné. V souboru /etc/ansible/ansible.cfg odkomentujeme řádek host_key_checking = False, aby Ansible nevyžadoval potvrzení nových strojů.
Dále je nutné automaticky generovat inventární soubor pro Ansible, odkud si bude brát IP adresy strojů, na kterých je třeba provést git pull.
Tento soubor generujeme pomocí API Hetzner, vy můžete získat seznam hostitelů z vašeho AWS, Azure, databáze (určitě máte API pro zobrazení vašich spuštěných strojů, že?).
Pro Ansible je velmi důležitá struktura inventárního souboru, jeho podoba by měla být následující:
[skupina]
ip-adresa
ip-adresa
[skupina2]
ip-adresa
ip-adresaPro generování takového souboru uděláme jednoduchý skript (nazveme ho 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_ipJe čas zkontrolovat, zda Ansible funguje a spolupracuje se získáváním IP adres:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group
Ve výstupu bychom měli získat hostname strojů, na kterých byl příkaz proveden.
Pár slov o syntaxi:
- /etc/ansible/./vm_list — генерируем список машин
- -i — absolutní cesta k inventárnímu souboru
- -m — říkáme Ansible, aby použil modul shell
- -a — argument. Here you can enter any command.
- group — the name of your cluster. If you need to do it on all clusters, change group to all.
Moving on — let's try to do a git pull on our. virtual machines:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group If the output shows already up to date or a repository dump, everything is working.
Now, for what this was all designed for.
We'll teach our script to run automatically upon committing to the master branch in GitLab.
First, we'll make our script prettier and put it in an executable file (let's call it exec_pull) —
#!/bin/bash
/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@" Let's go to our GitLab and create a file in the project. .gitlab-ci.yml
We place the following inside:
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 Everything is ready. Now —
- we make a commit.
- let's hope that everything works.
When transferring .yml to other projects, it's enough to just change the service name for restart and the name of the cluster on which the ansible commands will be executed.
Zdroj: habr.com
