====== Servidores y automatizaciones ====== Hoy he intentado ordenar mis ideas. Y tengo que reconocer que no es fácil. Cuando entra en juego el tema de servidores, máquinas físicas, servicios, configuraciones y //downtimes// las ideas fluyen entre tecnologías, siglas y palabras que se antojan difíciles de encajar en el mismo puzzle. Por eso - y después de varios días jugando con //Docker// - he decidido escribir unas notas intentando comprender la situación actual - de crisis de identidad - por la que atravieso. He intentado ordenar todo este proceso en 5 grupos o capas principalmente: - El host (o máquina física) - Instalación inicial de servicios (configuración invariable) - Configuración variable - Los datos - Monitorización y copias de seguridad Nota: En todo momento se intenta plantear la mejor solución contando con la menor inversión posible en elementos físicos, no pretendo alta disponibilidad, ni trabajar con aws ni cualquier otro tipo de soluciones caras, el target son los servidores de gama baja/media de OVH. ===== El host ===== Se trata de la ''parte física'' (vamos a llamarlo así), obvio que es la capa sobre la que se sostienen el resto de servicios y configuraciones y, por ende, una de las más preocupantes debido a los posibles fallos de hardware. Si el host falla tenemos un problema. * Solución: comprar otra máquina. * Otras soluciones: virtualización, openvz, docker, lxc * Automatizable: No, en primera instancia, siempre se puede jugar con el API de OVH, etc... Últimamente he estado probando ligeramente tanto openvz (a través de la distribución proxmox que instala ovh) como docker y me han gustado como solución "enjaulada" a ciertos servicios o grupos de servicios, sin embargo si el hardware falla, en openvz seguimos teniendo un problema mayor y en docker el cluster de hosts (docker-swarm) todavía está verde y no es capaz de reubicar los contenedores de un host a otro. Aunque el futuro es prometedor, de momento es sólo eso, futuro. ===== Instalación inicial de servicios ===== Un host normalmente lleva unos servicios asociados, estos servicios requieren de ciertas configuraciones para que se comporten a gusto del usuario/administrador, una vez funcionando las configuraciones deberían ser invariables. * Solución: Actualmente Fabric + Cuisine * Otras soluciones: Ansible, Puppet, Chef, Dockerfiles * Automatizable: al 100% Estoy contento con el repositorio de scripts Fabric que manejo actualmente, conozco el código, lo adapto a las necesidades que tengo y funciona perfectamente porque es el que he utilizado para configurar el 80% de los servidores que administro. He probado varias veces Ansible y no le he acabado de pillar el punto. Por otro lado los Dockerfiles son una buena solución, pero sólo para docker. ===== Configuración variable ===== Existen otro tipo de configuraciones - dependientes de los servicios - que a diferencia de las anteriores son variables (cuentas de correo, contraseñas, virtualhosts...) y pueden cambiar mucho a lo largo de la vida útil de una máquina. * Solución: Actualmente ninguna * Otras soluciones: Repositorios de configuraciones * Automatizable: al 100% Esta es la parte más floja, cualquiera de los otros puntos están más o menos cubiertos, sin embargo no tengo ninguna solución (a excepción de las copias de seguridad) que me permita restaurar las configuraciones rápidamente para que, en caso de fallo, tener la máquina replicada cuanto antes. * **Solución1**: La solución que pretendo implantar pasa por los repositorios de configuraciones. Idealmente serían dos repositorios, uno general que podría ser común a todos los servidores y otro específico de cada servidor: * serverconf-general * ssh, .profile, tmux.conf, munin-node, scripts-comunes * serverconf-fqdn * apache, nginx, mysql, postgresql... Se complica la idea de tener archivos de configuración variables en repositorios. Los sistemas de control de versiones y las gestiones de archivos de configuración son tareas lo suficientemente distintas para que puedan cuajar, hay bastantes inconsistencias: cambios de versiones de software, permisos de ficheros, organización estructural de los repositorios... y pasar por enlaces simbólicos no son la solución adecuada. Por lo tanto sigo buscando solución para este paso. * **Solución2**: ''etckeeper''. No aplicable porque crea repo de todo /etc con configuraciones propias de la máquina que no se deberían "clonar" (fstab, net ifaces...) * **Solución3**: Dos repos ''/etc'' y ''/root'' con default policy de ''ignore *'' e ir metiendo poco a poco las configuraciones variables correspondientes. Las invariables deberían ir provisionadas desde la herramienta correspondiente (Fabric, Ansible...). ===== Datos ===== Los datos son la otra parte crucial de la película, por eso me gusta tratarlos en un punto separado. Los datos pueden ser desde una página web o una base de datos hasta el Maildir de una cuenta de correo o las gráficas recogidas por las herramientas de monitorización. ===== Monitorización y copias de seguridad ===== Y el último eslabón de esta cadena son los servicios de monitorización y copias de seguridad de las máquinas y del resto de servicios que están funcionando. * Solución: Munin + Monit + rsync * Automatizable: al 100% No hay mucho que decir aquí, se plantea tanto la monitorización como las copias de seguridad de forma centralizada en un servidor independiente con herramientas que incluyen copias incrementales y alertas en forma de correo electrónico. ===== Flujo en caso de fallo (repos) ===== El flujo, en caso de fallo de hardware, sería el siguiente: * Se compra una máquina nueva (manualmente, ovh -> lento) * Se instalan y configuran los servicios iniciales (fabric -> rápido) * Se restauran los repositorios de configuraciones general y propio del servidor que ha fallado (no solución actualmente) * Se restauran los datos (solamente datos) de la última copia de seguridad (rsync -> depende del volúmen de datos) ==== Compra de máquina ==== Imagino que se podría automatizar de alguna forma jugando con el sistema de monitorización y el API de OVH, pero no es algo que me preocupe demasiado en este momento. ==== Instalación servicios iniciales ==== Tirando de los scripts de Fabric, tanto en caso de servidor nuevo como réplica, haríamos lo siguiente: $ fab add Host? mi.hostname FQDN? (mta only) nsloquesea.ip-XX-XX-XX.eu IP? XX.XX.XX.XX User? [root] Passwd? XXXX Shell [bash]? [bash] SSH Port [22]? [22] Create repo (yes|[no]) [no]? $ fab s:mi.hostname groups.basic_lamp:midominio.com $ fab s:mi.hostname phpmyadmin.deploy $ fab s:mi.hostname apache.add_vhost:midominio2.com,media El comando anterior debería crear también un repositorio ''serverconf-mi.hostname'' donde se irán guardando las configuraciones variables. ==== Restauramos configuraciones variables ==== Una vez agregado e instalado el nuevo servidor, al tratarse de un servidor réplica, le decimos que queremos importar las configuraciones de ''mi.otrohostname'' el script debería ser capaz de dejar las configuraciones variables exactamente igual. $ fab s:mi.otrohostname host.import_from_server:mi.hostname ==== Restauramos los datos ==== Tirando de la última copia de seguridad, restauramos los datos: $ rsync -e ssh --progress --delete -lprtvvzog root@backup:/home/backup/mi.otrohostname/home/www /home/www Propuesta (todavía por pulir): $ fab s:mi.otrohostname backup.restore:mi.backup,www,mysql ===== Flujo en caso de servidor existente sin repo ===== En caso de tener un servidor existente ya configurado y sin tener todavía repositorio de configuraciones genéricas ni variables podemos hacerlo de la siguiente forma: $ fab add # como alternativa podemos crear la configuración directamente $ fab s:me host.create_repo <- crea repo nuevo $ fab s:me host.import_from_server <- lo clona por primera vez (nuevo o de otro servidor) $ fab s:me host.pull_config <- actualiza Ahora toca trabajar agregando las configuraciones específicas y genéricas de ese servidor, así como los scripts de inicio ''gen/start.sh'' y ''cus/start.sh'' que se ejecutarán para hacer los correspondientes enlaces simbólicos y demás instalaciones necesarias no-genéricas.