
Boa tarde
Temos vários clusters em nuvem com um grande número de máquinas virtuais em cada um. Tudo isso está hospedado na Hetzner. Em cada cluster, temos uma máquina master, da qual é feito um snapshot e distribuído automaticamente para todas as VMs dentro do cluster.
Esse esquema não nos permite usar os gitlab-runners adequadamente, pois surgem muitos problemas quando há vários runners registrados iguais, o que nos levou a encontrar uma solução alternativa e a escrever este artigo/manual.
Provavelmente, isso não é a melhor prática, mas essa solução pareceu a mais conveniente e simples.
Peço que vejam o tutorial abaixo.
Pacotes necessários na máquina master:
- python
- git
- arquivo com chaves ssh
O princípio geral de implementação do git pull automático em todas as VMs é que precisamos de uma máquina na qual o Ansible será instalado. Dessa máquina, o ansible enviará comandos git pull e reiniciará o serviço que foi atualizado. Criamos para esses fins uma VM separada fora dos clusters e a configuramos:
- python
- ansible
- gitlab-runner
Sobre questões organizacionais — é necessário registrar o gitlab-runner, criar ssh-keygen, e enviar a chave pública ssh desta máquina para .ssh/authorized_keys na máquina master, abrir a porta 22 na máquina master para o ansible.
Agora vamos configurar o ansible
Como nosso objetivo é automatizar tudo o que for possível. No arquivo /etc/ansible/ansible.cfg iremos descomentar a linha host_key_checking = False, para que o ansible não solicite confirmação de novas máquinas.
Em seguida, é necessário gerar automaticamente um arquivo de inventário para o ansible, de onde ele irá obter os IPs das máquinas nas quais precisamos fazer o git pull.
Geramos esse arquivo usando a API da Hetzner, você pode pegar a lista de hosts da sua AWS, Azure, banco de dados (você deve ter alguma API para listar suas máquinas em execução, certo?).
Para o Ansible, a estrutura do arquivo de inventário é muito importante, e deve ser assim:
[grupo]
ip-endereço
ip-endereço
[grupo2]
ip-endereço
ip-endereçoPara gerar esse arquivo, vamos fazer um script simples (vamos chamá-lo de 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É hora de verificar se o ansible funciona e se comunica com a obtenção de endereços IP:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group
Na saída, devemos obter os nomes dos hosts das máquinas onde o comando foi executado.
Algumas palavras sobre a sintaxe:
- /etc/ansible/./vm_list — генерируем список машин
- -i — caminho absoluto para o arquivo de inventário
- -m — dizemos ao ansible para usar o módulo shell
- -a — argumento. Aqui você pode inserir qualquer comando.
- group — nome do seu cluster. Se precisar fazer em todos os clusters, troque group por all.
Vamos seguir em frente – vamos tentar fazer git pull nos nossos. máquinas virtuais:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group Se no output vimos already up to date ou a extração do repositório, significa que tudo está funcionando.
Agora vamos ao que realmente importa.
Vamos ensinar nosso script a ser executado automaticamente ao fazer commit na branch master no gitlab.
Primeiro, vamos deixar nosso script mais bonito e colocá-lo em um arquivo executável (vamos chamá-lo de exec_pull) —
#!/bin/bash
/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@" Vamos para nosso gitlab e dentro do projeto, criamos um arquivo. .gitlab-ci.yml
Inserimos o seguinte:
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 Está tudo pronto. Agora —
- faremos o commit.
- esperamos que tudo funcione.
Ao transferir .yml para outros projetos, basta mudar o nome do serviço para reiniciar e o nome do cluster onde os comandos ansible serão executados.
Fonte: habr.com
