Prácticas recomendadas para el ajuste de escala de Cloud Service Mesh en GKE

En esta guía, se describen las prácticas recomendadas para resolver problemas de escalamiento en arquitecturas de Cloud Service Mesh administrado en Google Kubernetes Engine. El objetivo principal de estas recomendaciones es garantizar el rendimiento, la confiabilidad y el uso de recursos óptimos para tus aplicaciones de microservicios a medida que crecen.

Para comprender las limitaciones de escalabilidad, consulta Límites de escalabilidad de Cloud Service Mesh.

La escalabilidad de Cloud Service Mesh en GKE depende del funcionamiento eficiente de sus dos componentes principales: el plano de datos y el plano de control. Este documento se centra principalmente en el ajuste de escala del plano de datos.

Cómo identificar problemas de escalamiento del plano de control y del plano de datos

En Cloud Service Mesh, los problemas de escalamiento pueden ocurrir en el plano de control o en el plano de datos. Sigue estos pasos para identificar el tipo de problema de escalamiento que tienes:

Síntomas de problemas de escalamiento del plano de control

Descubrimiento de servicios lento: Los servicios o extremos nuevos tardan mucho en descubrirse y estar disponibles.

Demoras en la configuración: Los cambios en las reglas de administración del tráfico o las políticas de seguridad tardan mucho en propagarse.

Mayor latencia en las operaciones del plano de control: Las operaciones como crear, actualizar o borrar recursos de Cloud Service Mesh se vuelven lentas o no responden.

Errores relacionados con Traffic Director: Es posible que observes errores en los registros de Cloud Service Mesh o en las métricas del plano de control que indiquen problemas con la conectividad, el agotamiento de recursos o la limitación de la API.

Alcance del impacto: Por lo general, los problemas del plano de control afectan a toda la malla, lo que provoca una degradación generalizada del rendimiento.

Síntomas de problemas de escalamiento del plano de datos

Mayor latencia en la comunicación entre servicios: Las solicitudes a un servicio dentro de la malla experimentan una mayor latencia o tiempos de espera, pero no hay un uso elevado de CPU o memoria en los contenedores del servicio.

Uso elevado de CPU o memoria en los proxies de Envoy: El uso elevado de CPU o memoria puede indicar que los proxies tienen dificultades para controlar la carga de tráfico.

Impacto localizado: Los problemas del plano de datos suelen afectar a servicios o cargas de trabajo específicos, según los patrones de tráfico y la utilización de recursos de los proxies de Envoy.

Cómo escalar el plano de datos

Para escalar el plano de datos, prueba las siguientes técnicas:

Configura el ajuste de escala automático horizontal de Pods (HPA) para las cargas de trabajo

Usa el ajuste de escala automático horizontal de Pods (HPA) para escalar de forma dinámica las cargas de trabajo con Pods adicionales según el uso de recursos. Ten en cuenta lo siguiente cuando configures el HPA:

  • Usa el parámetro --horizontal-pod-autoscaler-sync-period para kube-controller-manager y ajustar la frecuencia de sondeo del controlador de HPA. La frecuencia de sondeo predeterminada es de 15 segundos, y puedes considerar establecerla en un valor más bajo si esperas aumentos de actividad de tráfico más rápidos. Para obtener más información sobre cuándo usar el HPA con GKE, consulta Ajuste automático de escala horizontal de Pods.

  • El comportamiento de ajuste predeterminado puede generar que se implemente (o finalice) una gran cantidad de Pods a la vez, lo que puede provocar un aumento repentino en el uso de recursos. Considera usar políticas de ajuste de escala para limitar la velocidad a la que se pueden implementar los Pods.

  • Usa EXIT_ON_ZERO_ACTIVE_CONNECTIONS para evitar que se interrumpan las conexiones durante la reducción.

Para obtener más detalles sobre el HPA, consulta Ajuste automático de escala horizontal de Pods en la documentación de Kubernetes.

Optimiza la configuración del proxy de Envoy

Para optimizar la configuración del proxy de Envoy, ten en cuenta las siguientes recomendaciones:

Límites de recursos

Puedes definir solicitudes y límites de recursos para los sidecars de Envoy en las especificaciones de tus Pods. Esto evita la contención de recursos y garantiza un rendimiento coherente.

También puedes configurar límites de recursos predeterminados para todos los proxies de Envoy en tu malla con anotaciones de recursos.

Los límites de recursos óptimos para tus proxies de Envoy dependen de factores como el volumen de tráfico, la complejidad de la carga de trabajo y los recursos de los nodos de GKE. Supervisa y ajusta continuamente tu malla de servicios para garantizar un rendimiento óptimo.

Consideración importante:

  • Calidad de servicio (QoS): Establecer tanto las solicitudes como los límites garantiza que tus proxies de Envoy tengan una calidad de servicio predecible.

Cómo definir el alcance de las dependencias de servicios

Considera recortar el gráfico de dependencia de tu malla declarando todas tus dependencias a través de la API de Sidecar. Esto limita el tamaño y la complejidad de la configuración que se envía a una carga de trabajo determinada, lo que es fundamental para las mallas más grandes.

Por ejemplo, a continuación, se muestra el gráfico de tráfico de la aplicación de ejemplo de la boutique en línea.

Árbol del gráfico de tráfico de la aplicación de muestra Online Boutique con muchas hojas

Muchos de estos servicios son hojas en el gráfico y, como tales, no necesitan tener información de salida para ninguno de los otros servicios en la malla. Puedes aplicar un recurso de Sidecar que limite el alcance de la configuración del sidecar para estos servicios hoja, como se muestra en el siguiente ejemplo.

apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: leafservices
  namespace: default
spec:
  workloadSelector:
    labels:
      app: cartservice
      app: shippingservice
      app: productcatalogservice
      app: paymentservice
      app: emailservice
      app: currencyservice
  egress:
  -   hosts:
    -   "~/*"

Consulta la aplicación de muestra Online Boutique para obtener detalles sobre cómo implementar esta aplicación de muestra.

Otro beneficio del alcance de sidecar es la reducción de las consultas de DNS innecesarias. El alcance de las dependencias del servicio garantiza que un sidecar de Envoy solo realice consultas de DNS para los servicios con los que realmente se comunicará, en lugar de para cada clúster de la malla de servicios.

Para cualquier implementación a gran escala que tenga problemas con tamaños de configuración grandes en sus sidecars, se recomienda enfáticamente definir el alcance de las dependencias del servicio para la escalabilidad de la malla.

Para limitar el alcance de la configuración de todas las cargas de trabajo dentro de un solo espacio de nombres, crea un recurso de Sidecar en ese espacio de nombres. Esto indica a todos los proxies de Envoy dentro de ese espacio de nombres que solo reciban configuración para los servicios en su propio espacio de nombres.

apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: sidecar
  namespace: my-app
spec:
  egress:
  -   hosts:
    -   "my-app/*"

Puedes aplicar el comportamiento predeterminado a cada espacio de nombres de tu malla aplicando un solo recurso de Sidecar al espacio de nombres raíz, que suele ser istio-system.

El siguiente Sidecar restringe el tráfico de salida de cada sidecar en la malla a los servicios ubicados dentro de su propio espacio de nombres.

apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
  name: sidear
  namespace: istio-system
spec:
  egress:
  -   hosts:
    -   "./*"

Ten en cuenta que Cloud Service Mesh impone un límite en la cantidad total de recursos de Sidecar que se pueden crear dentro de una sola malla. Debido a esta restricción, se recomienda crear Sidecars a nivel del espacio de nombres.

Supervisa y ajusta

Después de establecer los límites iniciales de recursos, es fundamental supervisar tus proxies de Envoy para asegurarte de que funcionen de manera óptima. Usa los paneles de GKE para supervisar el uso de la CPU y la memoria, y ajusta los límites de recursos según sea necesario.

Para determinar si un proxy de Envoy requiere límites de recursos más altos, supervisa su consumo de recursos en condiciones de tráfico típicas y máximas. Esto es lo que debes buscar:

  • Uso alto de CPU: Si el uso de CPU de Envoy se acerca o supera constantemente su límite, es posible que tenga dificultades para procesar solicitudes, lo que genera una mayor latencia o solicitudes descartadas. Considera aumentar el límite de CPU.

    En este caso, es posible que te inclines por escalar con el escalamiento horizontal, pero si el proxy de sidecar no puede procesar las solicitudes con la misma rapidez que el contenedor de la aplicación, ajustar los límites de CPU puede producir los mejores resultados.

  • Uso de memoria alto: Si el uso de memoria de Envoy se acerca a su límite o lo supera, es posible que comience a descartar conexiones o que experimente errores de memoria insuficiente (OOM). Aumenta el límite de memoria para evitar estos problemas.

  • Registros de errores: Examina los registros de Envoy en busca de errores relacionados con el agotamiento de recursos, como errores de conexión ascendente o desconexión o restablecimiento antes de los encabezados o demasiados archivos abiertos. Estos errores pueden indicar que el proxy necesita más recursos. Consulta los documentos de solución de problemas de escalamiento para obtener información sobre otros errores relacionados con problemas de escalamiento.

  • Métricas de rendimiento: Supervisa las métricas de rendimiento clave, como la latencia de solicitudes, las tasas de error y la capacidad de procesamiento. Si observas una degradación del rendimiento correlacionada con un uso elevado de recursos, es posible que sea necesario aumentar los límites.

Si estableces y supervisas de forma activa los límites de recursos para tus proxies del plano de datos, puedes garantizar que tu malla de servicios se escale de manera eficiente en GKE.

Cómo escalar el plano de control

En esta sección, se describen los parámetros de configuración que se deben ajustar para escalar tu plano de control.

Selectores de descubrimiento

Los selectores de descubrimiento son un campo en MeshConfig que te permite especificar el conjunto de espacios de nombres que los planos de control consideran cuando calculan las actualizaciones de configuración para los sidecars.

De forma predeterminada, Cloud Service Mesh supervisa todos los espacios de nombres del clúster. Esto puede ser un cuello de botella para los clústeres grandes que no necesitan observar todos los recursos.

Usa discoverySelectors para reducir la carga computacional en el plano de control limitando la cantidad de recursos de Kubernetes (como servicios, Pods y extremos) que se supervisan y procesan.

Cuando se usa la implementación del plano de control de TRAFFIC_DIRECTOR, Cloud Service Mesh solo crea recursos de Google Cloud , como servicios de backend y grupos de extremos de red, para los recursos de Kubernetes en los espacios de nombres especificados en discoverySelectors.

Para obtener más información, consulta Selectores de descubrimiento en la documentación de Istio.

Desarrollo de la resiliencia

Puedes ajustar los siguientes parámetros de configuración para aumentar la resiliencia de tu malla de servicios:

Detección de valores atípicos

La detección de valores atípicos supervisa los hosts en un servicio upstream y los quita del grupo de balanceo de cargas cuando alcanzan un umbral de error.

  • Configuración clave:
    • outlierDetection: Es la configuración que controla la expulsión de hosts en mal estado del grupo de balanceo de cargas.
  • Beneficios: Mantiene un conjunto de hosts en buen estado en el grupo de balanceo de cargas.

Para obtener más información, consulta Detección de valores atípicos en la documentación de Istio.

Reintentos

Mitiga los errores transitorios reintentando automáticamente las solicitudes fallidas.

  • Configuración clave:
    • attempts: Es la cantidad de intentos de reintento.
    • perTryTimeout: Es el tiempo de espera por intento de reintento. Establece este valor en un tiempo más corto que el tiempo de espera general. Determina cuánto tiempo esperarás para cada intento de reintento individual.
    • retryBudget: Es la cantidad máxima de reintentos simultáneos.
  • Beneficios: Mayores tasas de éxito para las solicitudes y menor impacto de las fallas intermitentes.

Factores a tener en cuenta:

  • Idempotencia: Asegúrate de que la operación que se reintenta sea idempotente, lo que significa que se puede repetir sin efectos secundarios no deseados.
  • Max Retries: Limita la cantidad de reintentos (p.ej., un máximo de 3 reintentos) para evitar bucles infinitos.
  • Interrupción de circuitos: Integra reintentos con interrupciones de circuitos para evitar reintentos cuando un servicio falla de forma constante.

Para obtener más información, consulta Reintentos en la documentación de Istio.

Tiempos de espera

Usa tiempos de espera para definir el tiempo máximo permitido para el procesamiento de solicitudes.

  • Configuración clave:
    • timeout: Es el tiempo de espera de la solicitud para un servicio específico.
    • idleTimeout: Tiempo que una conexión puede permanecer inactiva antes de cerrarse.
  • Beneficios: Se mejoró la capacidad de respuesta del sistema, se previnieron las pérdidas de recursos y se reforzó la seguridad contra el tráfico malicioso.

Factores a tener en cuenta:

  • Latencia de red: Ten en cuenta el tiempo de ida y vuelta (RTT) esperado entre los servicios. Deja un margen para las demoras inesperadas.
  • Gráfico de dependencia del servicio: Para las solicitudes encadenadas, asegúrate de que el tiempo de espera de un servicio de llamada sea más corto que el tiempo de espera acumulativo de sus dependencias para evitar fallas en cascada.
  • Tipos de operaciones: Es posible que las tareas de larga duración necesiten tiempos de espera significativamente más largos que las recuperaciones de datos.
  • Control de errores: Los tiempos de espera deben activar la lógica de manejo de errores adecuada (p.ej., reintento, resguardo, interrupción de circuito).

Para obtener más información, consulta Tiempos de espera en la documentación de Istio.

Supervisa y ajusta

Considera comenzar con la configuración predeterminada para los tiempos de espera, la detección de valores atípicos y los reintentos, y, luego, ajústala gradualmente según los requisitos específicos de tu servicio y los patrones de tráfico observados. Por ejemplo, consulta datos reales sobre cuánto tiempo suelen tardar tus servicios en responder. Luego, ajusta los tiempos de espera para que coincidan con las características específicas de cada servicio o extremo.

Telemetría

Usa la telemetría para supervisar continuamente tu malla de servicios y ajustar su configuración para optimizar el rendimiento y la confiabilidad.

  • Métricas: Usa métricas integrales, específicamente, volúmenes de solicitudes, latencia y tasas de errores. Integración con Cloud Monitoring para la visualización y las alertas
  • Seguimiento distribuido: Habilita la integración del seguimiento distribuido con Cloud Trace para obtener estadísticas detalladas sobre los flujos de solicitudes en tus servicios.
  • Registro: Configura el registro de acceso para capturar información detallada sobre las solicitudes y las respuestas.

Lecturas adicionales