Ansible + auto git pull en un clúster de máquinas virtuales en la nube

Ansible + auto git pull en un clúster de máquinas virtuales en la nube

Buenos días

Contamos con varios clústeres en la nube que albergan numerosas máquinas virtuales en cada uno. Todo esto está alojado en Hetzner. En cada clúster, tenemos una máquina maestra, de la cual se realiza una instantánea y se distribuye automáticamente a todas las virtuales dentro del clúster.

Este esquema no nos permite usar correctamente los gitlab-runners, ya que surgen muchos problemas con la aparición de numerosos runners registrados idénticos, lo que llevó a buscar una solución alternativa y a escribir este artículo/manual.

Probablemente, esto no es lo mejor, pero esta solución nos pareció la más conveniente y sencilla.

Por favor, vean el tutorial a continuación.

Los paquetes necesarios en la máquina maestra:

  • python
  • git
  • archivo con las claves ssh

El principio general para implementar el git pull automático en todas las virtuales es que se necesita una máquina donde se instalará Ansible. Desde esta máquina, Ansible enviará comandos git pull y reiniciará el servicio que fue actualizado. Creamos para estos fines una máquina virtual separada fuera de los clústeres y le instalamos:

  • python
  • ansible
  • gitlab-runner

En cuestiones organizativas, es necesario registrar el gitlab-runner, hacer un ssh-keygen, y colocar la clave ssh pública de esta máquina en .ssh/authorized_keys en la máquina maestra, abrir el puerto 22 en la máquina maestra para Ansible.

Ahora configuremos Ansible

Ya que nuestro objetivo es automatizar todo lo que sea posible. En el archivo /etc/ansible/ansible.cfg descomentamos la línea host_key_checking = False, para que Ansible no pida confirmación para nuevas máquinas.

A continuación, es necesario generar automáticamente un archivo de inventario para Ansible, de donde tomará las IP de las máquinas en las que se debe hacer git pull.

Generamos este archivo utilizando la API de Hetzner, aunque usted puede obtener la lista de hosts de su AWS, Azure, base de datos (¿tiene alguna API para mostrar sus máquinas en funcionamiento, verdad?).

Para Ansible, la estructura del archivo de inventario es muy importante, debe tener el siguiente formato:

[grupo]
ip-dirección
ip-dirección

[grupo2]
ip-dirección
ip-dirección

Para generar un archivo así, hagamos un sencillo script (lo llamaremos 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

Es el momento de verificar que Ansible funciona y se comunica adecuadamente con la obtención de las direcciones IP:

/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'hostname' group

En la salida debemos obtener los nombres de host de las máquinas en las que se ejecutó el comando.
Unas palabras sobre la sintaxis:

  • /etc/ansible/./vm_list — генерируем список машин
  • -i — ruta absoluta al archivo de inventario
  • -m — indicamos a Ansible que utilice el módulo shell
  • -a — argumento. Aquí se puede escribir cualquier comando
  • grupo — el nombre de tu clúster. Si es necesario hacer en todos los clústeres, cambiamos grupo a all

Seguimos adelante — intentemos hacer git pull en nuestros máquinas virtuales:

/etc/ansible/./vm_list && ansible -i /etc/ansible/cloud_ip -m shell -a 'cd /path/to/project && git pull' group 

Si en la salida vemos already up to date o descarga del repositorio, significa que todo funciona.

Ahora lo que se pensó para esto

Enseñaremos a nuestro script a ejecutarse automáticamente al hacer commit en la rama maestra en gitlab

Primero haremos que nuestro script sea más bonito y lo pondremos en un archivo ejecutable (lo llamaremos exec_pull) —

#!/bin/bash

/etc/ansible/./get_vms && ansible -i /etc/ansible/cloud_ip -m shell -a "$@"

Vamos a nuestro gitlab y en el proyecto creamos un archivo .gitlab-ci.yml
Colocamos lo siguiente 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. Ahora —

  • hacemos commit
  • esperamos que todo funcione

Al trasladar .yml a otros proyectos, solo es necesario cambiar el nombre del servicio para reiniciar y el nombre del clúster en el que se ejecutarán los comandos ansible.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster