DEVOXX Reino Unido. Kubernetes en producción: implementación azul / verde, autoescalado y automatización de implementación. Parte 2

Kubernetes es una gran herramienta para ejecutar contenedores Docker en un entorno de producción en clúster. Sin embargo, hay tareas que Kubernetes no puede resolver. Con implementaciones frecuentes en un entorno de producción, necesitamos una implementación Azul / Verde totalmente automatizada para evitar el tiempo de inactividad en este proceso, que también requiere solicitudes HTTP externas y carga SSL. Esto requiere integración con un equilibrador de carga como ha-proxy. Otra tarea es el escalado semiautomático del clúster Kubernetes en sí mismo cuando se trabaja en la nube, por ejemplo, la reducción parcial de la escala del clúster por la noche.

Aunque Kubernetes no tiene estas características listas para usar, proporciona una API que puede usarse para resolver tales problemas. Las herramientas de escala y despliegue automatizado azul / verde de Kubernetes se desarrollaron como parte del proyecto de código abierto Cloud RTI.

Esta transcripción del video describe cómo configurar Kubernetes junto con otros componentes de código abierto para obtener un entorno listo para la producción que acepte el código del git commit change commit sin tiempo de inactividad en la producción.



DEVOXX Reino Unido. Kubernetes en producción: implementación azul / verde, autoescalado y automatización de implementación. Parte 1

Entonces, después de haber accedido a sus aplicaciones desde el mundo exterior, puede comenzar a configurar completamente la automatización, es decir, llevarla al escenario donde puede ejecutar git commit y asegurarse de que este git commit termine en producción. Naturalmente, en la implementación de estos pasos, en la implementación de la implementación, no queremos enfrentar el tiempo de inactividad. Entonces, cualquier automatización en Kubernetes comienza con una API.



Kubernetes no es una herramienta que se pueda usar "fuera de la caja" productivamente. Por supuesto, puede hacer esto, usar kubectl, etc., pero aún así la API es lo más interesante y útil de esta plataforma. Usando la API como un conjunto de características, puede acceder a casi todo lo que quiera hacer en Kubernetes. Kubectl también usa la API REST.

Esto es REST, por lo que puede usar cualquier idioma y herramientas para trabajar con esta API, pero las bibliotecas de usuario le facilitarán enormemente la vida. Mi equipo escribió 2 bibliotecas de este tipo: una para Java / OSGi y otra para Go. El segundo no se usa con frecuencia, pero en cualquier caso, estas cosas útiles están a su disposición. Son un proyecto de código abierto con licencia parcial. Existen muchas bibliotecas de este tipo para diferentes idiomas, por lo que puede elegir la más adecuada.



Por lo tanto, antes de embarcarse en la automatización de la implementación, debe asegurarse de que este proceso no esté sujeto a ningún tiempo de inactividad. Por ejemplo, nuestro equipo lleva a cabo la implementación de producción en la mitad del día, cuando las personas aprovechan al máximo sus aplicaciones, por lo que es muy importante evitar retrasos en este proceso. Para evitar el tiempo de inactividad, se utilizan 2 métodos: implementación azul / verde o actualización continua actualización continua. En el último caso, si tiene 5 réplicas de la aplicación en ejecución, se actualizan secuencialmente una tras otra. Este método funciona muy bien, pero no funciona si está ejecutando diferentes versiones de la aplicación al mismo tiempo durante el proceso de implementación. En este caso, puede actualizar la interfaz de usuario mientras el backend funcionará con la versión anterior y la aplicación dejará de funcionar.Por lo tanto, desde el punto de vista de la programación, trabajar en tales condiciones es bastante difícil.

Esta es una de las razones por las que preferimos utilizar la implementación azul / verde para automatizar la implementación de nuestras aplicaciones. Con este método, debe asegurarse de que en un momento determinado solo esté activa una versión de la aplicación.

El mecanismo de despliegue azul / verde es el siguiente. Obtenemos tráfico para nuestras aplicaciones a través de ha-proxy, que lo dirige a ejecutar réplicas de aplicaciones de la misma versión.

Cuando se lleva a cabo una nueva implementación, utilizamos Deployer, que se proporciona con nuevos componentes, e implementa la nueva versión. La implementación de una nueva versión de una aplicación significa que un nuevo conjunto de réplicas está "en aumento", después de lo cual estas réplicas de la nueva versión se lanzan en un nuevo pod separado. Sin embargo, ha-proxy no sabe nada sobre ellos y hasta ahora no les ha enviado ninguna carga de trabajo.

Por lo tanto, en primer lugar, es necesario verificar el estado de las nuevas versiones del chequeo de estado para asegurarse de que las réplicas estén listas para servir la carga.



Todos los componentes de implementación deben admitir alguna forma de revisión de salud. Esta puede ser una verificación HTTP muy simple con una llamada cuando recibe un código con un estado de 200, o una verificación más profunda en la que verifica la conexión de réplicas con la base de datos y otros servicios, la estabilidad de las conexiones del entorno dinámico, si todo comienza y funciona correctamente. Este proceso puede ser bastante complicado.



Después de que el sistema haya verificado que todas las réplicas actualizadas estén operativas, Deployer actualizará la configuración y pasará la confd correcta, que reconfigurará el proxy ha.



Solo después de eso, el tráfico se dirigirá hacia abajo con réplicas de la nueva versión, y la anterior desaparecerá.



Este mecanismo no es una característica de Kubernetes. El concepto de implementación azul / verde ha existido durante bastante tiempo y siempre ha utilizado un equilibrador de carga. Primero, dirige todo el tráfico a la versión anterior de la aplicación, y después de la actualización, transfiéralo completamente a la nueva versión. Este principio se usa no solo en Kubernetes.

Ahora le presentaré un nuevo componente de implementación: Deployer, que realiza una comprobación de estado, reconfigura los proxies, etc. Este es un concepto que no se aplica al mundo exterior y existe dentro de Kubernetes. Le mostraré cómo puede crear su propio concepto de Deployer utilizando herramientas de código abierto.

Entonces, lo primero que hace Deployer es crear un controlador de replicación RC utilizando la API de Kubernetes. Esta API crea pods y servicios para una mayor implementación, es decir, crea un clúster completamente nuevo para nuestras aplicaciones. Una vez que el RC verifica que las réplicas han comenzado, verificará su comprobación de estado. Para hacer esto, Deployer usa el comando GET / health. Lanza los componentes de verificación correspondientes y verifica todos los elementos que aseguran el funcionamiento del clúster.



Después de que todos los pods hayan informado de su "estado", Deployer crea un nuevo elemento de configuración: el almacenamiento distribuido, etc., que se usa dentro de Kubernetes, incluso para almacenar la configuración del equilibrador de carga. Escribimos datos en etcd, y una pequeña herramienta, confd, monitorea etcd para obtener nuevos datos.

Si encuentra algún cambio en la configuración inicial, genera un nuevo archivo de configuración y lo pasa a ha-proxy. En este caso, ha-proxy se reinicia sin perder ninguna conexión y aborda la carga con nuevos servicios que proporcionan la nueva versión de nuestras aplicaciones.



Como puede ver, a pesar de la abundancia de componentes, no hay nada complicado. Solo necesita prestar más atención a la API y etcd. Quiero contarles sobre el implementador de código abierto que nosotros mismos utilizamos: este es el Implementador de Amdatu Kubernetes.



Esta es una herramienta de organización de implementación de Kubernetes con las siguientes características:

  • Despliegue azul / verde
  • configurar un equilibrador de carga externo;
  • Gestión del descriptor de despliegue
  • Gestión de despliegue real
  • Comprobaciones de estado durante el despliegue
  • implementación de variables de entorno en pods.

Creado sobre la API de Kubernetes, este Implementador proporciona una API REST para administrar descriptores e implementaciones, así como una API Websocket para registros de flujo durante la implementación.

Pone los datos de configuración del equilibrador de carga en etcd, por lo que no puede usar ha-proxy con soporte "listo para usar", pero es fácil usar su propio archivo de configuración del equilibrador. Amdatu Deployer está escrito en Go, al igual que Kubernetes, y con licencia de Apache.

Antes de usar esta versión del desplegador, utilicé el siguiente descriptor de despliegue, que especifica los parámetros que necesito.



Uno de los parámetros importantes de este código es habilitar el indicador "useHealthCheck". Necesitamos indicar que se requiere una comprobación de estado durante el proceso de implementación. Esta opción se puede desactivar cuando la implementación utiliza contenedores de terceros que no es necesario verificar. Este descriptor también indica el número de réplicas y la URL de interfaz que ha-proxy necesita. Al final está el indicador de especificación para el podspec pod, que llama a Kubernetes para obtener información sobre la configuración del puerto, la imagen, etc. Este es un descriptor bastante simple en formato JSON.

Otra herramienta que forma parte del proyecto de código abierto Amdatu es Deploymentctl. Tiene una interfaz de usuario de interfaz de usuario para configurar la implementación, almacena el historial de implementación y contiene webhooks para devoluciones de llamada por parte de terceros usuarios y desarrolladores. No puede usar la interfaz de usuario, ya que Amdatu Deployer es una API REST, pero esta interfaz puede facilitarle la implementación sin involucrar ninguna API. Deploymentctl está escrito en OSGi / Vertx usando Angular 2.

Ahora demostraré lo anterior en la pantalla usando una grabación prefabricada, para que no tenga que esperar. Implementaremos una aplicación simple en Go. No se preocupe, si no se ha encontrado con Go antes, esta es una aplicación muy simple, por lo que debe entenderlo todo.



Aquí creamos un servidor HTTP que responde solo a / health, por lo que esta aplicación solo verifica el chequeo de salud y nada más. Si se aprueba el cheque, se invoca la estructura JSON que se muestra a continuación. Contiene la versión de la aplicación que implementará el implementador, el mensaje que verá en la parte superior del archivo y el tipo de datos lógicos booleanos, ya sea que nuestra aplicación funcione o no.

Hice un poco de trampa con la última línea, porque puse un valor booleano fijo en la parte superior del archivo, que en el futuro me ayudará a implementar incluso una aplicación "poco saludable". Nos ocuparemos de esto más tarde.

Entonces empecemos. Primero, verificamos si hay pods en ejecución usando el comando ~ kubectl get pods, y si no hay respuesta de la URL de la interfaz, nos aseguramos de que no se estén realizando implementaciones.



A continuación, en la pantalla, verá la interfaz Deploymentctl que mencioné, en la que se establecen los parámetros de implementación: espacio de nombres, nombre de la aplicación, versión de implementación, número de réplicas, URL de la interfaz, nombre del contenedor, imagen, límites de recursos, número de puerto para verificar el estado, etc. . Los límites de recursos son muy importantes, ya que le permiten utilizar la máxima cantidad posible de "hierro". También puede ver el registro de implementación registro de implementación aquí.



Si repite el comando ~ kubectl get pods ahora, puede ver que el sistema se "congela" durante 20 segundos, durante los cuales se produce la reconfiguración del proxy ha. Después de eso, comienza bajo, y nuestra réplica se puede ver en el registro de implementación.



Corté una espera de 20 segundos del video, y ahora ves en la pantalla que la primera versión de la aplicación está implementada. Todo esto se hizo solo con la ayuda de la interfaz de usuario.



Ahora intentemos la segunda versión. Para hacer esto, cambio el mensaje de la aplicación con "¡Hola, Kubernetes!" a "¡Hola, Implementador!", el sistema crea esta imagen y la coloca en el registro de Docker, después de lo cual simplemente hacemos clic en el botón "Implementar" en la ventana Deploymentctl nuevamente. En este caso, el registro de implementación se inicia automáticamente de la misma manera que cuando se implementó la primera versión de la aplicación.



El comando ~ kubectl get pods muestra que 2 versiones de la aplicación se están ejecutando actualmente, pero el front-end muestra que todavía estamos ejecutando la versión 1. El



equilibrador de carga espera hasta que se realice la comprobación de estado y luego redirige el tráfico a la nueva versión. Después de 20 segundos, cambiamos a curl y vemos que ahora hemos implementado la versión 2 de la aplicación, y la primera se elimina.



Fue el despliegue de una aplicación "saludable" - saludable. Veamos qué sucede si para la nueva versión de la aplicación cambio el valor del parámetro Saludable de verdadero a falso, es decir, trataré de implementar una aplicación poco saludable que no haya pasado la comprobación de estado. Esto puede suceder si en la etapa de desarrollo se cometieron algunos errores de configuración en la aplicación, y entró en producción de esta forma.

Como puede ver, la implementación pasa por todos los pasos anteriores, y ~ kubectl get pods muestra que ambos pods se están ejecutando. Pero a diferencia de la implementación anterior, el registro muestra el estado del tiempo de espera. Es decir, debido a que no se aprobó la comprobación de estado, la nueva versión de la aplicación no se puede implementar. Como resultado, verá que el sistema volvió a usar la versión anterior de la aplicación, y la nueva versión simplemente se eliminó.



Lo bueno de esto es que, incluso si tiene una gran cantidad de solicitudes simultáneas en la aplicación, ni siquiera notarán el tiempo de inactividad durante la implementación del procedimiento de implementación. Si prueba esta aplicación utilizando el marco de Gatling, que le envía la mayor cantidad posible de solicitudes, entonces ninguna de estas solicitudes se descartará. Esto significa que nuestros usuarios ni siquiera notarán actualizaciones de versiones en tiempo real. Si falla, el trabajo continuará en la versión anterior; si tiene éxito, los usuarios cambiarán a la nueva versión.

Solo hay una cosa que puede conducir a una falla: si la comprobación de estado fue exitosa y la aplicación se bloqueó tan pronto como recibió la carga de trabajo, es decir, el colapso ocurrirá solo después de que se complete la implementación. En este caso, deberá retroceder manualmente a la versión anterior. Entonces, vimos cómo usar Kubernetes con sus herramientas de código abierto. El proceso de implementación será mucho más simple si incrusta estas herramientas en la creación / implementación de tuberías de creación / implementación. Al mismo tiempo, para comenzar la implementación, puede usar la interfaz de usuario y automatizar completamente este proceso, aplicando, por ejemplo, commit to master.



Nuestro servidor de compilación Build Server creará una imagen de Docker, la pegará en Docker Hub o en cualquier otro registro que utilice. El Docker Hub admite webhook, por lo que podemos comenzar la implementación remota a través de Deployer como se muestra arriba. Por lo tanto, puede automatizar completamente la implementación de la aplicación en producción potencial.

Pasemos al siguiente tema: escalar el clúster de Kubernetes. Observo que el comando kubectl es un comando de escala. Con la ayuda de otro, puede aumentar fácilmente el número de réplicas en nuestro clúster. Sin embargo, en la práctica, generalmente queremos aumentar el número de nodos, no nodos.



Al mismo tiempo, durante las horas de trabajo, es posible que deba aumentar, y por la noche, para reducir el costo de los servicios de Amazon, disminuir el número de instancias en ejecución de la aplicación. Esto no significa que solo el número de pods se escalará lo suficiente, porque incluso si uno de los nodos no está ocupado, aún tiene que pagarle a Amazon por ello. Es decir, junto con escalar los hogares, necesita escalar el número de máquinas utilizadas.

Esto puede ser complicado porque, independientemente de si usamos Amazon u otro servicio en la nube, Kubernetes no sabe nada sobre la cantidad de máquinas utilizadas. Carece de una herramienta que le permita escalar el sistema a nivel de nodos.



Así que tendremos que cuidar los nodos y las vainas. Podemos escalar fácilmente el lanzamiento de nuevos nodos utilizando la API de AWS y las máquinas del grupo Scaling para configurar el número de nodos de trabajo de Kubernetes. También puede usar cloud-init o un script similar para registrar nodos en un clúster de Kubernetes.

La nueva máquina comienza en el grupo Scaling, se inicia como un nodo, se registra en el registro del asistente y comienza a funcionar. Después de eso, puede aumentar el número de réplicas para usar en los nodos resultantes. Reducir la escala requiere más esfuerzo, ya que debe asegurarse de que tal paso no conduzca a la destrucción de las aplicaciones que ya se están ejecutando después de apagar las máquinas "innecesarias". Para evitar este escenario, debe llevar los nodos al estado "no programable". Esto significa que el planificador predeterminado al programar los pods DaemonSet ignorará estos nodos. El programador no eliminará nada de estos servidores, pero tampoco lanzará nuevos contenedores allí. El siguiente paso es desplazar el nodo de drenaje, es decir, transferir los hogares de trabajo a otra máquina u otros nodos que tengan la capacidad suficiente para esto.Después de verificar que no hay más contenedores en estos nodos, puede eliminarlos de Kubernetes. Después de eso, para Kubernetes, simplemente dejan de existir. A continuación, debe usar la API de AWS para deshabilitar nodos o máquinas innecesarios.
Puede usar Amdatu Scalerd, otra herramienta de escalado de código abierto similar a la API de AWS. Proporciona una CLI para agregar o eliminar nodos en un clúster. Su característica interesante es la capacidad de configurar el planificador utilizando el siguiente archivo json.



El código que se muestra reduce a la mitad la capacidad del grupo por la noche. Se configura como la cantidad de réplicas disponibles y la capacidad deseada del clúster de Amazon. El uso de este programador reducirá automáticamente el número de nodos por la noche y los aumentará por la mañana, ahorrando así el costo de usar nodos de un servicio en la nube como Amazon. Esta característica no está integrada en Kubernetes, pero el uso de Scalerd le permitirá escalar esta plataforma a su gusto.

Quiero llamar su atención sobre el hecho de que muchas personas me dicen: "Todo esto es bueno, pero ¿qué pasa con mi base de datos, que generalmente está en un estado estático?" ¿Cómo puedo ejecutar algo como esto en un entorno dinámico como Kubernetes? En mi opinión, no debe hacer esto, no debe intentar organizar el funcionamiento del almacén de datos en Kubernetes. Técnicamente, esto es posible, y hay manuales en Internet sobre este tema, pero complicará seriamente su vida.

Sí, el concepto de almacenamiento persistente existe en Kubernetes, y puede intentar ejecutar almacenes de datos como Mongo o MySQL, pero esta es una tarea que requiere mucho tiempo. Esto se debe al hecho de que los almacenes de datos no son totalmente compatibles con la interacción con un entorno dinámico. La mayoría de las bases de datos requieren un ajuste significativo, incluida la configuración manual del clúster, no les gusta la escala automática y otras cosas similares.
Por lo tanto, no te compliques la vida al intentar iniciar un almacén de datos en Kubernetes. Organice su trabajo de la manera tradicional utilizando servicios familiares y solo brinde a Kubernetes la oportunidad de usarlos.



Al final del tema, quiero presentarles la plataforma Cloud RTI basada en Kubernetes, en la que está trabajando mi equipo. Proporciona registros centralizados, aplicaciones de monitoreo y clústeres, y tiene muchas otras características útiles que son útiles para usted. Utiliza varias herramientas de código abierto como Grafana para mostrar el monitoreo.





Se planteó la pregunta, ¿por qué usar el equilibrador de carga ha-proxy con Kubernetes? Buena pregunta, porque actualmente hay 2 niveles de equilibrio de carga. Los servicios de Kubernetes todavía se encuentran en direcciones IP virtuales. No puede usarlos para puertos host externos, porque si Amazon reinicia su host en la nube, la dirección cambiará. Es por eso que colocamos los servicios de proxy de ha delante de los servicios, para crear una estructura más estática para una interacción de tráfico perfecta con Kubernetes.

Otra buena pregunta es ¿cómo puedo cuidar de cambiar el esquema de la base de datos durante la implementación azul / verde? El hecho es que, independientemente del uso de Kubernetes, cambiar el esquema de la base de datos es una tarea compleja. Debe garantizar la compatibilidad del esquema antiguo y el nuevo, después de lo cual puede actualizar la base de datos y luego actualizar las aplicaciones. Puede intercambiar en caliente la base de datos y luego actualizar las aplicaciones. Conozco personas que descargaron un clúster de base de datos completamente nuevo con un nuevo esquema, esta es una opción si tiene una base de datos sin esquema como Mongo, pero en cualquier caso, esta no es una tarea fácil. Si no hay más preguntas, ¡gracias por su atención!


Un poco de publicidad :)


Gracias por estar con nosotros. ¿Te gustan nuestros artículos? ¿Quieres ver más materiales interesantes? Apóyenos haciendo un pedido o recomendando a sus amigos VPS basado en la nube para desarrolladores desde $ 4.99 , un análogo único de servidores de nivel básico que inventamos para usted: toda la verdad sobre VPS (KVM) E5-2697 v3 (6 núcleos) 10GB DDR4 480GB SSD 1Gbps desde $ 19 o cómo dividir el servidor? (las opciones están disponibles con RAID1 y RAID10, hasta 24 núcleos y hasta 40GB DDR4).

Dell R730xd 2 veces más barato en el centro de datos Equinix Tier IV en Amsterdam? Solo tenemos 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV desde $ 199 en los Países Bajos.Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - ¡desde $ 99! Lea sobre Cómo construir un edificio de infraestructura. clase c con servidores Dell R730xd E5-2650 v4 que cuestan 9,000 euros por un centavo?

All Articles