Bo día
Temos varios clústeres de nube cunha gran cantidade de máquinas virtuais en cada un. Organizamos todo este negocio en Hetzner. En cada clúster temos unha máquina mestra, tómase unha instantánea dela e distribúese automaticamente a todas as máquinas virtuais do clúster.
Este esquema non nos permite usar gitlab-runners normalmente, xa que xorden moitos problemas cando aparecen moitos corredores idénticos rexistrados, o que nos levou a buscar unha solución e escribir este artigo/manual.
Probablemente non sexa a mellor práctica, pero esta solución parecía o máis cómoda e sinxela posible.
Para o tutorial, consulte cat.
Paquetes necesarios na máquina mestra:
- python
- ir
- ficheiro con chaves ssh
O principio xeral de implementación do gut pull automático en todas as máquinas virtuais é que necesitas unha máquina na que se instalará Ansible. Desde esta máquina, ansible enviará comandos git pull e reiniciará o servizo que se actualizou. Para estes efectos, creamos unha máquina virtual separada fóra dos clústeres e instalamos nela:
- python
- ansible
- gitlab-runner
Por cuestións organizativas: cómpre rexistrar gitlab-runner, facer ssh-keygen, cargar a clave ssh pública desta máquina para .ssh/authorized_keys
na máquina mestra, abra o porto 22 para ansible na máquina mestra.
Agora imos configurar ansible
Xa que o noso obxectivo é automatizar todo o posible. En arquivo /etc/ansible/ansible.cfg
descomentaremos a liña host_key_checking = False
para que ansible non pide confirmación de novas máquinas.
A continuación, cómpre xerar automaticamente un ficheiro de inventario para ansible, de onde tomará a ip das máquinas nas que precisa facer git pull.
Xeramos este ficheiro usando a API de Hetzner, podes sacar a lista de hosts da túa base de datos AWS, Asure (tes unha API nalgún lugar para mostrar as túas máquinas en execución, non?).
A estrutura do ficheiro de inventario é moi importante para Ansible; debería verse así:
[группа]
ip-адрес
ip-адрес
[группа2]
ip-адрес
ip-адрес
Para xerar un ficheiro deste tipo, faremos un script sinxelo (chamémoslle 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 comprobar que Ansible funciona e é amigable coa recepción de enderezos IP:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group
A saída debe conter os nomes de host das máquinas nas que se executou o comando.
Algunhas palabras sobre sintaxe:
- /etc/ansible/./vm_list - xera unha lista de máquinas
- -i - ruta absoluta ao ficheiro de inventario
- -m - indica a ansible que use o módulo shell
- -a é o argumento. Calquera comando pódese introducir aquí
- group — o nome do seu clúster. Se precisas facelo en todos os clústeres, cambia o grupo a todos
Imos máis aló: intentemos facer git pull nas nosas máquinas virtuais:
/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group
Se na saída vemos xa actualizado ou descargando desde o repositorio, entón todo funciona.
Agora para iso estaba destinado todo
Ensinemos ao noso script a executarse automaticamente cando nos comprometemos coa rama mestra en gitlab
Primeiro, imos facer o noso script máis bonito e poñelo nun ficheiro executable (chamémoslle exec_pull) -
#!/bin/bash
/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@"
Imos ao noso gitlab e creemos un ficheiro no proxecto .gitlab-ci.yml
Poñemos o seguinte dentro:
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
Todo está listo. Agora -
- facer un compromiso
- Alégrome de que todo funcione
Ao transferir .yml a outros proxectos, só precisa cambiar o nome do servizo para reiniciar e o nome do clúster no que se executarán os comandos ansibles.
Fonte: www.habr.com