Desde una “startup” hasta miles de servidores en una docena de centros de datos. Cómo perseguimos el crecimiento de la infraestructura de Linux

Si su infraestructura de TI crece demasiado rápido, tarde o temprano se enfrentará a una elección: aumentar linealmente los recursos humanos para respaldarla o iniciar la automatización. Hasta algún momento vivimos en el primer paradigma, y ​​luego comenzó el largo camino hacia la infraestructura como código.

Desde una “startup” hasta miles de servidores en una docena de centros de datos. Cómo perseguimos el crecimiento de la infraestructura de Linux

Por supuesto, NSPK no es una startup, pero esa atmósfera reinó en la empresa en los primeros años de su existencia, y fueron años muy interesantes. Mi nombre es Korniakov Dmitri, He estado brindando soporte a la infraestructura Linux con requisitos de alta disponibilidad durante más de 10 años. Se unió al equipo de NSPK en enero de 2016 y, desafortunadamente, no vio el comienzo de la existencia de la empresa, pero llegó en una etapa de grandes cambios.

En general, podemos decir que nuestro equipo suministra 2 productos para la empresa. El primero es la infraestructura. El correo debería funcionar, el DNS debería funcionar y los controladores de dominio deberían permitirle acceder a servidores que no deberían fallar. ¡El panorama de TI de la empresa es enorme! Estos son sistemas comerciales y de misión crítica, los requisitos de disponibilidad para algunos son 99,999. El segundo producto son los propios servidores, físicos y virtuales. Los existentes deben ser monitoreados y los nuevos deben entregarse periódicamente a clientes de muchos departamentos. En este artículo quiero centrarme en cómo desarrollamos la infraestructura responsable del ciclo de vida del servidor.

A partir de un viaje

Al comienzo de nuestro viaje, nuestra pila de tecnología se veía así:
SO CentOS 7
Controladores de dominio FreeIPA
Automatización: Ansible (+Torre), Cobbler

Todo esto estaba ubicado en 3 dominios, repartidos en varios centros de datos. En un centro de datos hay sistemas de oficina y sitios de prueba, en el resto está PROD.

La creación de servidores en un momento se veía así:

Desde una “startup” hasta miles de servidores en una docena de centros de datos. Cómo perseguimos el crecimiento de la infraestructura de Linux

En la plantilla de VM, CentOS es mínimo y el mínimo requerido es como el /etc/resolv.conf correcto, el resto viene a través de Ansible.

CMDB-Excel.

Si el servidor es físico, entonces, en lugar de copiar la máquina virtual, el sistema operativo se instaló usando Cobbler: las direcciones MAC del servidor de destino se agregan a la configuración de Cobbler, el servidor recibe una dirección IP a través de DHCP y luego el sistema operativo está agregado.

Al principio incluso intentamos hacer algún tipo de gestión de configuración en Cobbler. Pero con el tiempo, esto empezó a traer problemas con la portabilidad de las configuraciones tanto a otros centros de datos como al código Ansible para preparar VM.

En ese momento, muchos de nosotros percibimos a Ansible como una extensión conveniente de Bash y no escatimamos en diseños usando shell y sed. En general, Bashsible. En última instancia, esto llevó al hecho de que si el libro de jugadas por alguna razón no funcionaba en el servidor, era más fácil eliminar el servidor, arreglar el libro de jugadas y ejecutarlo nuevamente. Básicamente, no había versiones de scripts ni portabilidad de configuraciones.

Por ejemplo, queríamos cambiar algunas configuraciones en todos los servidores:

  1. Cambiamos la configuración en los servidores existentes en el segmento lógico/centro de datos. A veces no en un día: los requisitos de accesibilidad y la ley de los grandes números no permiten aplicar todos los cambios a la vez. Y algunos cambios son potencialmente destructivos y requieren reiniciar algo, desde los servicios hasta el propio sistema operativo.
  2. Arreglarlo en Ansible
  3. Lo arreglamos en Cobbler
  4. Repita N veces para cada segmento lógico/centro de datos

Para que todos los cambios se realicen sin problemas, fue necesario tener en cuenta muchos factores y los cambios ocurren constantemente.

  • Refactorización de código ansible, archivos de configuración
  • Cambiar las mejores prácticas internas
  • Cambios basados ​​en los resultados del análisis de incidentes/accidentes
  • Cambiando los estándares de seguridad, tanto internos como externos. Por ejemplo, PCI DSS se actualiza con nuevos requisitos cada año.

Crecimiento de la infraestructura y el comienzo del viaje.

Creció el número de servidores/dominios lógicos/centros de datos, y con ellos el número de errores en las configuraciones. En algún momento, llegamos a tres direcciones en las que es necesario desarrollar la gestión de la configuración:

  1. Automatización. Se debe evitar en la medida de lo posible el error humano en operaciones repetitivas.
  2. Repetibilidad. Es mucho más fácil gestionar la infraestructura cuando es predecible. La configuración de servidores y herramientas para su preparación debe ser la misma en todas partes. Esto también es importante para los equipos de productos: después de la prueba, se debe garantizar que la aplicación terminará en un entorno de producción configurado de manera similar al entorno de prueba.
  3. Simplicidad y transparencia a la hora de realizar cambios en la gestión de la configuración.

Queda por agregar un par de herramientas.

Elegimos GitLab CE como nuestro repositorio de código, sobre todo por sus módulos CI/CD integrados.

Bóveda de los secretos - Hashicorp Vault, incl. para la gran API.

Prueba de configuraciones y roles ansibles: Molecule+Testinfra. Las pruebas son mucho más rápidas si se conecta a un mitógeno ansible. Al mismo tiempo, comenzamos a escribir nuestra propia CMDB y nuestro orquestador para la implementación automática (en la imagen de arriba de Cobbler), pero esta es una historia completamente diferente, que mi colega y principal desarrollador de estos sistemas contará en el futuro.

Nuestra eleccion:

Molécula + Infraestructura de prueba
Ansible + Torre + AWX
Mundo de Servidores + DITNET (Desarrollo propio)
Zapatero
Corredor Gitlab + GitLab
Bóveda de Hashicorp

Desde una “startup” hasta miles de servidores en una docena de centros de datos. Cómo perseguimos el crecimiento de la infraestructura de Linux

Por cierto, sobre roles ansibles. Al principio solo había uno, pero después de varias refactorizaciones quedaron 17. Recomiendo encarecidamente dividir el monolito en roles idempotentes, que luego se pueden ejecutar por separado; además, se pueden agregar etiquetas. Dividimos los roles por funcionalidad: red, registro, paquetes, hardware, molécula, etc. En general, seguimos la estrategia siguiente. No insisto en que ésta sea la única verdad, pero funcionó para nosotros.

  • ¡Copiar servidores de la "imagen dorada" es malo!La principal desventaja es que no se sabe exactamente en qué estado se encuentran las imágenes ahora y que todos los cambios se aplicarán a todas las imágenes en todas las granjas de virtualización.
  • Utilice los archivos de configuración predeterminados al mínimo y acuerde con otros departamentos que usted es responsable de los archivos principales del sistema., Por ejemplo:
    1. Deje /etc/sysctl.conf vacío, la configuración solo debe estar en /etc/sysctl.d/. Su valor predeterminado en un archivo, personalizado para la aplicación en otro.
    2. Utilice archivos de anulación para editar unidades systemd.
  • Modele todas las configuraciones e inclúyalas por completo; si es posible, no sed ni sus análogos en los libros de jugadas.
  • Refactorizando el código del sistema de gestión de configuración:
    1. Divida las tareas en entidades lógicas y reescriba el monolito en roles
    2. ¡Usa pelusas! Ansible-lint, yaml-lint, etc.
    3. ¡Cambia tu enfoque! No se puede criticar. Es necesario describir el estado del sistema.
  • Para todos los roles de Ansible, debe escribir pruebas en molécula y generar informes una vez al día.
  • En nuestro caso, tras preparar las pruebas (de las cuales hay más de 100), se encontraron alrededor de 70000 errores. Fueron necesarios varios meses para solucionarlo.Desde una “startup” hasta miles de servidores en una docena de centros de datos. Cómo perseguimos el crecimiento de la infraestructura de Linux

Nuestra implementación

Entonces, los roles ansibles estaban listos, modelados y verificados por linters. E incluso se crían idiotas en todas partes. Pero la cuestión de la entrega fiable de código a diferentes segmentos seguía abierta. Decidimos sincronizar con scripts. Tiene este aspecto:

Desde una “startup” hasta miles de servidores en una docena de centros de datos. Cómo perseguimos el crecimiento de la infraestructura de Linux

Una vez que llega el cambio, se lanza CI, se crea un servidor de prueba, se implementan roles y la molécula los prueba. Si todo está bien, el código pasa a la rama prod. Pero no aplicamos código nuevo a los servidores existentes en la máquina. Se trata de una especie de tope necesario para la alta disponibilidad de nuestros sistemas. Y cuando la infraestructura se vuelve enorme, entra en juego la ley de los grandes números: incluso si uno está seguro de que el cambio es inofensivo, puede tener consecuencias nefastas.

También hay muchas opciones para crear servidores. Terminamos eligiendo scripts Python personalizados. Y para CI ansible:

- name: create1.yml - Create a VM from a template
  vmware_guest:
    hostname: "{{datacenter}}".domain.ru
    username: "{{ username_vc }}"
    password: "{{ password_vc }}"
    validate_certs: no
    cluster: "{{cluster}}"
    datacenter: "{{datacenter}}"
    name: "{{ name }}"
    state: poweredon
    folder: "/{{folder}}"
    template: "{{template}}"
    customization:
      hostname: "{{ name }}"
      domain: domain.ru
      dns_servers:
        - "{{ ipa1_dns }}"
        - "{{ ipa2_dns }}"
    networks:
      - name: "{{ network }}"
        type: static
        ip: "{{ip}}"
        netmask: "{{netmask}}"
        gateway: "{{gateway}}"
        wake_on_lan: True
        start_connected: True
        allow_guest_control: True
    wait_for_ip_address: yes
    disk:
      - size_gb: 1
        type: thin
        datastore: "{{datastore}}"
      - size_gb: 20
        type: thin
        datastore: "{{datastore}}"

A esto hemos llegado, el sistema continúa viviendo y desarrollándose.

  • 17 roles de Ansible para configurar el servidor. Cada uno de los roles está diseñado para resolver una tarea lógica separada (registro, auditoría, autorización de usuarios, monitoreo, etc.).
  • Prueba de roles. Molécula + TestInfra.
  • Desarrollo propio: CMDB + Orchestrator.
  • El tiempo de creación del servidor es de ~30 minutos, está automatizado y prácticamente independiente de la cola de tareas.
  • El mismo estado/nombramiento de la infraestructura en todos los segmentos: guías, repositorios, elementos de virtualización.
  • Comprobación diaria del estado del servidor con generación de informes sobre discrepancias con el estándar.

Espero que mi historia sea de utilidad para quienes se encuentran al comienzo de su viaje. ¿Qué pila de automatización utilizas?

Fuente: habr.com