Automatización de la configuración

Para automatizar el aprovisionamiento, la configuración y el mantenimiento de nuestra plataforma de servidores, utilizamos Ansible (si no lo conocés, empezá acá). Estamos trabajando en esta automatización en esta tarea: #5903 y las tareas relacionadas.

Introducción a nuestro flujo de trabajo

Trabajamos paralelamente, en forma distribuida pero coordinada, mediante Git (Es útil leer esta introducción a Git: Bases de git para trabajar juntos).

Para el desarrollo de código, en este proyecto:

Conformando nuestro entorno de trabajo personal

En el README del proyecto está (también) descrito como configurar un entorno de trabajo.  (OjO que no haga doble empleo con esta página...).

Nota previa:
Generá tu propio entorno en tu cuenta en la máquina que quieras. Cuidado: ¡info sensible! ten en cuenta que eres responsable de estos datos, por lo cual debes proteger el acceso a esa máquina y a tu cuenta. Para el acceso remoto SSH, uso obligatorio de claves ssh pública/privada, con passphrase robusta.
En breve, se recomendará tener tal espacio de trabajo en una cuenta personal (con acceso SSH más passphrase) en la consola de administración ta.interior.edu.uy.
A mediano plazo, mejoraremos la separación de los derechos, accesos y compartimentación de los espacios de producción, de desarrollo, pruebas e integración. Contra servidores en producción sólo se podrá actuar desde cierto contexto (ej: sólo desde ta.interior), con AVISO CLARO, eventualmente con autenticación específica.

Instalá en tu máquina Git y Ansible. Este último debe ser de versión reciente, al menos superior o igual a 2.7, se logra fácilmente con los backports de Debian o el PPA oportuno de Ubuntu. Adicionalmente será necesario instalar las librerías Python de las que depende nuestro proyecto, actualmente son: jmespath y netaddr. Pueden instalarse fácilmente mediante el gestor Python pip:

pip install netaddr
pip install jmespath

Para acceder y descargar el proyecto config, debes tener una cuenta en nuestra instancia del gestor de desarrollo GitLab y ser miembro del mismo (la inscripción está abierta para mails en .uy).

  • Comenzá creando una carpeta de trabajo limpia, por ejemplo 'interior/'. Ubícate dentro de ella en una terminal y clona el repositorio del proyecto config:
    usuario@pc:~/interior$ git clone git@git.interior.edu.uy:adminsys/config.git
    
    Se creará directorio llamado config con el código del proyecto dentro.
  • Luego necesitas recuperar el archivo contrasenha_vault, que puedes encontrar en la consola de administración de la vieja plataforma bourdieu.csic.edu.uy:~/compartido/ansible/ (próximamente también en ta.interior.edu.uy) y ubicarlo dentro de interior/.
    Este archivo contiene la contraseña que descifra todos los archivos de variables protegidos (vaults) de los hosts gestionados con Ansible.
  • Por último necesitarás descargar los roles Ansible de los que config depende. Algunos se encuentran en la galaxia de Ansible y otros se encuentran directamente publicados en nuestro espacio de GitHub. Esta tarea es muy sencilla gracias al archivo requirements.yml ubicado en la raíz del proyecto, que lista todos los roles de los que se depende. Deberás ubicarte en interior/config y ejecutar lo siguiente:
    usuario@pc:~/interior/config$ ansible-galaxy install -r requirements.yml -g
    
    Verás como los roles se descargarán uno a uno. Una vez finalizada la descarga, dentro de interior/ contarás con un nuevo directorio llamado UdelaRInterior, con los roles deseados organizados en subcarpetas.

    Notar que al ejecutar ansible-galaxy con la opción '-g' (o '--keep-scm-meta' por su forma explícita) mantenemos en el directorio de cada role, la metadata del sistema de versionado utilizado. En este caso el directorio oculto '.git':

    UdelaRInterior
    ├── ...
    ├── ...
    └── crear_lxc
        ├── defaults
        ├── .git          <-----
        ├── .gitignore
        ├── handlers
        ├── LICENSE
        ├── meta
        ├── README.md
        ├── tasks
        ├── tests
        └── vars
    

    Mantener estos archivos de nos es de mucha utilidad, ya que permitirá:
    • Contar con los roles que requieren los playbooks para ejecutarse ya descargados, con nombre y ubicación correcta.
    • Trabajar cada role como un repositorio Git convencional. Pudiendo entonces actualizarlo (git pull), realizar aportes (git commit y git push) y navegar entre diferentes versiones del mismo (git checkout).

Completados todos los pasos, tu directorio interior/ debería lucir así:

interior
├── config
│   ├── ansible.cfg
│   ├── arenero
│   ├── config_host.yml
│   ├── configurar_fierros_proxmox.yml
│   ├── configurar_firewall_cluster_proxmox.yml
│   ├── crear_kvm.retry
│   ├── crear_kvm.yml
│   ├── crear_lxc.yml
│   ├── files
│   ├── group_vars
│   ├── hosts_prod
│   ├── hosts_stage
│   ├── host_vars
│   ├── info_servidor.yml
│   ├── README.md
│   ├── requirements.yml
│   ├── roles
│   ├── site.retry
│   └── site.yml
├── contrasenha_vault
└── UdelaRInterior
    ├── alternc
    ├── ...
    ├── ...
    └── crear_lxc

¿Te genera curiosidad saber por qué es necesario respetar esta estructura? Se debe a que en el mismo proyecto config contamos con un archivo de configuración que nos permite automatizar la conformación del entorno. Este archivo es ansible.cfg y luce así:

## Conforme a las ubicaciones propuestas en: 
## https://docs.ansible.com/ansible/latest/intro_configuration.html

[defaults]

## Nuestro inventario
inventory = ./hosts_stage

## Nuestra carpeta con roles publicados en la ansible-galaxy
roles_path = ../UdelaRInterior

## la contraseña de los vault
vault_identity_list = ../contrasenha_vault

Como se aprecia, este archivo nos permite indicar la ubicación de nuestro inventario de hosts de la plataforma, la ubicación de descarga/consumo de roles externos y la contraseña utilizada por defecto para descifrar los vaults (archivos cifrados por contener datos sensibles). Este archivo simplificará mucho la ejecución de órdenes de Ansible siempre que lo hagas desde el directrio en la raíz del proyecto: interior/config/

Es importante notar que manejamos dos archivos de inventario: hosts_stage para hosts de prueba y hosts_prod para los hosts de producción. Cuando ejecutes cualquier acción de Ansible, por defecto estarás utilizando el inventario de pruebas, ya que así se establece en ansible.cfg. Esto tiene implicación en simplificar el uso, pero por sobre todo, evitar que sysadmins distraídos ejecuten playbooks sobre servidores en producción.

Para trabajar sobre servidores en producción, se requerirá estar lo suficientemente concentrado como para a indicar en la orden de ejecución que usaremos otro inventario, agregando -i hosts_prod. Por supuesto, los beneficios de esta característica dependerán de que los archivos de inventario se mantengan actualizados, principalmente quitando o comentando en host_stage las referencias a servidores que se declararon en producción.

Organización de los playbooks en el proyecto config

Los archivos de inventario (hosts_stage y hosts_prod) se escriben en sintaxis YAML y organizan los grupos principales de nuestra infraestructura (OjO: incluye también cosas más allá de la nueva plataforma, en particular CSIC y el CURE. El grupo interior abarca la nueva plataforma en SeCIU).

Procuramos atenernos a las buenas prácticas de Ansible, en particular:
  • "colgamos" todo el código ya algo pulido tras un playbook general site.yml. Es decir que, a priori, si partimos de fierros básicamente instalados accesibles en root via SSH, obtenemos nuestra infraestructura funcional de la nueva plataforma lanzando:
    usuario@pc:~/interior/config$ ansible-playbook --limit interior site.yml
    
  • usamos roles y toda su estructura, tanto como podemos.
  • agrupamos en un rol common todo lo que convenga ejecutar en todos los servidores. Pero procuramos separar los conjuntos coherentes de tareas en archivos y roles incluidos.
  • usamos variables en la carpeta defaults de los roles. Por ejemplo:
    • los parámetros de configuración por omisión de un contenedor LXC están definidos acá. Estas variables puede ser sobre-escritas indicando valores particulares en las host_vars, group_vars u otros lugares que tenga precedencia al default de roles.
  • Usamos tags para alvianar la ejecución de los playbook, en particular:
    • tag adminsys para los accesos de administradores. Por ejemplo, si agregamos la cuenta y claves de un nuevo miembro del equipo (TO DO), se va a agregar automáticamente a todos los hosts que corresponda ejecutamos:
      usuario@pc:~/interior/config$ ansible-playbook --limit interior site.yml --tags=adminsys
      
    • tag descarga, que esta vez se exluye (skip-tags), para evitar GB de descargas. Por ejemplo, para crear los contenedores LXC que falten, sin por eso volver a descargar varios GB de templates para verificar que ya tenemos la última versión, correríamos:
      usuario@pc:~/interior/config$ ansible-playbook site.yml --limit mihost.interior.edu.uy --skip-tags=descarga
      
Además de las buenas prácticas, algunas elecciones que hemos hecho:
  • Nuestra carpeta de trabajo es la carpeta de la copia del proyecto Git. Por ende, solemos correr los playbooks para que tome correctamente la contraseña de los vaults del proyecto:
    usuario@pc:~/interior/config$ ansible-playbook mi_playbook.yml
    
  • El despliegue en los servidores administrados se hace con un usuario unix siempre denominado deploy (miembro del grupo raices, que tiene derechos sudo sin solicitud de contraseña). Se crea y configura en el rol acceso_deploy, que utiliza como insumo las variables globales (group_vars/all) para recuperar las claves de todxs lxs adminsitradores del host y configurarlas en los usuarios deploy y root.
  • En la configuración de la plataforma, es necesario configurar primero los servidores físicos (nodos Proxmox) y luego configurar contenedores, virtuales y otros. Por ende, el playbook site.yml es simplemente una inclusión secuencial de otros playbooks, empezando por el playbook configurar_fierros_proxmox.yml, que asegura la config del los fierros del mismo cluster Debian/Proxmox, en particular de los accesos deploy y adminsys, que serán un requisito a la hora de crear un virtual o un contenedor en su servidor madre.

Playbooks disponibles

Estamos trabajando sobre los playbook para la nueva plataforma acá #6009 y (mas recientemente) acá

Ya tenemos y usamos los playbook siguientes:

  • config/site.yml: incluye secuencialmente:
    • config/configurar_fierros_proxmox.yml: para el nivel de servidores físicos.
    • config/crear_lxc.yml: crea los contenedores definidos en el inventario con sus recursos específico, S.O. y les configura accesos.
    • config/crear_kvm.yml: crea las virtuales definidas en el inventario con sus recursos específicos y firewall Proxmox, sin S.O.
    • config/config_host.yml: aprovisiona a los hosts (sean LXC o KVM) con firewall, configuraciones de seguridad, paquetes, usuarios y servicios.
  • config/configurar_firewall_cluster_proxmox.yml: configura y establece reglas de firewall Proxmox para todo el cluster. Fue independizado de config/site.yml, ya que su incorrecta configuración y ejecución puede afectar la conectividad de varios o todos los hosts de la plataforma.

Procesos de instalación

Tareas para un servidor Proxmox

Hay una parte del proceso que no se puede hacer con Ansible, dado que este trabaja mediante un acceso en SSH, por lo cual tiene que haber previamente instalado un sistema ya accesible en línea.

Instalamos los 3 primeros servidores físicos con un .iso de Proxmox, y a mano (en particular de disco, ya en RAID hardware).

En ocasión de la instalación de un próximo nodo al cluster, convendría retomar esta tarea: #5932, que ya fue un poco explorada.

Una vez que se tienen las máquinas en línea, con acceso root en SSH, podemos hacer las siguientes tareas con Ansible:

  1. configuración de los repos de la UdelaR,
  2. desactivación del repo Proxmox con suscripción y activación del sin suscripción,
  3. instalación del usuario deploy y de los adminsys
  4. puesta en cluster de los Proxmox
  5. instalación de los certificados Let's Encryt

El playbook config/configurar_fierros_proxmox.yml ya hace parte de esto.

Explorar herramientas Ansible, Proxmox y otros

Compartir más

Además del proyecto config, proyecto reservado, que contiene el inventario de servidores y scripts específicos a nuestra plataforma, habíamos empezado un segundo, que pretendía ser abierto retirando la información sensible. Pero al final lo compartido, de acuerdo a la propuesta de la comunidad Ansible, pasó a la galaxy, nuestro espacio en GitHub.

No obstante, quizás que algún día continuemos el proyecto adminsys, armá tu propia nube.