Como fazer o escalonamento automático de implantações com métricas personalizadas

Neste tutorial, demonstramos como escalonar automaticamente as cargas de trabalho do GKE com base em métricas personalizadas exportadas para o Stackdriver pelos pods do Kubernetes. Para saber como fazer o escalonamento automático das cargas de trabalho com base em outras métricas disponíveis no Stackdriver, acesse Como fazer escalonamento automático de implantações com métricas externas.

Objetivos

Para configurar o escalonamento automático com métricas personalizadas no GKE, é preciso:

  1. Implantar o adaptador de métricas personalizadas do Stackdriver.
  2. Exportar métricas personalizadas para o Stackdriver.
  3. Implantar o recurso HorizontalPodAutoscaler (HPA) para escalonar a implantação com base em métricas personalizadas.

Antes de começar

Siga estas etapas para ativar a API do Kubernetes Engine:
  1. Acesse a página do Kubernetes Engine no Console do Google Cloud Platform.
  2. Crie ou selecione um projeto.
  3. Aguarde a ativação da API e dos serviços relacionados. Isso pode demorar alguns minutos.
  4. Verifique se o faturamento foi ativado no projeto do Google Cloud Platform.

    Saiba como ativar o faturamento

Instale as seguintes ferramentas de linha de comando usadas neste tutorial:

  • A gcloud é usada para criar e excluir clusters do Kubernetes Engine. A gcloud está incluída no SDK do Google Cloud.
  • A kubectl é utilizada para gerenciar o Kubernetes, o sistema de orquestração de clusters do Kubernetes Engine. É possível instalar a kubectl usando a gcloud:
    gcloud components install kubectl

Definir padrões da ferramenta de linha de comando gcloud

Para não perder tempo digitando o código do projeto e as opções de zona do Compute Engine na ferramenta de linha de comando gcloud, defina os padrões:
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b

Criar cluster e configurar o monitoramento

Como escolher uma métrica personalizada

Há duas maneiras de fazer escalonamento automático com métricas personalizadas:

  • Você pode exportar uma métrica personalizada de cada pod na implantação e apontar o valor médio por pod.
  • Você pode exportar uma métrica personalizada de um único pod fora da implantação e apontar o valor total.

Dentro dos limites indicados, uma implantação pode escalonar os pods replicados com base no valor da métrica. As métricas com um valor de destino total precisam ser definidas sempre de forma que o dimensionamento aproxime o valor da métrica do valor pretendido.

Por exemplo, pense em escalonar um aplicativo de front-end com base na métrica de consultas por segundo. Quando o valor da métrica aumenta, o número de pods precisa aumentar, com cada pod disponibilizando um volume de tráfego semelhante ao anterior. Exportar o valor de consultas por segundo de cada pod e definir um valor médio pretendido gera o comportamento pretendido. No entanto, exportar o número total de consultas por segundo e definir um valor pretendido total para essa métrica não produz o comportamento pretendido nesse caso, visto que aumentar o número de pods não reduz o tráfego total.

Outras métricas, como a latência de solicitação média, podem ser usadas diretamente com o valor pretendido total para escalonar implantações, dependendo do caso de uso.

Etapa 1: implantar o adaptador de métricas personalizadas do Stackdriver

Para conceder aos objetos do GKE acesso a métricas armazenadas no Stackdriver, você precisa implantar o adaptador de métricas personalizadas do Stackdriver. Para executar o adaptador de métricas personalizadas, é preciso conceder ao usuário a capacidade de criar os papéis de autorização exigidos executando o seguinte comando:

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

Para implantar o adaptador no cluster, execute o seguinte comando:

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

Etapa 2: exportar a métrica para o Stackdriver

É possível exportar as métricas para o Stackdriver diretamente do aplicativo ou expondo-as no formato do Prometheus (em inglês) e adicionando o adaptador do Prometheus para o Stackdriver (em inglês) aos contêineres do pod.

Para ver as métricas exportadas a partir do Metrics Explorer, procure custom/[METRIC_NAME]. Por exemplo, custom/foo.

Como exportar métricas a partir do aplicativo

Você pode criar métricas personalizadas e exportá-las diretamente para o Stackdriver a partir do código do aplicativo. Para saber mais, consulte Como criar métricas personalizadas na documentação do Stackdriver Monitoring. Você também pode aproveitar o recurso de criação automática de métricas personalizadas do Stackdriver.

A métrica precisa atender aos seguintes requisitos:

  • O tipo da métrica precisa ser GAUGE.
  • O tipo de valor da métrica pode ser DOUBLE ou INT64.
  • O nome da métrica precisa começar com o prefixo custom.googleapis.com/, seguido de um nome simples.
  • O tipo do recurso precisa ser "gke_container".
  • Os marcadores de recursos precisam incluir:
    • pod_id definido como o UID do pod, que pode ser recebido por meio da API Downward (em inglês);
    • container_name = ""
    • project_id, zone e cluster_name, que podem ser recebidos pelo aplicativo a partir do servidor de metadados. Para receber valores, use o cliente de metadados de computação do Google Cloud;
    • namespace_id, instance_id, que você pode definir com qualquer valor.

No arquivo de manifesto a seguir, veja uma implantação que executa uma única instância de um aplicativo em Go que exporta métricas usando bibliotecas de cliente do 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

Como exportar usando o Prometheus

É possível expor métricas no aplicativo no formato do Prometheus (em inglês) e implantar o adaptador do Prometheus para o Stackdriver (em inglês), que consegue as métricas e as exporta para o Stackdriver. Para exemplos de exposição de métricas no formato do Prometheus, consulte o guia de instrumentação do Kubernetes (em inglês).

A métrica precisa atender aos seguintes requisitos:

  • O tipo da métrica precisa ser Gauge (em inglês).
  • O nome da métrica não pode conter o prefixo custom.googleapis.com.

Implante o adaptador do Prometheus para o Stackdriver como um contêiner no pod usado para exportar as métricas e transmita as seguintes sinalizações para o contêiner:

  • pod-id e namespace-id: definidos como UID de namespace e pod, conseguidos por meio da API Downward (em inglês);
  • source=http://localhost:[PORT], em que [PORT] é a porta em que as métricas são expostas.
  • stackdriver-prefix=custom.googleapis.com

No arquivo de manifesto a seguir, veja um pod com um aplicativo em Go que expõe métricas usando as bibliotecas de cliente do Prometheus (em inglês) e um contêiner 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.2.3
    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

Etapa 3: criar o objeto HorizontalPodAutoscaler

Depois de exportar as métricas para o Stackdriver, você pode implantar um HPA para escalonar a implantação com base nas métricas.

As etapas a seguir dependem de como você escolheu coletar e exportar as métricas.

Como fazer escalonamento automático com base em métricas de todos os pods

O HPA usa as métricas para calcular uma média e compará-la com o valor médio pretendido.

No exemplo de exportação do aplicativo para o Stackdriver, uma implantação contém pods que exportam métricas. O arquivo de manifesto a seguir descreve um objeto HorizontalPodAutoscaler que escalona uma implantação com base no valor médio pretendido da 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

Como fazer escalonamento automático com base em métricas de um único pod

O HPA compara diretamente o valor exposto por um único pod com o valor pretendido especificado. Esse pod não precisa estar vinculado ao fluxo de trabalho escalonado.

No exemplo de exportação do Prometheus para o Stackdriver, um único pod exporta a métrica. No arquivo de manifesto a seguir, veja uma implantação e um HPA que escalona uma implantação com base no valor pretendido da 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

Limpeza

Para evitar que os recursos usados neste tutorial sejam cobrados em sua conta do Google Cloud Platform:

Exclua o cluster do GKE executando o seguinte comando:

gcloud container clusters delete [CLUSTER_NAME]

Solução de problemas

Se você tiver problemas com este tutorial, tente as seguintes etapas de depuração:

  1. Execute kubectl api-versions e verifique se a API custom.metrics.k8s.io/v1beta1 está registrada. Se não aparecer essa API na lista, verifique se o adaptador de métricas personalizadas (implantado na etapa 1) está sendo executado no cluster.
  2. Acesse o Metrics Explorer e verifique se sua métrica personalizada está sendo exportada para o Stackdriver. Procure métricas que começam com custom.googleapis.com/[NAME]. Se a sua métrica não aparecer na lista:

    • Assegure-se de que a implantação do exportador (implantado na etapa 2) esteja em execução.
    • Se você tiver personalizado a conta de serviço dos nós com --service-account, verifique se ela tem o papel do IAM gravador de métricas do Monitoring (roles/monitoring.metricWriter).
    • Se você personalizou o escopo de seus nós com --scopes, certifique-se de que seus nós tenham o escopo monitoring.
  3. Execute kubectl describe hpa [DEPLOYMENT_NAME] e verifique se sua métrica personalizada está sendo lida pelo HPA. Se aparecerem erros:

    • Certifique-se de que a implantação escalonada (implantada na etapa 2) esteja em execução.
    • Se você tiver personalizado a conta de serviço dos nós com "--service-account", verifique se ela tem o papel do IAM leitor do Monitoring (roles/monitoring.viewer).

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Tutoriais do Kubernetes Engine