Se acabaron las vacaciones y volvemos con nuestra segunda publicación de la serie Istio Service Mesh.
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.
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.
Así es como se ve el resultado de esta regla:
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:
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:
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.
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:
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.
siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).nip.io
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:
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:
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