Ajuste de escala automático de objetos Deployment con métricas personalizadas

En este instructivo, se muestra cómo escalar de manera automática tus cargas de trabajo de GKE según las métricas personalizadas que los pods de Kubernetes exportan a Stackdriver. Para obtener información sobre cómo hacer un ajuste de escala automático de las cargas de trabajo según otras métricas disponibles en Stackdriver, consulta Cómo realizar un ajuste de escala automático de implementaciones con métricas externas.

Objetivos

Para configurar un ajuste de escala automático con métricas personalizadas en GKE, debes seguir estos pasos:

  1. Implementar el adaptador de métricas personalizadas de Stackdriver.
  2. Exportar métricas personalizadas a Stackdriver.
  3. Implementar el recurso HorizontalPodAutoscaler (HPA) para escalar tu implementación según las métricas personalizadas.

Antes de comenzar

Sigue los pasos que se indican a continuación para habilitar la API de Kubernetes Engine:
  1. Consulta la página de Kubernetes Engine en Google Cloud Console.
  2. Crea o selecciona un proyecto.
  3. Espera a que la API y los servicios relacionados se habiliten. Esto puede tardar varios minutos.
  4. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud. Obtén información sobre cómo confirmar que tienes habilitada la facturación para tu proyecto.

Instala las siguientes herramientas de línea de comandos de este instructivo:

  • gcloud se usa para crear y borrar clústeres de Kubernetes Engine. gcloud se incluye en el SDK de Google Cloud.
  • kubectl se usa para administrar Kubernetes, el sistema de organización de clústeres que emplea Kubernetes Engine. Puedes instalar kubectl con gcloud:
    gcloud components install kubectl

Cómo establecer valores predeterminados para la herramienta de línea de comandos de gcloud

Para ahorrar tiempo cuando escribes las opciones del ID del proyecto y de la zona de Compute Engine en la herramienta de línea de comandos de gcloud, puedes establecer los valores predeterminados:
gcloud config set project project-id
gcloud config set compute/zone compute-zone

Crea el clúster y configura la supervisión

Elige una métrica personalizada

Existen dos modos de realizar el ajuste de escala automático con métricas personalizadas:

  • Puedes exportar una métrica personalizada de cada pod en el objeto Deployment y establecer el valor promedio por pod.
  • Si el pod está fuera del objeto Deployment y no forma parte de otra implementación, puedes exportar una métrica personalizada de cada pod y establecer la suma de estas métricas.

Dentro de límites determinados, un objeto Deployment puede escalar sus pods replicados según el valor de la métrica. Las métricas con un valor objetivo total siempre deben definirse de manera tal que el escalamiento acerque el valor de la métrica al valor objetivo.

Por ejemplo, considera escalar una aplicación frontend según la métrica de consultas por segundo. Cuando el valor de la métrica aumenta, la cantidad de pods debería escalar. Como resultado, cada pod procesará una cantidad similar de tráfico como antes. Exportar el valor de las consultas por segundo para cada pod y configurar un promedio objetivo deseado da como resultado el comportamiento esperado. Sin embargo, exportar la cantidad total de consultas por segundo y establecer un valor objetivo total para esta métrica no produce el comportamiento deseado en este caso, ya que aumentar la cantidad de pods no reduce el tráfico total.

Otras métricas, como la latencia de solicitud promedio, se pueden usar directamente con el valor objetivo total para escalar las implementaciones, según el caso práctico.

Paso 1: implementar métricas personalizadas con el adaptador de Stackdriver

Para que los objetos GKE tengan acceso a las métricas almacenadas en Stackdriver, debes implementar el adaptador de métricas personalizadas de Stackdriver. Para ejecutar el adaptador de métricas personalizadas, debes otorgar al usuario la capacidad de crear funciones de autorización requeridas mediante la ejecución del siguiente comando:

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user "$(gcloud config get-value account)"

Para implementar el adaptador en tu clúster, ejecuta el siguiente comando:

kubectl create -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter.yaml

Paso 2: exportar la métrica a Stackdriver

Puedes exportar las métricas a Stackdriver directamente desde la aplicación, o bien puedes exponerlas en formato Prometheus y agregar el adaptador Prometheus-to-Stackdriver a los contenedores de tu pod.

Puedes ver las métricas exportadas en el Explorador de métricas si buscas custom/[METRIC_NAME] (como custom/foo).

Para consultar las métricas de un recurso supervisado con el Explorador de métricas, haz lo siguiente:

  1. En Google Cloud Console, ve a Monitoring o usa el siguiente botón:
    Ir a Monitoring
  2. En el panel de navegación de Monitoring, haz clic en  Explorador de métricas.
  3. Ingresa el nombre del recurso supervisado en el cuadro de texto Find resource type and metric.

Exporta métricas desde la aplicación

Puedes crear métricas personalizadas y exportarlas directamente a Stackdriver desde el código de tu aplicación. Para obtener más información, visita Cómo crear métricas personalizadas en la Documentación de Stackdriver Monitoring. También puedes aprovechar la función de creación automática de métricas personalizadas de Stackdriver.

Tu métrica debe cumplir con los siguientes requisitos:

  • La clase de métrica debe ser GAUGE
  • El tipo de métrica debe ser DOUBLE o INT64
  • El nombre de la métrica debe comenzar con el prefijo custom.googleapis.com/ seguido de un nombre simple
  • El tipo de recurso debe ser "gke_container"
  • Las etiquetas del recurso deben incluir:
    • pod_id configurado como UID de pod, que puede obtenerse mediante la API de Downward
    • container_name = ""
    • project_id, zone, cluster_name, que la aplicación puede obtener desde el servidor de metadatos. Para obtener valores, puedes usar el cliente de metadatos de procesamiento de Google Cloud.
    • namespace_id, instance_id, que pueden configurarse en cualquier valor.

En el siguiente archivo de manifiesto, se describe una implementación que ejecuta una instancia única de una aplicación de Go que exporta métricas mediante las bibliotecas cliente de Stackdriver:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: custom-metric-sd
  name: custom-metric-sd
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      run: custom-metric-sd
  template:
    metadata:
      labels:
        run: custom-metric-sd
    spec:
      containers:
      - command: ["./direct-to-sd"]
        args: ["--metric-name=foo", "--metric-value=40", "--pod-id=$(POD_ID)"]
        image: gcr.io/google-samples/sd-dummy-exporter:latest
        name: sd-dummy-exporter
        resources:
          requests:
            cpu: 100m
        env:
          - name: POD_ID
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: metadata.uid

Exporta mediante Prometheus

Puedes exportar métricas en tu aplicación en formato Prometheus y, luego, implementar el adaptador Prometheus-to-Stackdriver, que recopila las métricas y las exporta a Stackdriver. Para ver ejemplos de cómo exponer las métricas en formato Prometheus, consulta la guía de instrumentación de Kubernetes.

Tu métrica debe cumplir con los siguientes requisitos:

  • El tipo de métrica debe ser Gauge
  • El nombre de la métrica no debe contener el prefijo custom.googleapis.com

Implementa el adaptador Prometheus-to-Stackdriver como un contenedor del pod desde el cual exportas las métricas y transfiere las siguientes marcas al contenedor:

  • pod-id y namespace-id: configurados como UID de pod y de espacio de nombres, obtenido mediante la API de Downward
  • source=http://localhost:[PORT], en el que [PORT] es el puerto en el que se exponen las métricas.
  • stackdriver-prefix=custom.googleapis.com

En el siguiente archivo de manifiesto, se describe un pod con una aplicación de Go que expone métricas mediante las bibliotecas cliente de Prometheus y un contenedor de adaptador:

apiVersion: v1
kind: Pod
metadata:
  name: custom-metric-prometheus-sd
spec:
  containers:
  - command:
    - /bin/sh
    - -c
    - ./prometheus-dummy-exporter --metric-name=foo --metric-value=40 --port=8080
    image: gcr.io/google-samples/prometheus-dummy-exporter:latest
    imagePullPolicy: Always
    name: prometheus-dummy-exporter
    resources:
      requests:
        cpu: 100m
  - name: prometheus-to-sd
    image: gcr.io/google-containers/prometheus-to-sd:v0.5.0
    command:
    - /monitor
    - --source=:http://localhost:8080
    - --stackdriver-prefix=custom.googleapis.com
    - --pod-id=$(POD_ID)
    - --namespace-id=$(POD_NAMESPACE)
    env:
    - name: POD_ID
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.uid
    - name: POD_NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace

Paso 3: crear el objeto HorizontalPodAutoscaler

Una vez que hayas exportado las métricas a Stackdriver, puedes implementar un HPA para escalar tu implementación según las métricas.

Los pasos siguientes dependen de cómo elegiste recopilar y exportar tus métricas.

Ajuste de escala automático basado en las métricas de todos los pods

El HPA usa las métricas para calcular un promedio y compararlo con el valor promedio objetivo.

En el ejemplo de exportación application-to-Stackdriver, una implementación contiene pods que exportan métricas. En el siguiente archivo de manifiesto, se describe un objeto HorizontalPodAutoscaler que escala una implementación según el valor promedio objetivo para la métrica:

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: custom-metric-sd
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1beta1
    kind: Deployment
    name: custom-metric-sd
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: Pods
    pods:
      metricName: foo
      targetAverageValue: 20

Ajuste de escala automático basado en las métricas de un único pod

El HPA compara de forma directa el valor expuesto por un único pod con el valor objetivo especificado. Este pod no tiene que estar vinculado con el flujo de trabajo escalado.

En el ejemplo de exportación Prometheus-to-Stackdriver, un único pod exporta la métrica. En el siguiente archivo de manifiesto, se describe una implementación y un HPA que escala una implementación según el valor objetivo para la métrica:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dummy-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      k8s-app: dummy-deployment
  template:
    metadata:
      labels:
        k8s-app: dummy-deployment
    spec:
      containers:
      - name: long
        image: busybox
        command: ["/bin/sh",  "-c", "sleep 180000000"]
---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: dummy-deployment-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1beta1
    kind: Deployment
    name: dummy-deployment
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: Object
    object:
      target:
        kind: Pod
        name: custom-metric-prometheus-sd
      metricName: foo
      targetValue: 20

Limpiar

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud Platform por los recursos que usaste en este instructivo:

Borra tu clúster de GKE mediante la ejecución del siguiente comando:

gcloud container clusters delete [CLUSTER_NAME]

Solución de problemas

Si tienes problemas con este instructivo, realiza los siguientes pasos de depuración:

  1. Ejecuta kubectl api-versions y verifica que la API custom.metrics.k8s.io/v1beta1 esté registrada. Si no ves esta API en la lista, asegúrate de que el adaptador de métricas personalizadas (implementado en el Paso 1) se esté ejecutando en el clúster.
  2. Dirígete al Explorador de métricas y verifica que tu métrica personalizada se exporte a Stackdriver. Busca métricas que comiencen con custom.googleapis.com/[NAME]. Si no ves tu métrica en la lista, sigue estos pasos:

    • Asegúrate de que la implementación del exportador (implementada en el Paso 2) esté en ejecución.
    • Si personalizaste la cuenta de servicio de tus nodos con --service-account, asegúrate de que tenga la función de Escritor de métricas de Monitoring de Cloud Identity and Access Management (Cloud IAM) (roles/monitoring.metricWriter).
    • Si personalizaste el permiso de tus nodos con --scopes, asegúrate de que tengan el permiso monitoring.

    Para consultar las métricas de un recurso supervisado con el Explorador de métricas, haz lo siguiente:

    1. En Google Cloud Console, ve a Monitoring o usa el siguiente botón:
      Ir a Monitoring
    2. En el panel de navegación de Monitoring, haz clic en  Explorador de métricas.
    3. Ingresa el nombre del recurso supervisado en el cuadro de texto Find resource type and metric.
  3. Ejecuta kubectl describe hpa [DEPLOYMENT_NAME] y verifica que el HPA lea tu métrica personalizada. Si observas errores, haz lo siguiente:

    • Asegúrate de que la implementación escalada (implementada en el Paso 2) esté en ejecución.
    • Si personalizaste la cuenta de servicio de tus nodos con --service-account, asegúrate de que tenga la función de Visualizador de Monitoring de Cloud IAM (roles/monitoring.viewer).

Próximos pasos