Disyuntor Istio: deshabilitar contenedores defectuosos

Se acabaron las vacaciones y volvemos con nuestra segunda publicación de la serie Istio Service Mesh.

Disyuntor Istio: deshabilitar contenedores defectuosos

El tema de hoy es Disyuntor, que traducido al idioma ruso en ingeniería eléctrica significa "disyuntor", en el lenguaje común, "disyuntor". Sólo que en Istio esta máquina no desconecta un circuito en cortocircuito o sobrecargado, sino contenedores defectuosos.

Cómo debería funcionar esto idealmente

Cuando Kubernetes gestiona los microservicios, por ejemplo dentro de la plataforma OpenShift, aumentan y disminuyen automáticamente según la carga. Debido a que los microservicios se ejecutan en pods, puede haber varias instancias de un microservicio en contenedores en un punto final, y Kubernetes enrutará las solicitudes y equilibrará la carga entre ellas. Y, idealmente, todo esto debería funcionar perfectamente.

Recordamos que los microservicios son pequeños y efímeros. A menudo se subestima lo efímero, que aquí significa la facilidad de aparecer y desaparecer. El nacimiento y la muerte de otra instancia de un microservicio en un pod son cosas bastante esperadas, OpenShift y Kubernetes lo manejan bien y todo funciona muy bien, pero nuevamente en teoría.

Cómo funciona realmente

Ahora imaginemos que una instancia específica de un microservicio, es decir, un contenedor, se ha vuelto inutilizable: o no responde (error 503) o, lo que es más desagradable, responde, pero demasiado lentamente. En otras palabras, presenta fallas o no responde a las solicitudes, pero no se elimina automáticamente del grupo. ¿Qué se debe hacer en este caso? ¿Volver a intentarlo? ¿Debo eliminarlo del esquema de enrutamiento? ¿Y qué significa “demasiado lento”? ¿Cuántos son los números y quién los determina? ¿Quizás simplemente darle un respiro y volver a intentarlo más tarde? Si es así, ¿cuánto después?

¿Qué es la expulsión de piscinas en Istio?

Y aquí Istio viene al rescate con sus máquinas de protección de disyuntores, que eliminan temporalmente los contenedores defectuosos del grupo de recursos de enrutamiento y equilibrio de carga, implementando el procedimiento de expulsión del grupo.

Utilizando una estrategia de detección de valores atípicos, Istio detecta los pods de curvas que están fuera de línea y los elimina del grupo de recursos durante un período de tiempo específico, llamado ventana de suspensión.

Para mostrar cómo funciona esto en Kubernetes en la plataforma OpenShift, comencemos con una captura de pantalla de los microservicios que funcionan normalmente del ejemplo en el repositorio. Demostraciones para desarrolladores de Red Hat. Aquí tenemos dos pods, v1 y v2, cada uno de los cuales ejecuta un contenedor. Cuando no se utilizan las reglas de enrutamiento de Istio, Kubernetes utiliza de forma predeterminada el enrutamiento por turnos equilibrado equitativamente:

Disyuntor Istio: deshabilitar contenedores defectuosos

Preparándose para un accidente

Antes de realizar la expulsión del grupo, debe crear una regla de enrutamiento de Istio. Digamos que queremos distribuir solicitudes entre pods en una proporción de 50/50. Además, aumentaremos la cantidad de contenedores v2 de uno a dos, así:

oc scale deployment recommendation-v2 --replicas=2 -n tutorial

Ahora establecemos una regla de enrutamiento para que el tráfico se distribuya entre los pods en una proporción de 50/50.

Disyuntor Istio: deshabilitar contenedores defectuosos
Así es como se ve el resultado de esta regla:

Disyuntor Istio: deshabilitar contenedores defectuosos
Se puede criticar que esta pantalla no sea 50/50, sino 14:9, pero con el tiempo la situación mejorará.

haciendo un fallo

Ahora deshabilitemos uno de los dos contenedores v2 para que tengamos un contenedor v1 en buen estado, un contenedor v2 en buen estado y un contenedor v2 defectuoso:

Disyuntor Istio: deshabilitar contenedores defectuosos

Arreglando el problema

Entonces, tenemos un contenedor defectuoso y es hora de expulsar la piscina. Usando una configuración muy simple, excluiremos este contenedor fallido de cualquier esquema de enrutamiento durante 15 segundos con la esperanza de que vuelva a un estado saludable (ya sea reiniciando o restaurando el rendimiento). Así es como se ve esta configuración y los resultados de su trabajo:

Disyuntor Istio: deshabilitar contenedores defectuosos
Disyuntor Istio: deshabilitar contenedores defectuosos
Como puede ver, el contenedor v2 fallido ya no se usa para enrutar solicitudes porque se eliminó del grupo. Pero después de 15 segundos volverá automáticamente a la piscina. En realidad, acabamos de mostrar cómo funciona Pool Eyection.

Empecemos a construir arquitectura.

Pool Ejection, combinado con las capacidades de monitoreo de Istio, le permite comenzar a construir un marco para reemplazar automáticamente los contenedores defectuosos para reducir, si no eliminar, el tiempo de inactividad y las fallas.

La NASA tiene un lema ruidoso: El fracaso no es una opción, cuyo autor es considerado el director de vuelo. Gene Kranz. Se puede traducir al ruso como “El fracaso no es una opción”, y el significado aquí es que todo puede funcionar si se tiene suficiente voluntad. Sin embargo, en la vida real, los fracasos no ocurren simplemente, son inevitables, en todas partes y en todo. ¿Y cómo afrontarlos en el caso de los microservicios? En nuestra opinión, es mejor confiar no en la fuerza de voluntad, sino en las capacidades de los contenedores, Kubernetes, Red Hat OpenShiftY Istio.

Istio, como escribimos anteriormente, implementa el concepto de disyuntores, que ha demostrado su eficacia en el mundo físico. Y así como un disyuntor eléctrico apaga una sección problemática de un circuito, el software Circuit Breaker de Istio abre la conexión entre un flujo de solicitudes y un contenedor de problemas cuando algo anda mal con el punto final, por ejemplo, cuando el servidor falla o comienza a fallar. desacelerar.

Además, en el segundo caso solo hay más problemas, ya que los frenos de un contenedor no sólo provocan una cascada de retrasos en los servicios que acceden a él y, como resultado, reducen el rendimiento del sistema en su conjunto, sino que también generan repetidas solicitudes a un servicio que ya funciona con lentitud, lo que sólo agrava la situación.

Disyuntor en teoría

Circuit Breaker es un proxy que controla el flujo de solicitudes a un punto final. Cuando este punto deja de funcionar o, según la configuración especificada, comienza a ralentizarse, el proxy interrumpe la conexión con el contenedor. Luego, el tráfico se redirige a otros contenedores, simplemente debido al equilibrio de carga. La conexión permanece abierta durante un período de suspensión determinado, digamos dos minutos, y luego se considera medio abierta. Un intento de enviar la siguiente solicitud determina el estado posterior de la conexión. Si todo está bien con el servicio, la conexión vuelve a funcionar y se cierra nuevamente. Si todavía hay algún problema con el servicio, la conexión se desconecta y se vuelve a habilitar la ventana de suspensión. Así es como se ve un diagrama de estado de disyuntor simplificado:

Disyuntor Istio: deshabilitar contenedores defectuosos
Es importante señalar aquí que todo esto sucede, por así decirlo, al nivel de la arquitectura del sistema. Entonces, en algún momento tendrás que enseñar a tus aplicaciones a trabajar con Circuit Breaker, como proporcionar un valor predeterminado en respuesta o, si es posible, ignorar la existencia del servicio. Para esto se utiliza un patrón de mamparo, pero está fuera del alcance de este artículo.

Disyuntor en la práctica

Por ejemplo, ejecutaremos dos versiones de nuestro microservicio de recomendación en OpenShift. La versión 1 funcionará bien, pero en la v2 incorporaremos un retraso para simular ralentizaciones en el servidor. Para ver los resultados, utilice la herramienta. cerco:

siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).nip.io

Disyuntor Istio: deshabilitar contenedores defectuosos
Todo parece funcionar, pero ¿a qué coste? A primera vista, tenemos una disponibilidad del 100%, pero si miramos más de cerca, la duración máxima de la transacción es de hasta 12 segundos. Esto es claramente un cuello de botella y es necesario ampliarlo.

Para ello usaremos Istio para eliminar llamadas a contenedores lentos. Así es como se ve la configuración correspondiente usando Circuit Breaker:

Disyuntor Istio: deshabilitar contenedores defectuosos
La última línea con el parámetro httpMaxRequestsPerConnection indica que la conexión debe desconectarse al intentar crear otra (una segunda) conexión además de la existente. Dado que nuestro contenedor simula un servicio lento, este tipo de situaciones surgirán periódicamente y luego Istio devolverá un error 503, pero esto es lo que mostrará siege:

Disyuntor Istio: deshabilitar contenedores defectuosos

Bien, tenemos el disyuntor, ¿qué sigue?

Entonces, implementamos el apagado automático sin tocar en absoluto el código fuente de los servicios. Usando el disyuntor y el procedimiento de expulsión del grupo descrito anteriormente, podemos eliminar los contenedores de freno del grupo de recursos hasta que vuelvan a la normalidad y verificar su estado con una frecuencia específica; en nuestro ejemplo, esto es dos minutos (parámetro SleepWindow).

Tenga en cuenta que la capacidad de una aplicación para responder a un error 503 todavía se establece en el nivel del código fuente. Existen muchas estrategias para utilizar el disyuntor, según la situación.

En la siguiente publicación: Hablaremos sobre el seguimiento y el monitoreo que ya están integrados o se agregan fácilmente a Istio, así como también sobre cómo introducir errores intencionalmente en el sistema.

Fuente: habr.com

Añadir un comentario