DevOps

Una introducción

Mikroways

Agenda

  • Presentación
  • Interacción entre infraestructura y desarrollo.
  • Perspectiva de desarrollo.
  • Perspectiva de infraestructura.
  • Puesta en producción.
  • DevOps
  • Flujo de trabajo.
  • Herramientas

Presentación

Sobre Mikroways

  • Brindamos servicios de TI, específicamente relacionados a la infraestructura tecnológica de nuestros clientes.
  • Diseñamos e implementamos soluciones a medida según las necesidades de cada cliente.
  • Damos soporte para solucionar cualquier problemática que surja en el funcionamiento de la infraestructura tecnológica existente.
  • Proveemos capacitación al personal de sistemas, adaptando los cursos a los requerimientos específicos.

Nuestros servicios

  • Devops
  • Docker
  • Monitoreo inteligente
  • Consultoría
  • Computación en la nube
  • Escalabilidad de aplicaciones web
  • Capacitación

Interacción entre IT y Desarrollo

Introducción

  • En la mayoría de las organizaciones ocurre que:
    • Desarrollo e infraestructura son grupos de trabajo disjuntos.
    • Desarrollo es uno de varios clientes de infraestructura.
      • ¿Usuario VIP?
    • Infraestructura atiende cuestiones complejas que son críticas.

¿Diferentes objetivos?

  • Desarrollo debe cumplir con lo que pide el usuario:
    • Permanentes pedidos de cambios y nuevas funcionalidades.
    • ¡Todos los pedidos son urgentes!
  • Infraestructura debe mantener los sistemas estables:
    • Los cambios son enemigos de la estabilidad.
    • El despliegue de cambios es delicado y lleva mucho tiempo.

¿Diferentes objetivos?

  • El objetivo de toda organización es cumplir con su propósito.
    • Puede ser ganar dinero, brindar un servicio público, etc.
    • Todas las áreas de la organización deben trabajar en pos de cumplir ese propósito.

El objetivo entonces de desarrollo y de infraestructura es el mismo, hacer posible que la organización cumpla con su propósito.

Analizaremos la problemática desde

  • La perspectiva de desarrollo.
  • La perspectiva de infraestructura.
  • La puesta en producción: el momento en que desarrollo e infraestructura interactúan.

La perspectiva de desarrollo

Arquitectura de aplicaciones

  • Monolíticas versus servicios o microservicios.
  • Múltiples lenguajes y frameworks.
  • Diferentes sistemas de bases de datos:
    • SQL, NoSQL.
  • Sistemas de colas.
  • Servicios de terceros.

Arquitecturas de aplicaciones

Metodologías Ágiles

  • El manifiesto ágil hace énfasis en los siguientes valores:
    • individuos e interacciones,
    • software funcionando,
    • colaboración con el cliente,
    • respuesta ante el cambio.
  • Desplegar nuevas versiones con mucha frecuencia:
    • Aparecen deployments diarios e incluso varias veces al día.
    • Responder a estos requerimientos requiere una operatoria ágil desde IT.
      • Si esto no sucede se produce un cuello de botella.

Versiones de librerías y lenguajes

  • Es común que los desarrolladores utilicen las versiones más recientes de determinados productos.
  • Algunos lenguajes no permiten, de forma simple, tener en el sistema más de una versión de una misma librería o lenguaje.
  • Esto crea diferencias entre el ambiente de desarrollo y producción.
    • Es esta es la brecha que debemos achicar.

Ambiente de desarrollo

  • Suele darse uno de tres escenarios.
    • No existen ambientes de desarrollo:
      • ¡se trabaja directamente en producción!
    • Ambiente de desarrollo común y compartido:
      • difícil administración,
      • problemas de concurrencia
    • Ambientes independientes de desarrollo:
      • Nuevo integrante debe generar todo el ambiente de cero.
      • Necesidad de sincronizar cambios entre desarrolladores (código, estructura de bases de datos).

Acceso a producción

  • Suele ser necesario acceder a un recurso en producción.
    • Dump de la BD o versión productiva del código (¡SCM!).
    • Datos dinámicos de la aplicación.
      • Archivos subidos o generados durante su uso.
  • A veces, por requerimientos de seguridad o legales, la información debe obtenerse ofuscada.
  • Otras veces, alcanza con un dato antiguo que puede extraerse desde un backup.

Réplica del ambiente productivo

  • Disponer de un ambiente similar al productivo es muy valioso para desarrollo porque permite, entre otras cosas:
    • Verificar problemas sin tocar producción.
    • Probar nuevos releases antes de pasarlos a producción.
    • Asegurarse que el código, que funciona en el ambiente de desarrollo, funcione en el de producción.
      • ¿Y si el ambiente de desarrollo fuera igual al del producción?
    • Que el cliente verifique los cambios solicitados antes de aplicarlos en producción.

Diagnóstico de problemas

  • Comportamiento del software en producción:
    • importancia de poder visualizar los logs:
      • Errores
      • Problemas de seguridad.
      • Otras situaciones anómalas.
    • Monitoreo del software:
      • Aviso en tiempo real cuando se produce una excepción.

Diagnóstico de problemas

  • Profiling de cada middleware de una aplicación: ORM, servicios externos, renderizado, caching, tiempos de respuesta, etc.
  • Generar información estadística para conocer el comportamiento normal de cada aplicación:
    • Desconocer estos datos es manejar con el parabrisas lleno de barro.

La perspectiva de infraestructura

Gestión de servicios

  • Infraestructura gestiona:
    • Hardware
    • Red de la organización y proveedores de servicios.
      • Ruteo, firewalls, switches, VPN.
    • Plataformas de virtualización.
    • Servicios en la nube.
    • Servidores de correo, DNS, sistemas web, LDAP, controladores de dominio, etc.
  • Organizaciones grandes explotan el área en aplicaciones, comunicaciones y seguridad, pero no ocurre siempre.
  • Cuántos más usuarios acceden a los servicios, más complejos se vuelven.

Gestión de servicios

  • Para todos los servicios debe asegurar:
    • Backups
    • Monitoreo
    • Disponibilidad: tolerancia a fallos, HA.
    • Seguridad
    • Integridad
  • ¡Todos los servicios son críticos!
  • La clave del éxito: ser invisibles.

Gestión de servicios

  • El mantenimiento de los servicios también implica:
    • Actualizar las versiones de software.
    • Actualizar los sistemas operativos.
  • Es común que la gestión de cuentas de usuarios siga siendo una tarea más del área de infraestructura.

Atender a todas las cuestiones mencionadas demanda tiempo y esfuerzo que no dejan lugar para la investigación de nuevas tendencias, prácticas ágiles o automatización.

Gestión manual

  • En los grupos de desarrollo, es habitual programar o automatizar cualquier paso repetible, pero no siempre aplica esto mismo en infraestructura.
  • Si se automatizan las tareas repetitivas, se se suele hacer con scripts de shell que utilizan herramientas auxiliares: awk, perl, python, sed, php, bc, etc.
    • Soluciones muy acopladas que no pueden reusarse en todos los casos.

Desarrollo como cliente

  • El área de desarrollo es un cliente más al que se le brinda servicio.
  • Debido a que produce constantemente aplicaciones o cambios en las mismas, la demanda es muy alta.
    • Las metodologías ágiles acentúan mucho más esta situación.
  • Es el cliente más demandante, pero no necesariamente el más prioritario.

Desarrollo como cliente

  • Los servidores son responsabilidad de infraestructura.
    • El acceso a los mismos debería ser exclusivo de esa área.
    • Infraestructura debe seguir atendiendo todas sus obligaciones.
    • Se transforma en un cuello de botella para los despliegues en producción.
  • Desarrollo demanda respuestas.
  • Se buscan soluciones alternativas.

Desarrollo como cliente

  • Acceso a los servidores productivos:
    • Usuario administrador: desarrollo instala los paquetes que necesita.
    • Usuario limitado: se le da un espacio donde alojar el código y credenciales para acceder a la base de datos.
    • ¿Equipos compartidos entre diferentes sistemas?
      • ¡Impacto en otras aplicaciones!
  • Servidores dedicados:
    • Desarrollo gestiona su infraestructura, sea en equipos físicos o virtuales.

Desarrollo como cliente

  • El área de desarrollo debería desarrollar.
    • Pierde tiempo gestionando infraestructura.
    • No es en lo que se especializa.
      • ¡Esto trae problemas que impactan en el área de infraestructura!

Desarrollo como cliente

  • Además de los sistemas en producción, se tiene:
    • Gestión de ambientes: surge la necesidad de disponer de ambientes con diferentes objetivos: desarrollo, testing, staging, QA, producción.
    • Servicios para la gestión de proyectos: también se brindan servicios que permiten a los desarrolladores manejar tickets, versionado, comunicación de equipos, integración continua, etc.

Entornos heterogéneos

  • Las organizaciones intentaron hace un tiempo homogeneizar tecnologías.
    • En los hechos esto se ha vuelto un fracaso.
    • Tecnologías cambian, evolucionan, pasan de moda.
    • Nuevos paradigmas requieren arquitecturas heterogéneas.
    • Sistemas legados.

Entornos heterogéneos

  • La heterogeneidad trae problemas:
    • Surgen tendencias que se convierten en requisitos: Java, Elixir, Rails, Django, NodeJS, Erlang, Redis, Memcached, Websockets, MongoDB, Hadoop, Spark, ElasticSearch, etc.
    • Infraestructura se enfrenta a:
      • ¿Cómo gestionar todos los nuevos servicios?
      • ¿Cómo monitorear?
      • ¿Cómo backupear?
      • ¿Seguridad?

Compromiso de la seguridad por hosting

  • Asegurar equipos y entornos compartidos.
  • Aislar diferentes sistemas que se ejecutan en los mismos servidores.
  • Limitar el impacto por problemas de seguridad.
  • ¡Todo lo anterior se debe hacer desconociendo cómo funcionan y qué hacen los sistemas!

Backups, monitoreo y estadísticas

  • Infraestructura define:
    • Políticas de backup.
    • Mecanismos de monitoreo.
    • Recolección de datos para generar estadísticas.
  • Lo anterior está bien para los servicios propios de infraestructura, ¿pero para los sistemas?
    • Backup de las máquinas completas:
      • ¿Hace falta hacer copias de seguridad del código?
    • Monitoreo de los servicios:
      • ¿Garantiza que anden los sistemas?
    • ¿Y las estadísticas?

Backups, monitoreo y estadísticas

  • En este punto, desarrollo debería:
    • Explicar cómo se monitorea el sistema (y mejor aún, disponer en la propia aplicación de un mecanismo para hacerlo).
    • Hacer un buen uso de los logs.
    • Indicar qué datos son los que deben resguardarse (¡y la periodicidad!).
      • ¿Política de backup corresponde a desarrollo? ¿Al dueño del sistema?
    • Usar herramientas de profiling que permitan evaluar el comportamiento de la aplicación.

Y no es todo...

  • El área de infraestructura tiene que atender muchas más cuestiones, como por ejemplo:
    • Vencimientos de certificados.
    • Gestión de SPAM para evitar la llegada y salida.
    • Problemas de hardware habituales.
    • Pruebas de restauración de backups.
    • Migraciones de datos entre productos.

Puesta en producción

El momento en que desarrollo e infraestructura interactúan

Puesta en producción

  • Deben definirse procedimientos para:
    • Deploy de nuevas aplicaciones.
    • Upgrade de aplicaciones existentes.
    • Rollback
  • ¿Cómo se actualiza una base de datos?
    • ¡¿Y el rollback?!
  • ¿Infraestructura y desarrollo deberían hacerlo en conjunto?
    • ¿README con instrucciones?

Puesta en producción

  • Cada caso requiere tiempo y, muchas veces, poner los sistemas offline.
  • Con las formas tradicionales de desarrollo:
    • Pasaban semanas entre cambios en producción.
    • Algunas organizaciones tenían días definidos para la puesta en producción.

Puesta en producción

Desarrollos tradicionales

Puesta en producción

  • Con las metodologías ágiles los cambios en producción deben ser muy frecuentes.
  • Infraestructura no cuenta con las herramientas necesarias para agilizar la puesta en producción de forma segura.
    • ¡Es un trabajo manual!
  • La promesa de las metologías ágiles encuentra un importante obstáculo...

Puesta en producción

Desarrollos ágiles

Deploy de nuevas aplicaciones

  • Es el caso ideal, se arranca sin historia previa.
  • Se deben considerar varias cuestiones:
    • La aplicación corre con un usuario determinado.
    • Crear la estructura de directorios necesaria.
    • Instalación de servicios que son requeridos:
      • Rotación de logs.
      • Servicios asincrónicos.
      • Creación de usuarios y bases de datos necesarios.
    • Definir y aplicar las políticas de backups.
    • Estadísticas y monitoreo.

Upgrade de aplicación existente

  • Revisar si alguno de los puntos considerados en el caso anterior varía.
  • Actualizar el código, preservando en lo posible la versión anterior.
  • Aplicar parches necesarios a la base de datos.
  • Poner el sistema offline es la solución más segura pero no siempre es una opción:

Rollback

  • Es volver atrás los cambios realizados.
    • Los cambios no funcionan según lo esperando.
  • Conservando una copia del código anterior, se vuelve a apuntar a esa versión.
    • Usando links simbólicos es muy simple.
    • Si hay cambios en la base de datos ya no es tan sencillo.
  • Si se utiliza blue green deployments, entonces sólo se cambia el proxy reverso.
    • Si la base de datos se puso en sólo lectura.

Actualizaciones de las bases de datos

  • El versionado del código resuelve la simplicidad de actualizar y realizar rollbacks.
    • Con las bases de datos no sucede lo mismo.
  • Versionar la estructura de la BD con el código no aporta demasiado.
    • Cómo aplicar un parche a un modelo y deshacerlo en caso de rollback.
    • Estos parches deben ser idempotentes.
    • No siempre un parche a una BD tiene vuelta atrás.
  • Algunos parches pueden ser costosos en BBDD grandes.

Otras cuestiones a considerar

  • Ante un cambio de versión es aconsejable notificar a los usuarios con anticipación de la interrupción del servicio.
    • Requiere conocer el dominio de usuarios afectados.
    • Programar el envío masivo de correos.
    • Planificar y notificar con anticipación mejoran la calidad del servicio.
  • Gestión de contratos:
    • Cumplir con el SLA.
    • Vencimiento de hosting.

Ambientes independientes

Mejorando la calidad global

Introducción

  • No disponer de diferentes ambientes implicaría:
    • La única versión que es igual a producción, es la de producción.
      • Se cambió algo en producción que no funcionaba y no se actualizó el código versionado.
    • Las pruebas se realizan en la PC del desarrollador o directamente en producción.
    • Lo que funciona en desarrollo no anda en producción.

Pareciera imposible que esto suceda, pero muchas organizaciones siguen gestionando sus desarrollos de esta forma.

Ambientes

  • Diferentes ambientes permiten:
    • Desarrollar bajo iguales condiciones.
    • Validar los cambios con los usuarios.
    • Realizar pruebas de calidad y seguridad del software.
    • Minimizar los problemas en producción.
  • Estos ambientes deben gestionarse:
    • Sobrecarga de trabajo.
    • Idealmente, todos idénticos entre sí.
      • ¿Cómo garantizamos esto?

Ambientes

  • Desarrollo: en el cuál se construye el software.
  • Testing: se publica el software para que sea probado por un grupo definido de personas, que debería incluir al usuario final o representantes del mismo.
  • Staging (QA): idéntico y previo a producción. Permite probar el despliegue y el funcionamiento, realizando cualquier ajuste necesario en esta instancia, evitando problemas en producción.
  • Producción: tiene todos los servicios productivos. Este ambiente cuenta con políticas estrictas en cuanto al acceso y la seguridad del mismo.

Ambientes

Dependiendo de la organización y el flujo de trabajo adoptado, pueden definirse más o menos ambientes.

Soluciones

(¡y nuevos problemas!)

Introducción

En este apartado veremos qué metodologías y/o herramientas han surgido para solucionar algunas de las problemáticas mencionadas.

Asimismo, mostraremos que estas soluciones introdujeron nuevos problemas.

Virtualización

  • Existen diferentes alternativas de virtualización, tanto libres como licenciadas, con diferentes capacidades.
  • El uso de cualquier herramienta disponible para virtualizar, ofrece mejoras sustanciales:
    • Backup de VMs.
    • Gestión simplificada de servidores, virtuales en lugar de físicos.
    • Migración en caliente de VMs entre equipos físicos.
    • Mejor aprovechamiento de recursos de hardware.
    • Instalación de SO basada en templates que permite disponer rápidamente de servidores pre-instalados.

Complicaciones con la virtualización

  • Muchas de sus ventajas requieren un storage.
  • Las características más atractivas suelen proveerse en versiones licenciadas.
  • Se administran más servidores que si se utilizaran equipos físicos:
    • Esto se debe a que un servicio aislado es más seguro e independiente, con lo cuál su reemplazo o actualización se simplifica.
    • Por esta razón, crece el uso de VMs, dificultando el mantenimiento de su inventario, que rápidamente se desactualiza.

Distribución de aplicaciones

  • Cuando varias aplicaciones comparten requerimientos, es tentador utilizar el mismo servidor para alojarlas:
    • Se reduce la cantidad de servidores a gestionar.
    • Se compromete la seguridad de todas las aplicaciones instaladas.
  • Los sistemas pueden agruparse por distintos criterios. Por ejemplo, por:
    • criticidad,
    • tecnologías,
    • conjuntos de usuarios.

Alta disponibilidad / Failover / Actualizaciones

  • Los stacks de un servicio determinado se componen de partes diferentes sobre las cuales quizá sea necesario garantizar alta disponibilidad y/o failover.
  • Actualizar un servicio es una tarea artesanal y costosa.
    • Sobre todo si es un servicio distribuido con muchas dependencias.

DevOps

¿Qué es DevOps?

  • Metodología para el desarrollo y puesta en producción del software.
  • Promueve una fuerte integración y colaboración entre desarolladores de software y administradores de sistemas.
  • Incrementa la productividad de los equipos, al mismo tiempo que permite generar software de mayor calidad, con una alta frecuencia de despliegues en producción.

¿Qué es DevOps?

  • Se lo suele asociar a una filosofía, pero es porque en realidad requiere un importante cambio cultural.
    • Acerca mucho las áreas de desarrollo e infraestructura.
      • El mayor impacto se da en esta última.
    • El cambio cultural es la barrera más difícil de superar para su adopción.

Orígenes

  • Aproximadamente en el año 2009, ante la convergencia de diferentes trabajos:
    • Las conferencias Velocity, en particular la presentación "10 deploys per day - Dev & Ops cooperation at Flickr"
      • Aquí además se acuña el término.
    • Los movimientos de IaC (Infraestructure as Code), Agile infraestructure y Agile system administration.
    • El movimiento de Lean Startup.
    • El movimiento de integración y despliegue continuo.

Orígenes

  • La gran disponibilidad de tecnologías de cloud: PaaS/IaaS.
    • AWS
    • Google Compute Engine
    • Microsoft Azure
    • Heroku
    • Digital Ocean
    • Softlayer
    • Rackspace

Orígenes

Como recurso adicional, hay un interesante video de Damon Edwards que resume la historia de DevOps (¡hasta 2012!).

Caracterización

  • DevOps se ajusta perfectamente a las metodologías ágiles:
    • extiende y completa el proceso de integración y despliegue continuo, asegurando que el código esté listo para producción, agregando así valor para los clientes.
  • Surge un nuevo perfil profesional:
    • La organización que desea incorporar DevOps debe formar a sus desarrolladores y administradores de sistemas para reunir las capacidades y conocimientos requeridos.
      • Desarrolladores que piensan como administradores y administradores que piensan como desarrolladores.

Infraestructure as code

  • IaC es el proceso por el cuál se gestionan y aprovisionan máquinas (físicas o virtuales) completas.
  • Este aprovisionamiento se realiza a través de archivos de configuración que son interpretados por alguna herramienta de orquestación.
  • Estos archivos de configuración se versionan en un SCM.
  • Se programa una vez y se repite miles de veces.

Infraestructure as code

  • Claves:
    • Idempotencia
    • Multiplataforma
    • Flexibilidad
    • ¿Facilidad de aprendizaje?

Herramientas

Existen diversos productos que se basan en IaC

Chef Logo Chef
Puppet Logo Puppet Labs
Ansible Logo Ansible
Saltstack Logo SaltStack

Test de la infraestructura

Conceptos relacionados

  • A continuación describiremos brevemente los siguientes conceptos:
    • Integración continua (continuous integration).
    • Entrega continua (continuous delivery).
    • Despliegue continuo (continuous deployment).

Integración continua

  • Considerar el trabajo diario de un equipo de desarrolladores.
    • Cada desarrollador trabaja en una rama determinada en el SCM.
    • Las ramas deben integrarse luego en la principal.
      • En un proyecto con varios desarrolladores, el momento de integrar todas esas ramas puede ser muy difícil (merge hell).

Proyecto con varias ramas

git branches

¿Cómo es posible garantizar un merge satisfactorio en todos los casos?

Integración continua

  • Integrar frecuentemente las ramas derivadas con la principal.
    • ¿Qué tan frecuente?
  • Al integrar frecuentemente:
    • Se minimizan los errores y el trabajo para hacer los merge.
    • Se detectan de forma temprana los problemas.
  • Requiere definir un flujo de trabajo que todos respeten.
  • Para hacer el merge, el código debe pasar todos los tests de unidad e integración.
    • Esto se puede automatizar con herramientas de CI.

Herramientas de CI

Entrega continua y despliegue continuo

  • Generalmente se confunden ambos conceptos.
    • Despliegue continuo significa que cada cambio se aplica directamente en producción.
    • Entrega continua hace que cada cambio esté disponible para producción, pero la puesta en producción requiere intervención humana.
  • Ambos mecanismos son posteriores en el tiempo a la integración continua.

Flujo de trabajo

Introducción

Es importante definir un flujo de trabajo que considere completamente las tareas desde que comienza el desarrollo hasta que se ponen los sistemas en producción.

¡Considerando que todas son tareas iterativas y continuas!

Gestión de proyectos

  • Sistema de tickets para seguimiento del proyecto.
  • Respetar estándares de codificación.
  • Utilizar una herramienta de versionado de código.
  • Gestionar los cambios en la base de datos.
  • Determinar versionado del producto.
  • Establecer un flujo de trabajo y reglas para el equipo de desarrollo.
  • Testing del software.
  • Reglas para pasaje a producción.

Versionado del código

  • Versionar el código: hoy en día, GIT.
  • Commits atómicos:
    • Cada commit debe atacar un problema específico.
    • Documentar correctamente el propio commit.
      • Simplifica la comunicación del equipo.
    • Relacionar los commits con tickets en el sistema correspondiente.
  • Usar plataforma de gestión del código.
    • Gitlab, Github, Bitbucket.

Versionado del código

  • Adoptar un flujo de trabajo para la gestión del código:
    • git-flow: trabajo con estrategias de branches y manejo de releases.
      • Concepto de hotfix branches.
      • Punto débil: no considera que se puedan mantener varias versiones productivas del software (solución con support branches, cherry pick).
    • Permisos sobre las ramas: desarrolladores experimentados revisan el código de programadores nóveles. Por ejemplo: flujo tipo GitHub.

Versionado de la base de datos

  • Versionar la base de datos no es algo habitual pero sí importante.
  • Necesitamos disponer de un mecanismo para poder ir hacia adelante y hacia atrás en la estructura de una base de datos.
  • Algunos frameworks incorporan mecanismos para gestionar el versionado de la base de datos.
  • Un parche no es versionado, dado que no permite volver atrás en la historia.

Versionado del software

  • Es importante disponer de una convención para versionar cada release del software.
    • Semantic Versioning
      • Define claramente el significado de cada número en un esquema X.Y.Z.
      • Permite establecer reglas de dependencia y automatización (ejemplo: si sólo cambia el último número aplicar directamente en producción).
  • Establecer una correspondencia entre la versión del código y la del modelo de datos.
  • La creación de un release implica que se hayan cumplido todos los requisitos de calidad del software.

Calidad del software

  • Aplicar buenas prácticas de calidad:
    • TDD con alta cobertura.
    • Tests de aceptación.
    • Tests de estilo (y estándares) de codificación.
  • Considerar en el flujo que se pueda lograr:
    • Integración continua.
    • Entrega continua.
    • Despliegue continuo.

TDD

  • Test-driven development es una técnica que promueve que primero se escriban los tests y luego el código que pase esos tests.
  • Simplifica el desarrollo, al conocer exactamente lo que el código debe hacer.
  • Garantiza que todo el código tenga tests (o la mayoría del mismo).
  • Incrementa significativamente la calidad del software.

TDD

  • Los tests deben controlarse por un área de QA en cada etapa del desarrollo, estableciendo políticas de aceptación para cada etapa.
  • Ejemplos de políticas:
    • El código no es revisado antes de mergerarse si no pasan los test de unidad, funcionales e integración. Tampoco si el analizador de código no garantiza que se respetan los estándares.
    • Un release no se pone en producción si no pasa todos los tests de unidad, funcionales, integración y aceptación.

Despliegues

  • Establecer reglas para desplegar el software en producción.
  • Automatizar todas las tareas repetitivas.
  • Según las reglas definidas, considerar la posibilidad de poder automatizar también la puesta en producción.
  • La automatización puede hacerse mediante scripts caseros o con herramientas específicas.

Mantenimiento del software

  • El trabajo no termina cuando el software se pone en producción.
  • Mecanismos para:
    • Backups
    • Monitoreo y estadísticas.
  • Automatizar esas configuraciones:
    • Al desplegar un software en producción, disponer de mecanismos que actualicen automáticamente los productos de backups y monitoreo.
    • Se garantiza que todo sistema en producción dispone de lo anterior.

Monitoreo y estadísticas

  • Recolectar constantemente información del software en producción.
    • Uso de recursos.
    • Tiempos de respuesta de cada componente.
    • Errores en cada capa.
  • Lo anterior permite:
    • Conocer el comportamiento normal del software.
    • Detectar y corregir errores: mejora continua.
    • ¡Aprender!

Monitoreo y estadísticas

  • Si conocemos el comportamiento normal del software entonces podemos:
    • Identificar los momentos en que los valores se escapan de lo normal.
    • “Personalizar” el monitoreo para cada sistema.
    • ¡Generar alertas significativas!
  • Las estadísticas permiten:
    • Tomar decisiones informadas.
    • Entender el uso del hardware.
    • Escalar los servicios de forma automática.

Escalamiento horizontal

  • Dos formas de hacerlo:
    • Alguien detecta que el servicio está lento (o se prevé un uso intensivo) y se escala manualmente.
    • El software de monitoreo detecta que los valores normales cambiaron y dispara una acción para escalar de forma automática.
  • Escalado:
    • Hacia arriba: para atender mayor cantidad de usuarios.
    • Hacia abajo: para ahorrar costos.

Escalamiento horizontal

  • El escalamiento de un sistema no es trivial.
    • Debe considerarse desde el diseño del software y de la propia infraestructura.
  • Los microservicios simplificaron el escalamiento, al permitir escalar sólo las componentes saturadas.

Herramientas

Vagrant

Vagrant background

Vagrant

  • Permite construir y gestionar máquinas virtuales con un flujo de trabajo sencillo y rápido.
  • Reduce significativamente el tiempo necesario para generar ambientes de desarrollo.
  • Aisla las dependencias y sus configuraciones en un ambiente consistente y descartable.
  • Utiliza un archivo de texto plano (Vagrantfile) para definir la configuración completa.
  • Disponible para Mac, Linux y Windows.

Providers

  • Virtualbox
  • Hyper-V
  • VMWare
  • Docker
  • AWS

Provisioners

  • File
  • Shell
  • Ansible
  • CFEngine
  • Chef
  • Puppet
  • Docker
  • Salt

Comandos

vagrant up
vagrant destroy
vagrant ssh
vagrant provision
vagrant reload [--provision]
vagrant box list

Ejemplo: shell provisioning

Vagrant.configure(2) do |config|
  config.vm.box = "bento/ubuntu-16.04"
  config.vm.box_check_update = false
  config.vm.network "private_network", ip: "192.168.222.22"

  config.vm.provision "shell", inline: <<-SHELL
     sudo apt-get update
     sudo apt-get install -y apache2
  SHELL
end

Ejemplo de un servidor con Apache

Ejemplos: multimachine

Vagrant.configure(2) do |config|
  config.vm.define 'master', primary: true do |app|
    app.vm.box = "bento/ubuntu-16.04"
    app.vm.network "private_network", ip: "192.168.222.20"
    app.vm.provision "docker" do |d|
      ...
    end
  end
  (1..3).each do |num|
    config.vm.define "node-#{num}" do |app|
      app.vm.box = "bento/ubuntu-16.04"
      app.vm.network "private_network", ip: "192.168.222.2#{num}"
      app.vm.provision "docker" do |d|
        ...
      end
    end
  end

Ejemplo de un cluster de Docker Swarm

Ejemplo: cluster de Rancher

  • Este ejemplo levanta 3 máquinas:
    • 1 será el servidor de Rancher.
    • 2 máquinas actúan como nodos de procesamiento.
  • Instala todo el software necesario.
  • Registra ambos nodos en el servidor de Rancher.
  • Deja el cluster listo para ser usado.

Vagrantfile
Repositorio completo

Docker

Docker logo

Docker

  • Permite correr contenedores aislados unos de otros.
  • Promueve la portabilidad, permitiendo contenedores autosuficientes que son creados según las necesidades de una aplicación.
  • Los contenedores usados en desarrollo pueden usarse en ambientes de testing y producción.
    • Minimiza la brecha entre desarrollo e infraestructura.
  • Se basa en en el concepto de inmutabilidad.
  • Funciona en Mac, Linux y Windows.
  • Los contenedores pueden ejecutar tanto Linux como Windows.
  • Puede utilizarse para aplicaciones gráficas.

Docker: conceptos

  • Docker funciona a partir de:
    • Docker engine: set de herramientas para gestionar Docker. Incluye el servicio de Docker, una API REST y un cliente de línea de comandos para interactuar con el daemon.
    • Docker hub/registry: repositorio de imágenes públicas o privadas a partir de las cuales se crean los contenedores.

Docker: comandos

docker search
docker images
docker pull
docker run
docker ps
docker diff
docker commit
docker inspect
docker log

Ejemplo: MySQL

Iniciamos una instancia de Mysql con Docker

docker run -p 33060:3306 -e MYSQL_ROOT_PASSWORD=devops -d mysql:5.7

mysql -u root -h 127.0.0.1 --port 33060 -pdevops

¿Qué sucede si eliminamos el contenedor?

Volúmenes

docker volume ls
docker volume create
docker volume rm
docker volume inspect

Ejemplo: MySQL con volúmenes

Iniciamos una instancia de Mysql con docker

docker run -p 33060:3306 -e MYSQL_ROOT_PASSWORD=devops -v /tmp/mysql:/var/lib/mysql -d mysql:5.7

mysql -u root -h 127.0.0.1 --port 33060 -pdevops

¿Qué sucede si eliminamos el contenedor?

Docker Compose

Se describe una aplicación compuesta por más de un contenedor mediante un yml

version: "2"
services:
  wordpress:
    image: wordpress
    links:
      - db:mysql
    ports:
      - 8080:80
  db:
    image: mysql:5.7

Ver ejemplo completo

Docker Compose: comandos

docker-compose up
docker-compose ps
docker-compose stop
docker-compose rm
docker-compose scale

Capistrano Logo

Automatizando los deploys

  • El objetivo es automatizar la instalación/actualización de una aplicación en un servidor remoto.
  • No todos los desarrollos tienen las mismas necesidades:
    • Realizar un build.
    • Publicar un artefacto.
    • Instalar dependencias.
    • Subir/Descargar código/artefacto.
    • Correr scripts.

Un ejemplo: Capistrano

role :demo, %w{srv-01 srv-02 srv-03}
task :uptime do
  on roles(:demo), in: :parallel do |host|
    uptime = capture(:uptime)
    puts "#{host.hostname} reports: #{uptime}"
  end
end

Ver ejemplo

Uso de Capistrano

cap install # Inicializa el directorio
cap -T # Lista todas las posibles tareas disponibles

Uso de Capistrano

  • Instaura la noción de ambientes:
    • Por defecto inicializa dos ambientes: production y staging.
    • Los ambientes configuran los accesos.
    • Las tareas son las mismas para cada ambiente.

production.rb

role :demo, %w{localhost}

server '192.168.222.22',
   roles: %w(demo),
   ssh_options: {
     user: 'vagrant',
     forward_agent: true,
     auth_methods: %w(publickey password),
     password: 'vagrant'
   }

Uso de Capistrano

  • Además de los ambientes, Capistrano define roles. Por ejemplo: web, app, db.
    • Un servidor tiene un rol.
    • En un server con un determinado rol, hay que realizar diferentes tareas. Por ejemplo: assets en web, deploy en app, dump en db.
  • Además de las tareas predefinidas, permite extenderlo con tareas propias, ya sean locales como remotas.
  • Las tareas predefinidas permiten realizar deploy y rollback.

Veremos ejemplos de uso de capistrano deployando en un servidor virtual con IP 192.168.23.22

Ejemplo de Capistrano y Jekyll

  • Jekyll es un generador de sitios web estáticos.
    • El sitio web de Mikroways fue desarrollado con Jekyll.
  • Desplegaremos en la VM el sitio usando Jekyll. Para ello:
    • El servidor debe tener instalado Ruby.
    • Se debe descargar el código del sitio desde GitHub.
    • Se debe correr el comando jekyll build
    • ¡Listo!
  • Para probarlo: http://192.168.23.22

Ver el ejemplo

Ejemplo de Capistrano y Jekyll

  • Con Capistrano:
    • Hacemos el despliegue del sitio: cap production deploy
    • En el servidor ejecutamos jekyll build
    • Probamos acceder al sitio con el navegador
  • Probamos una nueva versión del sitio.
  • Hacemos un rollback: cap production deploy:rollback

Capistrano y desarrollos dinámicos

  • En sitios que no son estáticos, existen archivos que deben mantenerse entre despliegues:
    • Configuración de la base de datos o software.
    • Uploads o archivos generados por la aplicación.
  • Capistrano permite definir qué archivos y qué directorios son compartidos.
  • De aquí la estructura propuesta por Capistrano es:
  base_dir
  ├── current -> /opt/sites/jekyll/releases/20180405173257
  ├── releases
  │   └── YYYYMMDDHHmmii
  ├── repo
  └── shared

Otras Herramientas

Chef Logo

Chef

  • Chef permite modelar y automatizar la infraestructura y aplicaciones como si fueran código.
  • Es altamente flexible y potente.
  • La consecuencia es que la infraestructura se vuelve:
    • Versionable
    • Testeable
    • Replicable
    • Idempotente
  • Se programa en Ruby usando una DSL (domain-specific language).

Conceptos de Chef

  • Para lograr su objetivo se utilizan definiciones reutilizables llamadas cookbooks y recipes.
  • El Chef server reúne todo el repositorio de configuraciones que utilizarán luego los nodos para configurarse.
  • Se interactúa con los nodos y el servidor usando el comando knife.
  • Los nodos representan a cada equipo gestionado con Chef.
  • Por medio de data bags, roles y atributos se personaliza cada servidor.
  • Cada nodo tiene una run list que indica todas las recetas que se le aplicarán.
  • Se puede buscar sobre todas las entidades de Chef.

Arquitectura

Chef architecture

Ejemplo de una receta

package 'nginx'

service 'nginx' do
  action [:enable, :start]
end

template '/etc/nginx/sites-enabled/www.conf' do
  source 'nginx-default.conf.erb'
  variables(
    server_name: 'www.mikroways.net',
    document_root: '/var/www'
  )
  notifies :restart, 'service[nginx]', :immediately
end

Ver ejemplo completo
Es posible probar las recetas con una versión de chef llamada chef-zero/chef-solo

TDD

Desplegando el potencial de Chef

Video

Alternativas a Chef

  • Ansible: muy sencillo, más tentador para administradores de sistemas.
  • Saltstack
  • Puppet: principal competencia.

chef-provisioning

Introducción

  • Chef-provisioning extiende chef permitiendo crear VMs en diferentes plataformas de virtualización. Algunas de ellas son:
    • Vagrant
    • AWS
    • Azure
    • DigitalOcean
    • VMWare
    • XenServer
    • Google Compute Engine
    • IBM SoftLayer

¿Para qué sirve?

  • Permite crear, iniciar y aprovisionar máquinas, abstrayendo al usuario de la plataforma subyacente.
  • Evita el uso reiterativo de knife para iniciar VMs.
  • Posibilita restaurar de forma completa una infraestructura.

Ejemplo

chef_role 'web-server' do
  run_list ["recipe[apt]","recipe[web-server]"]
end

machine_batch do
  machine 'web-01' do
    run_list ['role[web-server]']
  end
  machine 'web-02' do
    run_list ['role[web-server]']
  end
end

machine 'proxy' do
  run_list ['recipe[myhaproxy]']
end

Corremos en nuestra PC

chef-client -z -r 'my-infra::chef,my-infra::aws,my-infra'

Eliminando todo

chef_role 'web-server' do
  action :delete
end

machine_batch do
  action :destroy
  machines 'web-01', 'web-02', 'proxy'
end

Corremos en nuestra PC

chef-client -z -r 'my-infra::chef,my-infra::aws,my-infra::delete'

Y ahora con Vagrant


chef-client -z -r 'my-infra::chef,my-infra::vagrant,my-infra'

Esto es muy importante, porque sólo cambiando el driver de aprovisionamiento, podemos reusar nuestra infraestructura definida.

Podemos incluso tener un cluster con VMs de diferentes proveedores.

Terraform

Terraform logo

La alternativa a chef-provisioning

Clusters de contenedores

Productos para clusters

Características

  • Scheduling de contenedores.
    • Importancia de los labels en Docker.
  • Service discovery:
    • Zookeper
    • Consul
    • Etcd
  • Complicaciones:
    • Volúmenes compartidos.
    • Monitoreo y logs.

Sistemas operativos para Docker

Rancher logo

Rancher

  • Permite configurar ambientes con:
    • Cattle, Swarm, Kubernetes y Mesos.
  • Los ambientes se componen de nodos.
  • Los contenedores se agrupan en stacks y se crean con docker-compose.
  • Provee un catálogo de aplicaciones que se puede extender.
  • Simplifica la integración con registries privadas.
  • Proxy reverso basado en service discovery.
  • Simplifica el escalamiento de contenedores.
  • Tiene una API REST que permite interactuar con el cluster.

Ejemplo

  • Desplegar un Wordpress desde el catálogo.
    • Establecer una restricción para que el RDBMS corra en un nodo determinado.
  • Escalar el servicio.

Otro ejemplo

  • Aplicación propia:
    • El nombre del directorio es importante ya que le da el nombre al stack.
    • Crear: docker-compose.yml
    • Iniciar el stack: rancher-compose up
    • Verificar
    • Actualizar: rancher-compose up -u my-app
    • Verificar
    • Realizar un rollback.

¿Preguntas?

Gracias


contacto@mikroways.net
www.mikroways.net