Ruta de aprendizaje: aplicaciones escalables - Escalado

Este conjunto de tutoriales está dirigido a administradores de TI y operadores que quieran desplegar, ejecutar y gestionar entornos de aplicaciones modernas que se ejecuten en Google Kubernetes Engine (GKE). A lo largo de esta serie de tutoriales, aprenderás a configurar la monitorización y las alertas, a escalar cargas de trabajo y a simular errores. Todo ello con la aplicación de microservicios de ejemplo Cymbal Bank:

  1. Crear un clúster y desplegar una aplicación de ejemplo
  2. Monitorizar con Google Cloud Managed Service para Prometheus
  3. Escalar cargas de trabajo (este tutorial)
  4. Simular un fallo
  5. Centralizar la gestión de cambios

Descripción general y objetivos

Una aplicación de consumo como Cymbal Bank suele tener un número variable de usuarios en diferentes momentos. Lo ideal es que tu sitio web pueda hacer frente a los picos de tráfico sin ralentizarse ni tener otros problemas, pero sin que la organización tenga que gastar dinero en recursos de la nube que no necesita. Una solución que Google Cloud proporciona esto es el autoescalado.

En este tutorial, aprenderás a configurar clústeres y cargas de trabajo en un clúster de GKE para que se escalen usando tanto métricas de Kubernetes integradas como métricas personalizadas de Cloud Monitoring y Cloud Trace. Aprenderás a completar las siguientes tareas:

  • Habilita las métricas personalizadas en Cloud Monitoring para Trace.
    • Las métricas personalizadas te permiten escalar usando datos de monitorización adicionales o entradas externas que no conoce el clúster de Kubernetes, como el tráfico de red o los códigos de respuesta HTTP.
  • Configura el autoescalador horizontal de pods, una función de GKE que puede aumentar o reducir automáticamente el número de pods de una carga de trabajo en función de las métricas especificadas.
  • Simula la carga de la aplicación y observa cómo responden la herramienta de adaptación dinámica de clústeres y la herramienta de adaptación dinámica horizontal de pods.

Costes

Si habilitas GKE y despliegas la aplicación de ejemplo Cymbal Bank para esta serie de tutoriales, se te aplicarán cargos por clúster de GKE en Google Cloud , tal como se indica en nuestra página de precios, hasta que inhabilites GKE o elimines el proyecto.

También eres responsable de otros Google Cloud costes en los que incurras al ejecutar la aplicación de ejemplo de Cymbal Bank, como los cargos de las máquinas virtuales de Compute Engine y Trace.

Antes de empezar

Para aprender a escalar tus despliegues, debes completar el primer tutorial para crear un clúster de GKE que use Autopilot y desplegar la aplicación de microservicios de ejemplo Cymbal Bank.

Te recomendamos que completes este conjunto de tutoriales para aplicaciones escalables en orden. A medida que avances en el conjunto de tutoriales, adquirirás nuevas habilidades y usarás más Google Cloud productos y servicios.

También debes crear una cuenta de servicio de gestión de identidades y accesos y conceder algunos permisos para que la herramienta de adaptación dinámica horizontal de pods funcione correctamente:

  1. Crea una cuenta de servicio de IAM. Esta cuenta de servicio se usa en el tutorial para conceder acceso a métricas personalizadas que permiten que la herramienta de adaptación dinámica de pods horizontal determine cuándo aumentar o reducir la escala:

    gcloud iam service-accounts create scalable-apps
    
  2. Concede acceso a la cuenta de servicio de gestión de identidades y accesos para realizar las acciones de escalado necesarias:

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --role roles/cloudtrace.agent \
      --member "serviceAccount:scalable-apps@PROJECT_ID.iam.gserviceaccount.com"
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
      --role roles/monitoring.metricWriter \
      --member "serviceAccount:scalable-apps@PROJECT_ID.iam.gserviceaccount.com"
    
    gcloud iam service-accounts add-iam-policy-binding "scalable-apps@PROJECT_ID.iam.gserviceaccount.com" \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:PROJECT_ID.svc.id.goog[default/default]"
    

    Se concede el siguiente acceso a la cuenta de servicio de gestión de identidades y accesos:

    • roles/cloudtrace.agent: escribe datos de seguimiento, como información de latencia, en Trace.
    • roles/monitoring.metricWriter: escribe métricas en Cloud Monitoring.
    • roles/iam.workloadIdentityUser: Permite que una cuenta de servicio de Kubernetes use Workload Identity Federation for GKE para actuar como cuenta de servicio de IAM.
  3. Configura la cuenta de servicio de Kubernetes default en el espacio de nombres default para que actúe como la cuenta de servicio de IAM que has creado:

    kubectl annotate serviceaccount default \
        iam.gke.io/gcp-service-account=scalable-apps@PROJECT_ID.iam.gserviceaccount.com
    

    Esta configuración permite que los pods que usan la cuenta de servicio de Kubernetes default en el espacio de nombres default accedan a los mismos recursos Google Cloudque la cuenta de servicio de gestión de identidades y accesos.

Configurar la recogida de métricas personalizadas

Puedes configurar el autoescalador horizontal de pods para que use métricas básicas de CPU y memoria de Kubernetes, o bien métricas personalizadas de Cloud Monitoring, como las solicitudes HTTP por segundo o la cantidad de instrucciones SELECT. Las métricas personalizadas pueden funcionar sin necesidad de hacer cambios en la aplicación y proporcionan a tu clúster más información sobre el rendimiento general y las necesidades de la aplicación. En este tutorial, aprenderás a usar tanto las métricas integradas como las personalizadas.

  1. Para permitir que el autoescalador horizontal de pods lea métricas personalizadas de Monitoring, debes instalar el adaptador Custom Metrics - Stackdriver Adapter en tu clúster.

    Despliega el adaptador de métricas personalizadas de Stackdriver en tu clúster:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter.yaml
    
  2. Para permitir que el adaptador de Stackdriver obtenga métricas personalizadas de tu clúster, usa Workload Identity Federation para GKE. Este método usa una cuenta de servicio de gestión de identidades y accesos (IAM) que tiene permisos para leer métricas de monitorización.

    Asigna el rol roles/monitoring.viewer a la cuenta de servicio de IAM:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member "serviceAccount:scalable-apps@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/monitoring.viewer
    
  3. Configura el adaptador de Stackdriver para que use la federación de identidades de carga de trabajo para GKE y la cuenta de servicio de IAM que tiene permisos para leer las métricas de monitorización:

    gcloud iam service-accounts add-iam-policy-binding scalable-apps@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[custom-metrics/custom-metrics-stackdriver-adapter]"
    
  4. Kubernetes incluye su propio sistema de cuentas de servicio para acceder a un clúster. Para que tus aplicaciones se autentiquen en servicios y recursos fuera de tus clústeres de Google Kubernetes Engine, como Monitoring, usa la federación de identidades de carga de trabajo para GKE. Con este método, se configura la cuenta de servicio de Kubernetes para que use la cuenta de servicio de IAM para GKE.

    Anota la cuenta de servicio de Kubernetes que usa el adaptador:

    kubectl annotate serviceaccount custom-metrics-stackdriver-adapter \
        --namespace=custom-metrics \
        iam.gke.io/gcp-service-account=scalable-apps@PROJECT_ID.iam.gserviceaccount.com
    
  5. Reinicia la implementación del adaptador de Stackdriver para aplicar los cambios:

    kubectl rollout restart deployment custom-metrics-stackdriver-adapter \
        --namespace=custom-metrics
    

Configurar el autoescalador horizontal de pods

GKE Autopilot puede escalar de varias formas. En este tutorial, se muestra cómo se puede escalar un clúster mediante los siguientes métodos:

  • Herramienta de adaptación dinámica horizontal de pods: escala el número de pods de una carga de trabajo.
  • Herramienta de adaptación dinámica de clústeres: escala los recursos de los nodos disponibles en el clúster.

Estos dos métodos pueden funcionar conjuntamente para que, a medida que cambie el número de pods de tus aplicaciones, también cambien los recursos de los nodos para admitir esos pods.

Hay otras implementaciones disponibles para escalar pods que se basan en la herramienta de adaptación dinámica horizontal de pods. También puedes usar la herramienta de adaptación dinámica vertical de pods para ajustar las solicitudes de CPU y memoria de un pod en lugar del número de pods.

En este tutorial, configurarás el autoescalador horizontal de pods para el deployment userservice con métricas integradas y para el deployment frontend con métricas personalizadas.

En el caso de tus propias aplicaciones, colabora con tus desarrolladores de aplicaciones e ingenieros de plataformas para conocer sus necesidades y configurar las reglas de escalado automático horizontal de pods.

Escalar el despliegue de userservice

Cuando aumenta el número de usuarios de la aplicación de ejemplo Cymbal Bank, el servicio userservice consume más recursos de CPU. Utilizas un objeto HorizontalPodAutoscaler para controlar cómo quieres que responda tu aplicación a la carga. En el manifiesto YAML de HorizontalPodAutoscaler, defines qué Deployment debe escalar el escalador automático horizontal de pods, qué métricas debe monitorizar y el número mínimo y máximo de réplicas que quieres ejecutar.

  1. Consulta el HorizontalPodAutoscalerarchivo de manifiesto de ejemplouserservice para la implementación:

    # Copyright 2022 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    ---
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: userservice
    spec:
      behavior:
        scaleUp:
          stabilizationWindowSeconds: 0
          policies:
            - type: Percent
              value: 100
              periodSeconds: 5
          selectPolicy: Max
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: userservice
      minReplicas: 5
      maxReplicas: 50
      metrics:
        - type: Resource
          resource:
            name: cpu
            target:
              type: Utilization
              averageUtilization: 60
    

    Este archivo de manifiesto hace lo siguiente:

    • Define el número máximo de réplicas durante un escalado vertical a 50.
    • Define el número mínimo de durante una reducción a 5.
    • Usa una métrica de Kubernetes integrada para tomar decisiones de escalado. En este ejemplo, la métrica es el uso de la CPU y el uso objetivo es del 60%, lo que evita tanto el uso excesivo como el insuficiente.
  2. Aplica el manifiesto al clúster:

    kubectl apply -f extras/postgres-hpa/hpa/userservice.yaml
    

Escalar el despliegue de frontend

En la sección anterior, has configurado el autoescalador horizontal de pods en la implementación userservice basándote en las métricas de Kubernetes integradas para el uso de CPU. En el caso de la implementación frontend, puede que prefieras escalar en función del número de solicitudes HTTP entrantes. Este enfoque usa el adaptador de Stackdriver para leer métricas personalizadas de Monitoring para el objeto Ingress del balanceador de carga HTTP(S).

  1. Consulta el archivo de manifiesto de HorizontalPodAutoscaler para la frontend implementación:

    # Copyright 2022 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    ---
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: frontend
    spec:
      behavior:
        scaleUp:
          stabilizationWindowSeconds: 0
          policies:
            - type: Percent
              value: 100
              periodSeconds: 5
          selectPolicy: Max
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: frontend
      minReplicas: 5
      maxReplicas: 25
      metrics:
        - type: External
          external:
            metric:
              name: loadbalancing.googleapis.com|https|request_count
              selector:
                matchLabels:
                  resource.labels.forwarding_rule_name: FORWARDING_RULE_NAME
            target:
              type: AverageValue
              averageValue: "5"
    

    Este manifiesto usa los siguientes campos:

    • spec.scaleTargetRef: el recurso de Kubernetes que se va a escalar.
    • spec.minReplicas: número mínimo de réplicas, que en este ejemplo es 5.
    • spec.maxReplicas: número máximo de réplicas, que es 25 en este ejemplo.
    • spec.metrics.*: la métrica que se va a usar. En este ejemplo, se trata del número de solicitudes HTTP por segundo, que es una métrica personalizada de Monitoring proporcionada por el adaptador que has implementado.
    • spec.metrics.external.metric.selector.matchLabels: etiqueta de recurso específica por la que filtrar al escalar.
  2. Busca el nombre de la regla de reenvío del balanceador de carga de entrada frontend:

    export FW_RULE=$(kubectl get ingress frontend -o=jsonpath='{.metadata.annotations.ingress\.kubernetes\.io/forwarding-rule}')
    echo $FW_RULE
    

    El resultado debería ser similar al siguiente:

    k8s2-fr-j76hrtv4-default-frontend-wvvf7381
    
  3. Añade tu regla de reenvío al archivo de manifiesto:

    sed -i "s/FORWARDING_RULE_NAME/$FW_RULE/g" "extras/postgres-hpa/hpa/frontend.yaml"
    

    Este comando sustituye FORWARDING_RULE_NAME por la regla de reenvío que hayas guardado.

  4. Aplica el manifiesto al clúster:

    kubectl apply -f extras/postgres-hpa/hpa/frontend.yaml
    

Simular carga

En esta sección, usarás un generador de carga para simular picos de tráfico y observar cómo aumenta el número de réplicas y de nodos para adaptarse al aumento de la carga a lo largo del tiempo. Después, puedes dejar de generar tráfico y observar cómo se reduce el número de réplicas y nodos en respuesta.

  1. Antes de empezar, comprueba el estado de la herramienta de adaptación dinámica de pods horizontal y el número de réplicas que se están usando.

    Obtén el estado de tus recursos de HorizontalPodAutoscaler:

    kubectl get hpa
    

    El resultado es similar al siguiente, que muestra que hay 1 réplica frontend y 5 réplicas userservice:

    NAME                     REFERENCE                            TARGETS             MINPODS   MAXPODS   REPLICAS   AGE
    frontend                 Deployment/frontend                  <unknown>/5 (avg)   5         25        1          34s
    userservice              Deployment/userservice               0%/60%              5         50        5          4m56s
    
  2. La aplicación de muestra Cymbal Bank incluye un servicio loadgenerator. Este servicio envía continuamente solicitudes imitando a los usuarios al frontend y crea periódicamente nuevas cuentas y simula transacciones entre ellas.

    Expón la interfaz web de loadgenerator de forma local. Esta interfaz se usa para simular la carga en la aplicación de ejemplo Cymbal Bank:

    kubectl port-forward svc/loadgenerator 8080
    

    Si aparece un mensaje de error, vuelve a intentarlo cuando el Pod esté en funcionamiento.

  3. En un navegador de tu ordenador, abre la interfaz web del generador de carga:

    • Si usas una shell local, abre un navegador y ve a http://127.0.0.1:8080.
    • Si usas Cloud Shell, haz clic en Vista previa web y, a continuación, en Obtener vista previa en el puerto 8080.
  4. En la interfaz web del generador de carga, si el valor de Fallos es 100%, sigue estos pasos para actualizar la configuración de la prueba:

    1. Haz clic en el botón Detener situado junto al contador de tasa de errores.
    2. En Estado, haga clic en la opción Nueva prueba.
    3. Actualiza el valor de Host a la dirección IP de tu entrada de Cymbal Bank.
    4. Haz clic en Iniciar enjambre.
  5. En la interfaz web del generador de carga, haga clic en la pestaña Gráficos para observar el rendimiento a lo largo del tiempo. Consulta el número de solicitudes y la utilización de recursos.

  6. Abre una nueva ventana de terminal y observa el número de réplicas de tus pods frontend y userservice:

    kubectl get hpa -w
    

    El número de réplicas aumenta a medida que lo hace la carga. Las acciones de ampliación pueden tardar unos diez minutos, ya que el clúster reconoce que las métricas configuradas alcanzan el umbral definido y usa el autoescalador horizontal de pods para aumentar el número de pods.

    En el siguiente ejemplo de salida se muestra que el número de réplicas ha aumentado a medida que se ejecuta el generador de carga:

    NAME                     REFERENCE                            TARGETS          MINPODS   MAXPODS   REPLICAS
    frontend                 Deployment/frontend                  5200m/5 (avg)    5         25        13
    userservice              Deployment/userservice               71%/60%          5         50        17
    
  7. Abre otra ventana de terminal y comprueba el número de nodos del clúster:

    gcloud container clusters list \
        --filter='name=scalable-apps' \
        --format='table(name, currentMasterVersion, currentNodeVersion, currentNodeCount)' \
        --location="CONTROL_PLANE_LOCATION"
    

    Sustituye CONTROL_PLANE_LOCATION por la ubicación de Compute Engine del plano de control de tu clúster. Proporciona una región para los clústeres regionales o una zona para los clústeres zonales.

    El número de nodos también ha aumentado desde la cantidad inicial para dar cabida a las nuevas réplicas. Este aumento del número de nodos se debe a Autopilot de GKE. No tienes que configurar nada para este escalado de nodos.

  8. Abre la interfaz del generador de carga y haz clic en Detener para finalizar la prueba.

  9. Vuelve a comprobar el número de réplicas y de nodos, y observa cómo se reducen a medida que disminuye la carga. El escalado hacia abajo puede tardar un poco, ya que la ventana de estabilización predeterminada de las réplicas del recurso HorizontalPodAutoscaler de Kubernetes es de cinco minutos.

En un entorno real, tanto el número de nodos como el de pods de tu entorno se adaptarían automáticamente de la misma forma que con esta carga simulada. La aplicación de ejemplo Cymbal Bank se ha diseñado para adaptarse a este tipo de escalado. Consulte con los operadores de su aplicación y con los ingenieros de fiabilidad de sitios (SRE) o los desarrolladores de aplicaciones para saber si sus cargas de trabajo pueden beneficiarse de estas funciones de escalado.

Limpieza

El conjunto de tutoriales de Cymbal Bank está diseñado para completarse uno después del otro. A medida que avances en el conjunto de tutoriales, adquirirás nuevas habilidades y usarás más Google Cloud productos y servicios.

Si quieres hacer un descanso antes de pasar al siguiente tutorial y evitar que se te cobren los recursos utilizados en este tutorial en tu cuenta, elimina el proyecto que has creado. Google Cloud

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Siguientes pasos

En el siguiente tutorial, aprenderás a simular un fallo en GKE.